diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index de28b210887..def03c714d7 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -34,8 +34,12 @@ libs/common/src/models/export @bitwarden/team-tools-dev libs/common/src/tools @bitwarden/team-tools-dev libs/importer @bitwarden/team-tools-dev libs/tools @bitwarden/team-tools-dev -bitwarden_license/bit-web/src/app/tools @bitwarden/team-tools-dev -bitwarden_license/bit-common/src/tools @bitwarden/team-tools-dev + +## Dirt (Data Insights & Reporting) team files ## +apps/web/src/app/dirt @bitwarden/team-data-insights-and-reporting-dev +bitwarden_license/bit-common/src/dirt @bitwarden/team-data-insights-and-reporting-dev +bitwarden_license/bit-web/src/app/dirt @bitwarden/team-data-insights-and-reporting-dev +libs/dirt @bitwarden/team-data-insights-and-reporting-dev ## Localization/Crowdin (Platform and Tools team) apps/browser/src/_locales @bitwarden/team-tools-dev @bitwarden/team-platform-dev @@ -91,7 +95,6 @@ apps/web/src/app/core @bitwarden/team-platform-dev apps/web/src/app/shared @bitwarden/team-platform-dev apps/web/src/translation-constants.ts @bitwarden/team-platform-dev # Workflows -# Any changes here should also be reflected in Renovate configuration .github/workflows/automatic-issue-responses.yml @bitwarden/team-platform-dev .github/workflows/automatic-pull-request-responses.yml @bitwarden/team-platform-dev .github/workflows/build-browser-target.yml @bitwarden/team-platform-dev @@ -161,7 +164,6 @@ apps/desktop/src/locales/en/messages.json apps/web/src/locales/en/messages.json ## BRE team owns these workflows ## -# Any changes here should also be reflected in Renovate configuration ## .github/workflows/brew-bump-desktop.yml @bitwarden/dept-bre .github/workflows/deploy-web.yml @bitwarden/dept-bre .github/workflows/publish-cli.yml @bitwarden/dept-bre @@ -182,5 +184,8 @@ apps/web/src/locales/en/messages.json **/entrypoint.sh ## Overrides -# tsconfig files are potentially dangerous and will be reviewed by platform to prevent misconfigurations +# For the time being platform owns tsconfig and jest config +# These overrides will be removed after Nx is implemented +# To track that effort please see https://bitwarden.atlassian.net/browse/PM-21636 **/tsconfig.json @bitwarden/team-platform-dev +**/jest.config.js @bitwarden/team-platform-dev diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 91b4ac86328..8ad9ad1b360 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -4,52 +4,24 @@ enabledManagers: ["cargo", "github-actions", "npm"], packageRules: [ { - // Group all build/test/lint workflows for GitHub Actions together for Platform. - // Since they are code owners we don't need to assign a review team in Renovate. - // Any changes here should also be reflected in CODEOWNERS. - groupName: "github-action", + // Group all Github Action minor updates together to reduce PR noise. + groupName: "Minor github-actions updates", matchManagers: ["github-actions"], - matchFileNames: [ - "./github/workflows/automatic-issue-responses.yml", - "./github/workflows/automatic-pull-request-responses.yml", - "./github/workflows/build-browser.yml", - "./github/workflows/build-cli.yml", - "./github/workflows/build-desktop.yml", - "./github/workflows/build-web.yml", - "./github/workflows/chromatic.yml", - "./github/workflows/crowdin-pull.yml", - "./github/workflows/enforce-labels.yml", - "./github/workflows/lint.yml", - "./github/workflows/locales-lint.yml", - "./github/workflows/repository-management.yml", - "./github/workflows/scan.yml", - "./github/workflows/stale-bot.yml", - "./github/workflows/test.yml", - "./github/workflows/version-auto-bump.yml", - ], - commitMessagePrefix: "[deps] Platform:", + matchUpdateTypes: ["minor"], + addLabels: ["hold"], }, { - // Group all release-related workflows for GitHub Actions together for BRE. - // Since they are code owners we don't need to assign a review team in Renovate. - // Any changes here should also be reflected in CODEOWNERS. - groupName: "github-action", - matchManagers: ["github-actions"], - matchFileNames: [ - "./github/workflows/brew-bump-desktop.yml", - "./github/workflows/deploy-web.yml", - "./github/workflows/publish-cli.yml", - "./github/workflows/publish-desktop.yml", - "./github/workflows/publish-web.yml", - "./github/workflows/retrieve-current-desktop-rollout.yml", - "./github/workflows/staged-rollout-desktop.yml", - "./github/workflows/release-cli.yml", - "./github/workflows/release-desktop-beta.yml", - "./github/workflows/release-desktop.yml", - "./github/workflows/release-web.yml", - ], - commitMessagePrefix: "[deps] BRE:", - addLabels: ["hold"], + // Enable support for Rust toolchain updates. + matchManagers: ["custom.regex"], + matchDepNames: ["rust"], + commitMessageTopic: "Rust", + }, + { + // By default, we send patch updates to the Dependency Dashboard and do not generate a PR. + // We want to generate PRs for a select number of dependencies to ensure we stay up to date on these. + matchPackageNames: ["browserslist", "electron", "rxjs", "typescript", "webpack", "zone.js"], + matchUpdateTypes: ["patch"], + dependencyDashboardApproval: false, }, { // Disable major and minor updates for TypeScript and Zone.js because they are managed by Angular. @@ -73,49 +45,7 @@ enabled: false, }, { - // Renovate should manage patch updates for TypeScript and Zone.js, despite ignoring major and minor. - matchPackageNames: ["typescript", "zone.js"], - matchUpdateTypes: "patch", - }, - { - // We want to update all the Jest-related packages together, to reduce PR noise. - groupName: "jest", - matchPackageNames: ["@types/jest", "jest", "ts-jest", "jest-preset-angular"], - }, - { - // We need to group all napi-related packages together to avoid build errors caused by version incompatibilities. - groupName: "napi", - matchPackageNames: ["napi", "napi-build", "napi-derive"], - }, - { - // We need to group all macOS/iOS binding-related packages together to avoid build errors caused by version incompatibilities. - groupName: "macOS/iOS bindings", - matchPackageNames: ["core-foundation", "security-framework", "security-framework-sys"], - }, - { - // We need to group all zbus-related packages together to avoid build errors caused by version incompatibilities. - groupName: "zbus", - matchPackageNames: ["zbus", "zbus_polkit"], - }, - { - matchPackageNames: [ - "base64-loader", - "buffer", - "bufferutil", - "core-js", - "css-loader", - "html-loader", - "mini-css-extract-plugin", - "postcss", - "postcss-loader", - "process", - "sass", - "sass-loader", - "style-loader", - "ts-loader", - "url", - "util", - ], + matchPackageNames: ["buffer", "bufferutil", "core-js", "process", "url", "util"], description: "Admin Console owned dependencies", commitMessagePrefix: "[deps] AC:", reviewers: ["team:team-admin-console-dev"], @@ -129,6 +59,9 @@ { matchPackageNames: [ "@angular-eslint/schematics", + "@eslint/compat", + "@typescript-eslint/rule-tester", + "@typescript-eslint/utils", "angular-eslint", "eslint-config-prettier", "eslint-import-resolver-typescript", @@ -149,6 +82,7 @@ { matchPackageNames: [ "@angular-eslint/schematics", + "@eslint/compat", "@typescript-eslint/rule-tester", "@typescript-eslint/utils", "angular-eslint", @@ -164,7 +98,7 @@ "lint-staged", "typescript-eslint", ], - groupName: "Linting minor-patch", + groupName: "Minor and patch linting updates", matchUpdateTypes: ["minor", "patch"], }, { @@ -213,7 +147,6 @@ "@types/chrome", "@types/firefox-webext-browser", "@types/glob", - "@types/jquery", "@types/lowdb", "@types/node", "@types/node-forge", @@ -222,6 +155,7 @@ "anyhow", "arboard", "babel-loader", + "base64-loader", "base64", "bindgen", "browserslist", @@ -229,6 +163,7 @@ "bytes", "core-foundation", "copy-webpack-plugin", + "css-loader", "dirs", "electron", "electron-builder", @@ -240,6 +175,7 @@ "futures", "hex", "homedir", + "html-loader", "html-webpack-injector", "html-webpack-plugin", "interprocess", @@ -248,6 +184,7 @@ "libc", "log", "lowdb", + "mini-css-extract-plugin", "napi", "napi-build", "napi-derive", @@ -258,15 +195,22 @@ "oslog", "pin-project", "pkg", + "postcss", + "postcss-loader", "rand", "rxjs", + "sass", + "sass-loader", "scopeguard", "security-framework", "security-framework-sys", + "semver", "serde", "serde_json", "simplelog", + "style-loader", "sysinfo", + "ts-loader", "tsconfig-paths-webpack-plugin", "type-fest", "typenum", @@ -288,6 +232,52 @@ commitMessagePrefix: "[deps] Platform:", reviewers: ["team:team-platform-dev"], }, + { + // We need to group all napi-related packages together to avoid build errors caused by version incompatibilities. + groupName: "napi", + matchPackageNames: ["napi", "napi-build", "napi-derive"], + }, + { + // We need to group all macOS/iOS binding-related packages together to avoid build errors caused by version incompatibilities. + groupName: "macOS/iOS bindings", + matchPackageNames: ["core-foundation", "security-framework", "security-framework-sys"], + }, + { + // We need to group all zbus-related packages together to avoid build errors caused by version incompatibilities. + groupName: "zbus", + matchPackageNames: ["zbus", "zbus_polkit"], + }, + { + // We group all webpack build-related minor and patch updates together to reduce PR noise. + // We include patch updates here because we want PRs for webpack patch updates and it's in this group. + matchPackageNames: [ + "@babel/core", + "@babel/preset-env", + "babel-loader", + "base64-loader", + "browserslist", + "copy-webpack-plugin", + "css-loader", + "html-loader", + "html-webpack-injector", + "html-webpack-plugin", + "mini-css-extract-plugin", + "postcss-loader", + "postcss", + "sass-loader", + "sass", + "style-loader", + "ts-loader", + "tsconfig-paths-webpack-plugin", + "webpack-cli", + "webpack-dev-server", + "webpack-node-externals", + "webpack", + ], + description: "webpack-related build dependencies", + groupName: "Minor and patch webpack updates", + matchUpdateTypes: ["minor", "patch"], + }, { matchPackageNames: [ "@angular-devkit/build-angular", @@ -303,6 +293,7 @@ "@angular/platform-browser", "@angular/platform", "@angular/router", + "axe-playwright", "@compodoc/compodoc", "@ng-select/ng-select", "@storybook/addon-a11y", @@ -311,6 +302,7 @@ "@storybook/addon-essentials", "@storybook/addon-interactions", "@storybook/addon-links", + "@storybook/test-runner", "@storybook/addon-themes", "@storybook/angular", "@storybook/manager-api", @@ -319,9 +311,7 @@ "autoprefixer", "bootstrap", "chromatic", - "jquery", "ngx-toastr", - "popper.js", "react", "react-dom", "remark-gfm", @@ -346,6 +336,11 @@ commitMessagePrefix: "[deps] SM:", reviewers: ["team:team-secrets-manager-dev"], }, + { + // We need to update several Jest-related packages together, for version compatibility. + groupName: "jest", + matchPackageNames: ["@types/jest", "jest", "ts-jest", "jest-preset-angular"], + }, { matchPackageNames: [ "@microsoft/signalr-protocol-msgpack", @@ -413,6 +408,18 @@ commitMessagePrefix: "[deps] KM:", reviewers: ["team:team-key-management-dev"], }, + { + // Any versions of lowdb above 1.0.0 are not compatible with CommonJS. + matchPackageNames: ["lowdb"], + allowedVersions: "1.0.0", + description: "Higher versions of lowdb are not compatible with CommonJS", + }, + { + // Pin types as well since we are not upgrading past v1 (and also v2+ does not need separate types). + matchPackageNames: ["@types/lowdb"], + allowedVersions: "< 2.0.0", + description: "Higher versions of lowdb do not need separate types", + }, ], - ignoreDeps: ["@types/koa-bodyparser", "bootstrap", "node-ipc", "node", "npm"], + ignoreDeps: ["@types/koa-bodyparser", "bootstrap", "node-ipc", "@bitwarden/sdk-internal"], } diff --git a/.github/workflows/build-browser-target.yml b/.github/workflows/build-browser-target.yml index 6f05cb71934..a2ae48d419b 100644 --- a/.github/workflows/build-browser-target.yml +++ b/.github/workflows/build-browser-target.yml @@ -8,10 +8,9 @@ name: Build Browser on PR Target on: pull_request_target: - types: [opened, synchronize] - branches-ignore: - - 'l10n_master' - - 'cf-pages' + types: [opened, synchronize, reopened] + branches: + - main paths: - 'apps/browser/**' - 'libs/**' diff --git a/.github/workflows/build-cli-target.yml b/.github/workflows/build-cli-target.yml index f817046ff30..6b493d4e6d9 100644 --- a/.github/workflows/build-cli-target.yml +++ b/.github/workflows/build-cli-target.yml @@ -8,10 +8,9 @@ name: Build CLI on PR Target on: pull_request_target: - types: [opened, synchronize] - branches-ignore: - - 'l10n_master' - - 'cf-pages' + types: [opened, synchronize, reopened] + branches: + - main paths: - 'apps/cli/**' - 'libs/**' diff --git a/.github/workflows/build-desktop-target.yml b/.github/workflows/build-desktop-target.yml index 65772223722..fa21b3fe5d9 100644 --- a/.github/workflows/build-desktop-target.yml +++ b/.github/workflows/build-desktop-target.yml @@ -9,10 +9,9 @@ name: Build Desktop on PR Target on: pull_request_target: - types: [opened, synchronize] - branches-ignore: - - 'l10n_master' - - 'cf-pages' + types: [opened, synchronize, reopened] + branches: + - main paths: - 'apps/desktop/**' - 'libs/**' diff --git a/.github/workflows/build-desktop.yml b/.github/workflows/build-desktop.yml index 6d954ca1098..74df17f1e5a 100644 --- a/.github/workflows/build-desktop.yml +++ b/.github/workflows/build-desktop.yml @@ -428,12 +428,6 @@ jobs: - name: Set up environmentF run: choco install checksum --no-progress - - name: Rust - shell: pwsh - run: | - rustup target install i686-pc-windows-msvc - rustup target install aarch64-pc-windows-msvc - - name: Print environment run: | node --version @@ -681,12 +675,6 @@ jobs: - name: Set up Node-gyp run: python3 -m pip install setuptools --break-system-packages - - name: Rust - shell: pwsh - run: | - rustup target add aarch64-apple-darwin - rustup target add x86_64-apple-darwin - - name: Print environment run: | node --version @@ -893,12 +881,6 @@ jobs: - name: Set up Node-gyp run: python3 -m pip install setuptools --break-system-packages - - name: Rust - shell: pwsh - run: | - rustup target add aarch64-apple-darwin - rustup target add x86_64-apple-darwin - - name: Print environment run: | node --version @@ -1046,10 +1028,7 @@ jobs: - name: Build Native Module if: steps.cache.outputs.cache-hit != 'true' working-directory: apps/desktop/desktop_native - run: | - rustup target add aarch64-apple-darwin - rustup target add x86_64-apple-darwin - node build.js cross-platform + run: node build.js cross-platform - name: Build if: steps.build-cache.outputs.cache-hit != 'true' @@ -1146,12 +1125,6 @@ jobs: - name: Set up Node-gyp run: python3 -m pip install setuptools --break-system-packages - - name: Rust - shell: pwsh - run: | - rustup target add aarch64-apple-darwin - rustup target add x86_64-apple-darwin - - name: Print environment run: | node --version @@ -1306,10 +1279,7 @@ jobs: - name: Build Native Module if: steps.cache.outputs.cache-hit != 'true' working-directory: apps/desktop/desktop_native - run: | - rustup target add aarch64-apple-darwin - rustup target add x86_64-apple-darwin - node build.js cross-platform + run: node build.js cross-platform - name: Build if: steps.build-cache.outputs.cache-hit != 'true' diff --git a/.github/workflows/build-web-target.yml b/.github/workflows/build-web-target.yml index 8f06d066d34..ca10e6d46f2 100644 --- a/.github/workflows/build-web-target.yml +++ b/.github/workflows/build-web-target.yml @@ -8,10 +8,9 @@ name: Build Web on PR Target on: pull_request_target: - types: [opened, synchronize] - branches-ignore: - - 'l10n_master' - - 'cf-pages' + types: [opened, synchronize, reopened] + branches: + - main paths: - 'apps/web/**' - 'libs/**' diff --git a/.github/workflows/build-web.yml b/.github/workflows/build-web.yml index 630e1e55682..019647f594a 100644 --- a/.github/workflows/build-web.yml +++ b/.github/workflows/build-web.yml @@ -291,7 +291,7 @@ jobs: - name: Install Cosign if: github.event_name != 'pull_request_target' && github.ref == 'refs/heads/main' - uses: sigstore/cosign-installer@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da # v3.7.0 + uses: sigstore/cosign-installer@3454372f43399081ed03b604cb2d021dabca52bb # v3.8.2 - name: Sign image with Cosign if: github.event_name != 'pull_request_target' && github.ref == 'refs/heads/main' @@ -309,7 +309,7 @@ jobs: - name: Scan Docker image if: ${{ needs.setup.outputs.has_secrets == 'true' }} id: container-scan - uses: anchore/scan-action@869c549e657a088dc0441b08ce4fc0ecdac2bb65 # v5.3.0 + uses: anchore/scan-action@2c901ab7378897c01b8efaa2d0c9bf519cc64b9e # v6.2.0 with: image: ${{ steps.image-name.outputs.name }} fail-build: false diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml index f436f1b3760..78733bc5a8b 100644 --- a/.github/workflows/chromatic.yml +++ b/.github/workflows/chromatic.yml @@ -7,7 +7,9 @@ on: - "rc" - "hotfix-rc" pull_request_target: - types: [opened, synchronize] + types: [opened, synchronize, reopened] + branches: + - "main" jobs: check-run: @@ -73,7 +75,7 @@ jobs: run: npm run build-storybook:ci - name: Publish to Chromatic - uses: chromaui/action@8a12962215a66cd05b1ac5b0f1c08768d1aab155 # v11.25.0 + uses: chromaui/action@e8cc4c31775280b175a3c440076c00d19a9014d7 # v11.28.2 with: token: ${{ secrets.GITHUB_TOKEN }} projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} diff --git a/.github/workflows/crowdin-pull.yml b/.github/workflows/crowdin-pull.yml index 32907699747..2fc035ec038 100644 --- a/.github/workflows/crowdin-pull.yml +++ b/.github/workflows/crowdin-pull.yml @@ -22,7 +22,7 @@ jobs: crowdin_project_id: "308189" steps: - name: Generate GH App token - uses: actions/create-github-app-token@d72941d797fd3113feb6b93fd0dec494b13a2547 # v1.12.0 + uses: actions/create-github-app-token@30bf6253fa41bdc8d1501d202ad15287582246b4 # v2.0.3 id: app-token with: app-id: ${{ secrets.BW_GHAPP_ID }} diff --git a/.github/workflows/repository-management.yml b/.github/workflows/repository-management.yml index 06daf70d7c9..8ab74adf543 100644 --- a/.github/workflows/repository-management.yml +++ b/.github/workflows/repository-management.yml @@ -66,7 +66,7 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Generate GH App token - uses: actions/create-github-app-token@d72941d797fd3113feb6b93fd0dec494b13a2547 # v1.12.0 + uses: actions/create-github-app-token@30bf6253fa41bdc8d1501d202ad15287582246b4 # v2.0.3 id: app-token with: app-id: ${{ secrets.BW_GHAPP_ID }} @@ -115,7 +115,7 @@ jobs: version: ${{ inputs.version_number_override }} - name: Generate GH App token - uses: actions/create-github-app-token@d72941d797fd3113feb6b93fd0dec494b13a2547 # v1.12.0 + uses: actions/create-github-app-token@30bf6253fa41bdc8d1501d202ad15287582246b4 # v2.0.3 id: app-token with: app-id: ${{ secrets.BW_GHAPP_ID }} @@ -452,7 +452,7 @@ jobs: - setup steps: - name: Generate GH App token - uses: actions/create-github-app-token@d72941d797fd3113feb6b93fd0dec494b13a2547 # v1.12.0 + uses: actions/create-github-app-token@30bf6253fa41bdc8d1501d202ad15287582246b4 # v2.0.3 id: app-token with: app-id: ${{ secrets.BW_GHAPP_ID }} diff --git a/.github/workflows/scan.yml b/.github/workflows/scan.yml index 77b66ba8bf1..59ef1e0734e 100644 --- a/.github/workflows/scan.yml +++ b/.github/workflows/scan.yml @@ -7,8 +7,14 @@ on: - "main" - "rc" - "hotfix-rc" + pull_request: + types: [opened, synchronize, reopened] + branches-ignore: + - main pull_request_target: - types: [opened, synchronize] + types: [opened, synchronize, reopened] + branches: + - "main" jobs: check-run: @@ -68,7 +74,7 @@ jobs: ref: ${{ github.event.pull_request.head.sha }} - name: Scan with SonarCloud - uses: sonarsource/sonarqube-scan-action@bfd4e558cda28cda6b5defafb9232d191be8c203 # v4.2.1 + uses: sonarsource/sonarqube-scan-action@2500896589ef8f7247069a56136f8dc177c27ccf # v5.2.0 env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} with: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6411337f6e9..64cc86f1db6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,7 +8,7 @@ on: - "rc" - "hotfix-rc-*" pull_request: - types: [opened, synchronize] + types: [ opened, synchronize ] jobs: @@ -58,7 +58,7 @@ jobs: run: npm test -- --coverage --maxWorkers=3 - name: Report test results - uses: dorny/test-reporter@31a54ee7ebcacc03a09ea97a7e5465a47b84aea5 # v1.9.1 + uses: dorny/test-reporter@6e6a65b7a0bd2c9197df7d0ae36ac5cee784230c # v2.0.0 if: ${{ github.event.pull_request.head.repo.full_name == github.repository && !cancelled() }} with: name: Test Results @@ -66,11 +66,14 @@ jobs: reporter: jest-junit fail-on-error: true - - name: Upload coverage to codecov.io - uses: codecov/codecov-action@1e68e06f1dbfde0e4cefc87efeba9e4643565303 # v5.1.2 - - name: Upload results to codecov.io - uses: codecov/test-results-action@4e79e65778be1cecd5df25e14af1eafb6df80ea9 # v1.0.2 + uses: codecov/test-results-action@f2dba722c67b86c6caa034178c6e4d35335f6706 # v1.1.0 + + - name: Upload test coverage + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 + with: + name: jest-coverage + path: ./coverage/lcov.info rust: name: Run Rust tests on ${{ matrix.os }} @@ -148,7 +151,37 @@ jobs: working-directory: ./apps/desktop/desktop_native run: cargo llvm-cov --all-features --lcov --output-path lcov.info --workspace --no-cfg-coverage - - name: Upload to codecov.io - uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # v5.3.1 + - name: Upload test coverage + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: - files: ./apps/desktop/desktop_native/lcov.info + name: rust-coverage + path: ./apps/desktop/desktop_native/lcov.info + + upload-codecov: + name: Upload to Codecov + runs-on: ubuntu-22.04 + needs: + - testing + - rust-coverage + steps: + - name: Check out repo + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Download jest coverage + uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 + with: + name: jest-coverage + path: ./ + + - name: Download rust coverage + uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 + with: + name: rust-coverage + path: ./apps/desktop/desktop_native + + - name: Upload coverage to codecov.io + uses: codecov/codecov-action@ad3126e916f78f00edff4ed0317cf185271ccc2d # v5.4.2 + with: + files: | + ./lcov.info + ./apps/desktop/desktop_native/lcov.info diff --git a/.github/workflows/version-auto-bump.yml b/.github/workflows/version-auto-bump.yml index 9431eab37c5..e8bd1dde246 100644 --- a/.github/workflows/version-auto-bump.yml +++ b/.github/workflows/version-auto-bump.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Generate GH App token - uses: actions/create-github-app-token@d72941d797fd3113feb6b93fd0dec494b13a2547 # v1.12.0 + uses: actions/create-github-app-token@30bf6253fa41bdc8d1501d202ad15287582246b4 # v2.0.3 id: app-token with: app-id: ${{ secrets.BW_GHAPP_ID }} diff --git a/.gitignore b/.gitignore index e865fa6a8fb..0fa968aa47c 100644 --- a/.gitignore +++ b/.gitignore @@ -34,6 +34,9 @@ build # Testing coverage junit.xml +## The "base" root level folder is expected for some local tests that do +## comparisons between the current branch and a base branch (usually main) +base/ # Misc *.crx diff --git a/.storybook/format-args-for-code-snippet.ts b/.storybook/format-args-for-code-snippet.ts new file mode 100644 index 00000000000..bf36c153c0a --- /dev/null +++ b/.storybook/format-args-for-code-snippet.ts @@ -0,0 +1,33 @@ +import { argsToTemplate, StoryObj } from "@storybook/angular"; + +type RenderArgType = StoryObj["args"]; + +export const formatArgsForCodeSnippet = >( + args: RenderArgType, +) => { + const nonNullArgs = Object.entries(args as ComponentType).filter( + ([_, value]) => value !== null && value !== undefined, + ); + const functionArgs = nonNullArgs.filter(([_, value]) => typeof value === "function"); + const argsToFormat = nonNullArgs.filter(([_, value]) => typeof value !== "function"); + + const argsToTemplateIncludeKeys = [...functionArgs].map( + ([key, _]) => key as keyof RenderArgType, + ); + + const formattedNonFunctionArgs = argsToFormat + .map(([key, value]) => { + if (typeof value === "boolean") { + return `[${key}]="${value}"`; + } + + if (Array.isArray(value)) { + const formattedArray = value.map((v) => `'${v}'`).join(", "); + return `[${key}]="[${formattedArray}]"`; + } + return `${key}="${value}"`; + }) + .join(" "); + + return `${formattedNonFunctionArgs} ${argsToTemplate(args as ComponentType, { include: argsToTemplateIncludeKeys })}`; +}; diff --git a/.storybook/main.ts b/.storybook/main.ts index 9583d1fc6f2..879e87fe376 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -8,6 +8,8 @@ const config: StorybookConfig = { stories: [ "../libs/auth/src/**/*.mdx", "../libs/auth/src/**/*.stories.@(js|jsx|ts|tsx)", + "../libs/dirt/card/src/**/*.mdx", + "../libs/dirt/card/src/**/*.stories.@(js|jsx|ts|tsx)", "../libs/tools/send/send-ui/src/**/*.mdx", "../libs/tools/send/send-ui/src/**/*.stories.@(js|jsx|ts|tsx)", "../libs/vault/src/**/*.mdx", @@ -20,8 +22,7 @@ const config: StorybookConfig = { "../apps/browser/src/**/*.stories.@(js|jsx|ts|tsx)", "../bitwarden_license/bit-web/src/**/*.mdx", "../bitwarden_license/bit-web/src/**/*.stories.@(js|jsx|ts|tsx)", - "../libs/tools/card/src/**/*.mdx", - "../libs/tools/card/src/**/*.stories.@(js|jsx|ts|tsx)", + "../libs/angular/src/**/*.stories.@(js|jsx|ts|tsx)", ], addons: [ getAbsolutePath("@storybook/addon-links"), diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index 6bd28cfe809..59b5287f3a3 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -26,6 +26,9 @@ const preview: Preview = { wrapperDecorator, ], parameters: { + a11y: { + element: "#storybook-root", + }, controls: { matchers: { color: /(background|color)$/i, @@ -38,7 +41,12 @@ const preview: Preview = { order: ["Documentation", ["Introduction", "Colors", "Icons"], "Component Library"], }, }, - docs: { source: { type: "dynamic", excludeDecorators: true } }, + docs: { + source: { + type: "dynamic", + excludeDecorators: true, + }, + }, backgrounds: { disable: true, }, diff --git a/.storybook/test-runner.ts b/.storybook/test-runner.ts new file mode 100644 index 00000000000..208adf96214 --- /dev/null +++ b/.storybook/test-runner.ts @@ -0,0 +1,47 @@ +import { type TestRunnerConfig } from "@storybook/test-runner"; +import { injectAxe, checkA11y } from "axe-playwright"; + +const testRunnerConfig: TestRunnerConfig = { + setup() {}, + + async preVisit(page, context) { + return await injectAxe(page); + }, + + async postVisit(page, context) { + await page.waitForSelector("#storybook-root"); + // https://github.com/abhinaba-ghosh/axe-playwright#parameters-on-checka11y-axerun + await checkA11y( + // Playwright page instance. + page, + + // context + "#storybook-root", + + // axeOptions, see https://www.deque.com/axe/core-documentation/api-documentation/#parameters-axerun + { + detailedReport: true, + detailedReportOptions: { + // Includes the full html for invalid nodes + html: true, + }, + verbose: false, + }, + + // skipFailures + false, + + // reporter "v2" is terminal reporter, "html" writes results to file + "v2", + + // axeHtmlReporterOptions + // NOTE: set reporter param (above) to "html" to activate these options + { + outputDir: "reports/a11y", + reportFileName: `${context.id}.html`, + }, + ); + }, +}; + +export default testRunnerConfig; diff --git a/angular.json b/angular.json index 665d810cf4e..87ee7dc57b2 100644 --- a/angular.json +++ b/angular.json @@ -6,6 +6,32 @@ "analytics": false }, "projects": { + "bit-web": { + "projectType": "application", + "schematics": { + "@schematics/angular:application": { + "strict": true + } + }, + "root": "bitwarden_license/bit-web", + "sourceRoot": "bitwarden_license/bit-web/src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "outputPath": "dist/web", + "index": "apps/web/src/index.html", + "main": "bitwarden_license/bit-web/src/app/main.ts", + "polyfills": "apps/web/src/polyfills.ts", + "tsConfig": "bitwarden_license/bit-web/tsconfig.json", + "assets": ["apps/web/src/favicon.ico"], + "styles": [], + "scripts": [] + } + } + } + }, "web": { "projectType": "application", "schematics": { @@ -22,8 +48,8 @@ "options": { "outputPath": "dist/web", "index": "apps/web/src/index.html", - "main": "apps/web/src/app/main.ts", - "polyfills": "apps/web/src/app/polyfills.ts", + "main": "apps/web/src/main.ts", + "polyfills": "apps/web/src/polyfills.ts", "tsConfig": "apps/web/tsconfig.json", "assets": ["apps/web/src/favicon.ico"], "styles": [], diff --git a/apps/browser/jest.config.js b/apps/browser/jest.config.js index 73f5ada287a..14cd959810e 100644 --- a/apps/browser/jest.config.js +++ b/apps/browser/jest.config.js @@ -1,18 +1,17 @@ const { pathsToModuleNameMapper } = require("ts-jest"); -const { compilerOptions } = require("./tsconfig"); +const { compilerOptions } = require("../../tsconfig.base"); const sharedConfig = require("../../libs/shared/jest.config.angular"); /** @type {import('jest').Config} */ module.exports = { ...sharedConfig, - preset: "jest-preset-angular", setupFilesAfterEnv: ["/test.setup.ts"], moduleNameMapper: pathsToModuleNameMapper( - { "@bitwarden/common/spec": ["../../libs/common/spec"], ...(compilerOptions?.paths ?? {}) }, + { "@bitwarden/common/spec": ["libs/common/spec"], ...(compilerOptions?.paths ?? {}) }, { - prefix: "/", + prefix: "/../../", }, ), }; diff --git a/apps/browser/package.json b/apps/browser/package.json index 9ed3c807c11..c44743add7c 100644 --- a/apps/browser/package.json +++ b/apps/browser/package.json @@ -1,6 +1,6 @@ { "name": "@bitwarden/browser", - "version": "2025.4.0", + "version": "2025.5.1", "scripts": { "build": "npm run build:chrome", "build:chrome": "cross-env BROWSER=chrome MANIFEST_VERSION=3 NODE_OPTIONS=\"--max-old-space-size=8192\" webpack", diff --git a/apps/browser/src/_locales/ar/messages.json b/apps/browser/src/_locales/ar/messages.json index c2f3c72f281..0a8ba5b1164 100644 --- a/apps/browser/src/_locales/ar/messages.json +++ b/apps/browser/src/_locales/ar/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "حفظ كتسجيل دخول جديد", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "تحديث تسجيل الدخول", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "اقتراحات التعبئة التلقائية" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "إظهار اقتراحات التعبئة التلقائية في حقول النموذج" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "استخدم كلمة المرور هذه" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "استخدم اسم المستخدم هذا" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "إجراء المهلة" }, - "newCustomizationOptionsCalloutTitle": { - "message": "خيارات التخصيص الجديدة" - }, - "newCustomizationOptionsCalloutContent": { - "message": "تخصيص تجربة المخزن الخاص بك مع إجراءات النسخ السريعة، والوضع المدمج، والمزيد!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "عرض جميع إعدادات المظهر" - }, "lock": { "message": "قفل", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "كل الإرسالات", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "إخفاء النص بشكل افتراضي" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "لم يتم العثور على معرف فريد." }, - "convertOrganizationEncryptionDesc": { - "message": "يستخدم $ORGANIZATION$ SSO مع خادم مفتاح الاستضافة الذاتية. لم تعد هناك حاجة إلى كلمة مرور رئيسية لتسجيل الدخول لأعضاء هذه المنظمة.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "مغادرة المؤسسة" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Device trusted" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "No active Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Use Send to securely share encrypted information with anyone.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Input is required." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Are you sure you want to permanently delete this attachment?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Authenticating" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Important notice" - }, - "setupTwoStepLogin": { - "message": "Set up two-step login" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Remind me later" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" - }, - "turnOnTwoStepLogin": { - "message": "Turn on two-step login" - }, - "changeAcctEmail": { - "message": "Change account email" - }, "extensionWidth": { "message": "Extension width" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/az/messages.json b/apps/browser/src/_locales/az/messages.json index 3550ec52462..a38c590e4d4 100644 --- a/apps/browser/src/_locales/az/messages.json +++ b/apps/browser/src/_locales/az/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "Yeni element, yeni bir pəncərədə açılır", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Saxlamazdan əvvəl düzəliş et", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ Bitwarden-də saxlanıldı.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "\"Bitwarden\"də saxlanıldı.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ Bitwarden-də güncəlləndi.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "\"Bitwarden\"də güncəlləndi.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "$ITEMTYPE$, $ITEMNAME$ seç", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Yeni giriş kimi saxla", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Giriş məlumatlarını güncəllə", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Bu girişi saxlamaq üçün kilidi açın", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Girişi saxla", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Avto-doldurma təklifləri" }, + "autofillSpotlightTitle": { + "message": "Avto-doldurma təkliflərini asanlıqla tap" + }, + "autofillSpotlightDesc": { + "message": "Bitwarden ilə ziddiyyət yaranmaması üçün brauzerinizin avto-doldurma ayarlarını söndürün." + }, + "turnOffBrowserAutofill": { + "message": "$BROWSER$ avto-doldurma ayarını söndür", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Avto-doldurmanı söndür" + }, "showInlineMenuLabel": { "message": "Avto-doldurma təkliflərini form xanalarında göstər" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Bu parolu istifadə et" }, + "useThisPassphrase": { + "message": "Bu keçid ifadəsini istifadə et" + }, "useThisUsername": { "message": "Bu istifadəçi adını istifadə et" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Vaxt bitmə əməliyyatı" }, - "newCustomizationOptionsCalloutTitle": { - "message": "Yeni özəlləşdirmə seçimləri" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Cəld kopyalama fəaliyyəti, yığcam rejim və daha çoxu ilə seyf təcrübənizi özəlləşdirin!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "Bütün Görünüş ayarlarına bax" - }, "lock": { "message": "Kilidlə", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "Bütün \"Send\"lər", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Maksimal müraciət sayına çatıldı", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Mətni ilkin olaraq gizlət" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Unikal identifikator tapılmadı." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$, self-hosted açar serveri ilə SSO istifadə edir. Bu təşkilatın üzvlərinin giriş etməsi üçün artıq ana parol tələb edilməyəcək.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "Aşağıdakı təşkilatların üzvləri üçün artıq ana parol tələb olunmur. Lütfən aşağıdakı domeni təşkilatınızın inzibatçısı ilə təsdiqləyin." + }, + "organizationName": { + "message": "Təşkilat adı" + }, + "keyConnectorDomain": { + "message": "Key Connector domeni" }, "leaveOrganization": { "message": "Təşkilatı tərk et" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Cihaz güvənlidir" }, + "trustOrganization": { + "message": "Təşkilata güvən" + }, + "trust": { + "message": "Güvən" + }, + "doNotTrust": { + "message": "Güvənmə" + }, + "organizationNotTrusted": { + "message": "Təşkilata güvənilmir" + }, + "emergencyAccessTrustWarning": { + "message": "Hesabınızın təhlükəsizliyi üçün yalnız bu istifadəçiyə fövqəladə hal müraciəti icazəsini verdiyinizi və onun barmaq izinin hesabında görünən barmaq izi ilə uyuşduğunu təsdiqləyin" + }, + "orgTrustWarning": { + "message": "Hesabınızın təhlükəsizliyi üçün yalnız bu təşkilatın üzvüsünüzsə, hesab geri qaytarma fəaldırsa və aşağıda görünən barmaq izi təşkilatın barmaq izi ilə uyuşursa davam edin." + }, + "orgTrustWarning1": { + "message": "Bu təşkilat, sahib olduğu Müəssisə siyasəti ilə sizi hesabın qaytarılması prosesinə yazdıracaq. Yazılma, təşkilat inzibatçılarının parolunuzu dəyişdirməsinə imkan verəcək. Yalnız bu təşkilatı tanıyırsınızsa və aşağıda görünən barmaq izi ifadəsi, təşkilatın barmaq izi ifadəsi ilə uyuşursa davam edin." + }, + "trustUser": { + "message": "İstifadəçiyə güvən" + }, "sendsNoItemsTitle": { "message": "Aktiv \"Send\" yoxdur", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Şifrələnmiş məlumatları hər kəslə güvənli şəkildə paylaşmaq üçün \"Send\"i istifadə edin.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send, həssas məlumatlar təhlükəsizdir", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "İstənilən platformada faylları və dataları hər kəslə paylaşın. İfşa olunmağı məhdudlaşdıraraq məlumatlarınız ucdan-uca şifrələnmiş qalacaq.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Giriş lazımdır." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Bitwarden-i endir" + }, + "downloadBitwardenOnAllDevices": { + "message": "Bitwarden-i bütün cihazlarda endir" + }, + "getTheMobileApp": { + "message": "Mobil tətbiqi əldə et" + }, + "getTheMobileAppDesc": { + "message": "Bitwarden mobil tətbiqi ilə parollarınıza hər yerdən müraciət edin." + }, + "getTheDesktopApp": { + "message": "Masaüstü tətbiqi əldə et" + }, + "getTheDesktopAppDesc": { + "message": "Seyfinizə brauzer olmadan müraciət edin, sonra həm masaüstü tətbiqində, həm də brauzer uzantısında kilid açma prosesini sürətləndirmək üçün biometrik ilə kilid açma prosesini qurun." + }, + "downloadFromBitwardenNow": { + "message": "İndi bitwarden.com saytından endir" + }, + "getItOnGooglePlay": { + "message": "Google Play-dən endir" + }, + "downloadOnTheAppStore": { + "message": "App Store-dan endir" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Bu qoşmanı birdəfəlik silmək istədiyinizə əminsiniz?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Bilinməyən bilinməyən bir səbəbə görə biometrik kilid açma əlçatmazdır." }, + "unlockVault": { + "message": "Seyfinizin kilidini saniyələr ərzində açın" + }, + "unlockVaultDesc": { + "message": "Seyfinizə daha cəld müraciət etmək üçün kilid açma və bitmə vaxtı ayarlarını özəlləşdirə bilərsiniz." + }, + "unlockPinSet": { + "message": "PIN ilə kilid açma təyini" + }, "authenticating": { "message": "Kimlik doğrulama" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Vacib bildiriş" - }, - "setupTwoStepLogin": { - "message": "İki addımlı girişi qur" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden, 2025-ci ilin Fevral ayından etibarən yeni cihazlardan gələn girişləri doğrulamaq üçün hesabınızın e-poçtuna bir kod göndərəcək." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "Hesabınızı qorumaq üçün alternativ bir yol kimi iki addımlı girişi qura və ya e-poçtunuzu müraciət edə biləcəyiniz e-poçtla dəyişdirə bilərsiniz." - }, - "remindMeLater": { - "message": "Daha sonra xatırlat" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "$EMAIL$ e-poçtunuza güvənli şəkildə müraciət edə bilirsiniz?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "Xeyr, edə bilmirəm" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Bəli, e-poçtuma güvənli şəkildə müraciət edə bilirəm" - }, - "turnOnTwoStepLogin": { - "message": "İki addımlı girişi işə sal" - }, - "changeAcctEmail": { - "message": "Hesabın e-poçtunu dəyişdir" - }, "extensionWidth": { "message": "Uzantı eni" }, @@ -5202,10 +5260,10 @@ "message": "Riskli parolları dəyişdir" }, "settingsVaultOptions": { - "message": "Vault options" + "message": "Seyf seçimləri" }, "emptyVaultDescription": { - "message": "The vault protects more than just your passwords. Store secure logins, IDs, cards and notes securely here." + "message": "Seyf, yalnız parollarızı yox, həm də daha çoxunu qoruyur. Giriş məlumatlarınızı, kimlikləri, kartları və notları burada güvənli şəkildə saxlayın." }, "introCarouselLabel": { "message": "Bitwarden-ə xoş gəlmisiniz" @@ -5234,49 +5292,97 @@ "secureDevicesBody": { "message": "Bitwarden mobil, brauzer və masaüstü tətbiqləri ilə limitsiz cihaz arasında limitsiz parol saxlayın." }, + "nudgeBadgeAria": { + "message": "1 bildiriş" + }, "emptyVaultNudgeTitle": { - "message": "Import existing passwords" + "message": "Mövcud parolları daxilə köçür" }, "emptyVaultNudgeBody": { - "message": "Use the importer to quickly transfer logins to Bitwarden without manually adding them." + "message": "Giriş məlumatlarını əllə daxil etmədən daha tez daxilə köçürmək üçün \"Daxilə köçürücü\"nü istifadə edin." }, "emptyVaultNudgeButton": { - "message": "Import now" + "message": "İndi daxilə köçür" }, "hasItemsVaultNudgeTitle": { - "message": "Welcome to your vault!" + "message": "Seyfinizə xoş gəlmisiniz!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Hazırkı səhifə üçün elementləri avto-doldur" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Asan müraciət üçün elementləri sevimlilərə əlavə et" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Seyfinizdə başqa bir şey axtarın" }, "newLoginNudgeTitle": { - "message": "Save time with autofill" + "message": "Avto-doldurma ilə vaxta qənaət edin" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Bir veb sayt", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "daxil edin ki,", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "bu giriş məlumatları avto-doldurma təklifi kimi görünsün.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { - "message": "Seamless online checkout" + "message": "Problemsiz onlayn ödəniş" }, "newCardNudgeBody": { - "message": "With cards, easily autofill payment forms securely and accurately." + "message": "Kartlarla, ödəniş xanalarını təhlükəsiz və doğru şəkildə avtomatik doldurun." }, "newIdentityNudgeTitle": { - "message": "Simplify creating accounts" + "message": "Hesab yaratmanı sadələşdirin" }, "newIdentityNudgeBody": { - "message": "With identities, quickly autofill long registration or contact forms." + "message": "Kimliklərinizlə, uzun qeydiyyat və ya əlaqə xanalarını daha tez avtomatik doldurun." }, "newNoteNudgeTitle": { - "message": "Keep your sensitive data safe" + "message": "Həssas datalarınızı güvənli şəkildə saxlayın" }, "newNoteNudgeBody": { - "message": "With notes, securely store sensitive data like banking or insurance details." + "message": "Notlarla, bankçılıq və ya sığorta təfsilatları kimi həssas dataları təhlükəsiz saxlayın." }, "newSshNudgeTitle": { - "message": "Developer-friendly SSH access" + "message": "Gəlişdirici dostu SSH müraciəti" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Açarlarınızı saxlayın və sürətli, şifrələnmiş kimlik doğrulama üçün SSH agentinə bağlayın.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "SSH agenti barədə daha ətraflı", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Cəld parol yaradın" + }, + "generatorNudgeBodyOne": { + "message": "Klikləyərək güclü və unikal parolları asanlıqla yaradın", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "və girişlərinizi güvənli şəkildə saxlayın.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Girişlərinizi güvənli şəkildə saxlamağınıza kömək etməsi üçün Parol yarat düyməsinə klikləyərək güclü və unikal parolları asanlıqla yaradın.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "Bu səhifəyə baxmaq icazəniz yoxdur. Fərqli hesabla giriş etməyə çalışın." } } diff --git a/apps/browser/src/_locales/be/messages.json b/apps/browser/src/_locales/be/messages.json index 20c5bb8ff35..888569cd588 100644 --- a/apps/browser/src/_locales/be/messages.json +++ b/apps/browser/src/_locales/be/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Прапановы аўтазапаўнення" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Show autofill suggestions on form fields" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Выкарыстоўваць гэты пароль" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Выкарыстоўваць гэта імя карыстальніка" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Timeout action" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "Заблакіраваць", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "Усе Send’ы", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Hide text by default" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Не знойдзены ўнікальны ідэнтыфікатар." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ выкарыстоўвае SSO з уласным серверам ключоў. Асноўны пароль для ўдзельнікаў гэтай арганізацыі больш не патрабуецца.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Выйсці з арганізацыі" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Давераная прылада" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "Няма актыўных Send'аў", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Выкарыстоўвайце Send'ы, каб бяспечна абагуляць зашыфраваную інфармацыю з іншымі.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Неабходны ўвод даных." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Are you sure you want to permanently delete this attachment?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Authenticating" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Important notice" - }, - "setupTwoStepLogin": { - "message": "Set up two-step login" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Remind me later" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" - }, - "turnOnTwoStepLogin": { - "message": "Turn on two-step login" - }, - "changeAcctEmail": { - "message": "Change account email" - }, "extensionWidth": { "message": "Extension width" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/bg/messages.json b/apps/browser/src/_locales/bg/messages.json index 2bc42c0e6c9..ac99ce4376e 100644 --- a/apps/browser/src/_locales/bg/messages.json +++ b/apps/browser/src/_locales/bg/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "Нов елемент, отваря се в нов прозорец", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Редактиране преди запазване", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "Запазено в Битуорден: $ITEMNAME$.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "запазено в Битуорден.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "Обновено в Битуорден: $ITEMNAME$.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "обновено в Битуорден.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Избиране на $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Запазване като нов елемент за вписване", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Обновяване на данните за вписване", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Отключете, за да запазите тези данни за вписване", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Запазване на данните за вписване", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Предложения за авт. попълване" }, + "autofillSpotlightTitle": { + "message": "Намирайте лесно предложения за авт. попълване" + }, + "autofillSpotlightDesc": { + "message": "Изключете настройките за автоматично попълване на браузъра си, за да не си пречат с Битуорден." + }, + "turnOffBrowserAutofill": { + "message": "Изключете автоматичното попълване на $BROWSER$", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Изключване на автоматичното попълване" + }, "showInlineMenuLabel": { "message": "Показване на предложения за авт. попълване на полетата във формуляри" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Използване на тази парола" }, + "useThisPassphrase": { + "message": "Използване на тази парола-фраза" + }, "useThisUsername": { "message": "Използване на това потребителско име" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Действие при изтичането на времето за достъп" }, - "newCustomizationOptionsCalloutTitle": { - "message": "Нови възможности за персонализиране" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Персонализирайте трезора си с бързи действия за копиране, компактен режим и още!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "Преглед на всички настройки за външния вид" - }, "lock": { "message": "Заключване", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "Всички изпращания", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Достигнат е максималният брой достъпвания", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Скриване на текста по подразбиране" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Няма намерен уникален идентификатор." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ използва еднократно удостоверяване със собствен сървър за ключове. Членовете на тази организация вече нямат нужда от главна парола за вписване.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "За членовете на следната организация вече не се изисква главна парола. Потвърдете домейна по-долу с администратора на организацията си." + }, + "organizationName": { + "message": "Име на организацията" + }, + "keyConnectorDomain": { + "message": "Домейн на конектора за ключове" }, "leaveOrganization": { "message": "Напускане на организацията" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Устройството е доверено" }, + "trustOrganization": { + "message": "Даване на доверие на организацията" + }, + "trust": { + "message": "Даване на доверие" + }, + "doNotTrust": { + "message": "Да не се дава доверие" + }, + "organizationNotTrusted": { + "message": "Организацията не е доверена" + }, + "emergencyAccessTrustWarning": { + "message": "С оглед на сигурността на акаунта Ви, потвърдете само, ако сте дали на този потребител достъп за спешни случаи и ако отпечатъкът му съвпада с това, което се вижда в акаунта му" + }, + "orgTrustWarning": { + "message": "С оглед на сигурността на акаунта Ви, продължете само, ако сте член на тази организация, ако възстановяването на акаунта Ви е включено и ако отпечатъкът показан по-долу съвпада с този на организацията." + }, + "orgTrustWarning1": { + "message": "Тази организация има политика от плана за големи организации, която ще Ви включи в схемата за възстановяване на акаунти. Това включване ще позволи на администраторите да променят паролата Ви. Продължете само, ако разпознавате тази организация и уникалната фраза показана по-долу съвпада с отпечатъка на организацията." + }, + "trustUser": { + "message": "Даване на доверие на потребителя" + }, "sendsNoItemsTitle": { "message": "Няма активни Изпращания", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Използвайте Изпращане, за да споделите безопасно шифрована информация с някого.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Изпращайте чувствителна информация сигурно", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Споделяйте сигурно файлове и данни с всекиго, през всяка система. Информацията Ви ще бъде защитена с шифроване от край до край, а видимостта ѝ ще бъде ограничена.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Полето е задължително да бъде попълнено." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Сваляне на Битуорден" + }, + "downloadBitwardenOnAllDevices": { + "message": "Сваляне на Битуорден на всички устройства" + }, + "getTheMobileApp": { + "message": "Свалете мобилното приложение" + }, + "getTheMobileAppDesc": { + "message": "Разполагайте с паролите си дори когато сте в движение, с мобилното приложение на Битуорден." + }, + "getTheDesktopApp": { + "message": "Свалете настолното приложение" + }, + "getTheDesktopAppDesc": { + "message": "Използвайте трезора си без браузър. Можете да настроите отключване с биометрични данни, за да ускорите отключването както в настолното приложение, така и в добавката за браузъра." + }, + "downloadFromBitwardenNow": { + "message": "Свалете от bitwarden.com сега" + }, + "getItOnGooglePlay": { + "message": "Вземете го от Google Play" + }, + "downloadOnTheAppStore": { + "message": "Свалете от App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Наистина ли искате да изтриете завинаги този прикачен файл?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Отключването с биометрични данни не е налично по неизвестна причина." }, + "unlockVault": { + "message": "Отключвайте трезора си за секунди" + }, + "unlockVaultDesc": { + "message": "Можете да персонализирате настройките си за отключване и време на активност, за да получавате достъп до трезора си по-бързо." + }, + "unlockPinSet": { + "message": "Зададен е ПИН код за отключване" + }, "authenticating": { "message": "Удостоверяване" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Бета" }, - "importantNotice": { - "message": "Важно съобщение" - }, - "setupTwoStepLogin": { - "message": "Настройте двустепенно удостоверяване" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Битуорден ще изпрати код до е-пощата Ви, за потвърждаване на вписването от нови устройства. Това ще започне от февруари 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "Можете да настроите двустепенно удостоверяване, като различен метод на защита, или ако е необходимо да промените е-пощата си с такава, до която имате достъп." - }, - "remindMeLater": { - "message": "Напомнете ми по-късно" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Имате ли сигурен достъп до е-пощата си – $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "Не, нямам" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Да, имам достъп до е-пощата си" - }, - "turnOnTwoStepLogin": { - "message": "Включване на двустепенното удостоверяване" - }, - "changeAcctEmail": { - "message": "Промяна на е-пощата" - }, "extensionWidth": { "message": "Ширина на разширението" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Съхранявайте неограничен брой пароли на множество устройства – с приложенията на Битуорден за мобилни телефони, браузър и компютър." }, + "nudgeBadgeAria": { + "message": "1 известие" + }, "emptyVaultNudgeTitle": { "message": "Внасяне на съществуващи пароли" }, @@ -5246,37 +5307,82 @@ "hasItemsVaultNudgeTitle": { "message": "Добре дошли в трезора си!" }, - "hasItemsVaultNudgeBody": { - "message": "Елементи за авт. попълване в текущата страница\nЛюбими елементи за лесен достъп\nПотърсете в трезора си за нещо друго" + "hasItemsVaultNudgeBodyOne": { + "message": "Попълвайте автоматично елементи в текущата страница" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Добавете любими елементи за бърз достъп" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Потърсете нещо друго в трезора си" }, "newLoginNudgeTitle": { - "message": "Save time with autofill" + "message": "Спестете време с автоматично попълване" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Добавете", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "уеб сайт", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": ", за да може тези данни за вписване да се появяват като предложение за автоматично попълване.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { - "message": "Seamless online checkout" + "message": "Безпроблемни плащания" }, "newCardNudgeBody": { - "message": "With cards, easily autofill payment forms securely and accurately." + "message": "С възможността за запазване на карти, можете лесно да ги попълвате автоматично във формулярите – сигурно и точно." }, "newIdentityNudgeTitle": { - "message": "Simplify creating accounts" + "message": "Опростено създаване на акаунти" }, "newIdentityNudgeBody": { - "message": "With identities, quickly autofill long registration or contact forms." + "message": "С възможността за запазване на самоличности, можете лесно да попълвате автоматично дълги формуляри за регистрация или връзка с уеб сайт." }, "newNoteNudgeTitle": { - "message": "Keep your sensitive data safe" + "message": "Пазете тайните си на сигурно място" }, "newNoteNudgeBody": { - "message": "With notes, securely store sensitive data like banking or insurance details." + "message": "С възможността за запазване на бележки, можете да съхранявате тайна информация, като например банкови и застрахователни данни." }, "newSshNudgeTitle": { - "message": "Developer-friendly SSH access" + "message": "Улеснен достъп за разработчици чрез SSH" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Съхранявайте ключове и използвайте връзка чрез SSH агента, за бързо и шифровано удостоверяване.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Научете повече относно SSH-агента", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Създавайте пароли бързо" + }, + "generatorNudgeBodyOne": { + "message": "Създавайте лесно сложни и уникални пароли като щракнете върху", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "за да защитите данните си за вписване.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Създавайте лесно сложни и уникални пароли като щракнете върху бутона за генериране на парола, за да защитите данните си за вписване.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "Нямате права за преглед на тази страница. Опитайте да се впишете с друг акаунт." } } diff --git a/apps/browser/src/_locales/bn/messages.json b/apps/browser/src/_locales/bn/messages.json index c14d5308a6b..fe386c53e62 100644 --- a/apps/browser/src/_locales/bn/messages.json +++ b/apps/browser/src/_locales/bn/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Autofill suggestions" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Show autofill suggestions on form fields" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Use this password" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Use this username" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Timeout action" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "লক", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "All Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Hide text by default" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ is using SSO with a self-hosted key server. A master password is no longer required to log in for members of this organization.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Leave organization" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Device trusted" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "No active Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Use Send to securely share encrypted information with anyone.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Input is required." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Are you sure you want to permanently delete this attachment?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Authenticating" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Important notice" - }, - "setupTwoStepLogin": { - "message": "Set up two-step login" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Remind me later" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" - }, - "turnOnTwoStepLogin": { - "message": "Turn on two-step login" - }, - "changeAcctEmail": { - "message": "Change account email" - }, "extensionWidth": { "message": "Extension width" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/bs/messages.json b/apps/browser/src/_locales/bs/messages.json index eaa9ba863e0..b7982ba4981 100644 --- a/apps/browser/src/_locales/bs/messages.json +++ b/apps/browser/src/_locales/bs/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Autofill suggestions" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Show autofill suggestions on form fields" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Use this password" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Use this username" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Timeout action" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "Zaključaj", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "All Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Hide text by default" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ is using SSO with a self-hosted key server. A master password is no longer required to log in for members of this organization.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Leave organization" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Device trusted" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "No active Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Use Send to securely share encrypted information with anyone.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Input is required." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Are you sure you want to permanently delete this attachment?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Authenticating" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Important notice" - }, - "setupTwoStepLogin": { - "message": "Set up two-step login" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Remind me later" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" - }, - "turnOnTwoStepLogin": { - "message": "Turn on two-step login" - }, - "changeAcctEmail": { - "message": "Change account email" - }, "extensionWidth": { "message": "Extension width" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/ca/messages.json b/apps/browser/src/_locales/ca/messages.json index bbf6ccb9c41..005c100f105 100644 --- a/apps/browser/src/_locales/ca/messages.json +++ b/apps/browser/src/_locales/ca/messages.json @@ -189,7 +189,7 @@ "message": "Copia notes" }, "copy": { - "message": "Copy", + "message": "Copia", "description": "Copy to clipboard" }, "fill": { @@ -1043,10 +1043,10 @@ "message": "Llista els elements d'identitat de la pestanya de la pàgina per facilitar l'autoemplenat." }, "clickToAutofillOnVault": { - "message": "Feu clic als elements per emplenar automàticament a la vista de la caixa forta" + "message": "Feu clic als elements per emplenar automàticament en la vista de la caixa forta" }, "clickToAutofill": { - "message": "Click items in autofill suggestion to fill" + "message": "Feu clic als elements del suggeriment d'emplenament automàtic per omplir-los" }, "clearClipboard": { "message": "Buida el porta-retalls", @@ -1057,7 +1057,7 @@ "description": "Clipboard is the operating system thing where you copy/paste data to on your device." }, "notificationAddDesc": { - "message": "Bitwarden ha de recordar aquesta contrasenya per a vosaltres?" + "message": "Ha de recordar Bitwarden aquesta contrasenya per a vosaltres?" }, "notificationAddSave": { "message": "Guarda" @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,14 +1599,32 @@ "autofillSuggestionsSectionTitle": { "message": "Suggeriments d'emplenament automàtic" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Mostra suggeriments d'emplenament automàtic als camps del formulari" }, "showInlineMenuIdentitiesLabel": { - "message": "Display identities as suggestions" + "message": "Mostra identitats com a suggeriments" }, "showInlineMenuCardsLabel": { - "message": "Display cards as suggestions" + "message": "Mostra targetes com a suggeriments" }, "showInlineMenuOnIconSelectionLabel": { "message": "Mostra suggeriments quan la icona està seleccionada" @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Utilitzeu aquesta contrasenya" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Utilitzeu aquest nom d'usuari" }, @@ -2191,7 +2222,7 @@ "description": "This will be used as part of a larger sentence, broken up to include the generator icon. The full sentence will read 'Use the generator [GENERATOR_ICON] to create a strong unique password'" }, "vaultCustomization": { - "message": "Vault customization" + "message": "Personalització de la caixa forta" }, "vaultTimeoutAction": { "message": "Acció quan acabe el temps d'espera de la caixa forta" @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Acció després del temps d'espera" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "Bloqueja", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "Tots els Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Amaga el text per defecte" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "No s'ha trobat cap identificador únic." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ està utilitzant SSO amb un servidor autoallotjat de claus. Ja no es requereix una contrasenya mestra d'inici de sessió per als membres d'aquesta organització.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Abandona l'organització" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Dispositiu de confiança" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "No hi ha Sends actius", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Utilitzeu Send per compartir informació xifrada de manera segura amb qualsevol persona.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "L'entrada és obligatòria." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Esteu segur que voleu suprimir definitivament aquest adjunt?" }, @@ -4902,10 +4987,10 @@ "message": "Amaga el recompte de caràcters" }, "itemsInTrash": { - "message": "Items in trash" + "message": "Elements a la paperera" }, "noItemsInTrash": { - "message": "No items in trash" + "message": "No hi ha cap element a la paperera" }, "noItemsInTrashDesc": { "message": "Items you delete will appear here and be permanently deleted after 30 days" @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "S'està autenticant" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Noticia important" - }, - "setupTwoStepLogin": { - "message": "Set up two-step login" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Recorda-m'ho més tard" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, jo no" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" - }, - "turnOnTwoStepLogin": { - "message": "Activa l'inici de sessió en dos passos" - }, - "changeAcctEmail": { - "message": "Change account email" - }, "extensionWidth": { "message": "Amplada d'extensió" }, @@ -5202,7 +5260,7 @@ "message": "Change at-risk password" }, "settingsVaultOptions": { - "message": "Vault options" + "message": "Opcions de la caixa forta" }, "emptyVaultDescription": { "message": "The vault protects more than just your passwords. Store secure logins, IDs, cards and notes securely here." @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/cs/messages.json b/apps/browser/src/_locales/cs/messages.json index dfbc0acea76..6fc2d1ddb34 100644 --- a/apps/browser/src/_locales/cs/messages.json +++ b/apps/browser/src/_locales/cs/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "Nová položka, otevře se v novém okně", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Upravit před uložením", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ - uloženo do Bitwardenu.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "uloženo do Bitwardenu.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ - aktualizováno v Bitwardenu.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "aktualizováno v Bitwardenu.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Vybrat $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Uložit jako nové přihlašovací údaje", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Aktualizovat přihlašovací údaje", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Odemknout pro uložení tohoto přihlášení", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Uložit přihlašovací údaje", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Návrhy automatického vyplňování" }, + "autofillSpotlightTitle": { + "message": "Snadné hledání návrhů automatického vyplňování" + }, + "autofillSpotlightDesc": { + "message": "Vypněte nastavení automatického vyplňování prohlížeče, takže nebude v rozporu s Bitwardenem." + }, + "turnOffBrowserAutofill": { + "message": "Vypnout automatické vyplňování $BROWSER$", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Vypnout automatické vyplňování" + }, "showInlineMenuLabel": { "message": "Zobrazit návrhy automatického vyplňování v polích formuláře" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Použít toto heslo" }, + "useThisPassphrase": { + "message": "Použít tuto heslovou frázi" + }, "useThisUsername": { "message": "Použít toto uživatelské jméno" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Akce vypršení časového limitu" }, - "newCustomizationOptionsCalloutTitle": { - "message": "Nové volby přizpůsobení" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Přizpůsobte si svůj trezor s rychlými kopírovacími akcemi, kompaktním režimem a dalším!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "Zobrazit všechna nastavení vzhledu" - }, "lock": { "message": "Zamknout", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "Všechny Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Dosažen maximální počet přístupů", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Ve výchozím nastavení skrýt text" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Nenalezen žádný jedinečný identifikátor." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ používá SSO s vlastním serverem s klíči. Hlavní heslo pro členy této organizace již není vyžadováno.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "Hlavní heslo již není vyžadováno pro členy následující organizace. Potvrďte níže uvedenou doménu u správce Vaší organizace." + }, + "organizationName": { + "message": "Název organizace" + }, + "keyConnectorDomain": { + "message": "Doména Key Connectoru" }, "leaveOrganization": { "message": "Opustit organizaci" @@ -3444,7 +3470,7 @@ "message": "Nastavení automatického vyplňování" }, "autofillKeyboardShortcutSectionTitle": { - "message": "Zkrátka automatického vyplňování" + "message": "Zkratka automatického vyplňování" }, "autofillKeyboardShortcutUpdateLabel": { "message": "Změnit zkratku" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Zařízení zařazeno mezi důvěryhodné" }, + "trustOrganization": { + "message": "Důvěřovat organizaci" + }, + "trust": { + "message": "Důvěřovat" + }, + "doNotTrust": { + "message": "Nedůvěřovat" + }, + "organizationNotTrusted": { + "message": "Organizace není důvěryhodná" + }, + "emergencyAccessTrustWarning": { + "message": "Pro zabezpečení Vašeho účtu potvrďte jen v případě, že jste tomuto uživateli udělili nouzový přístup a jeho otisk prstu odpovídá tomu, co je zobrazeno v jeho účtu." + }, + "orgTrustWarning": { + "message": "Pro zabezpečení Vašeho účtu pokračujte jen v případě, že jste členem této organizace, máte povoleno obnovení účtu a zobrazený otisk prstu níže odpovídá otisku prstu organizace." + }, + "orgTrustWarning1": { + "message": "Tato organizace má firemní zásady, které Vás zapíšou do obnovy účtu. Zápis umožní správcům organizace změnit Vaše heslo. Pokračujte jen v případě, že znáte tuto organizaci a fráze otisku prstu zobrazenou níže odpovídá otisku prstu organizace." + }, + "trustUser": { + "message": "Důvěřovat uživateli" + }, "sendsNoItemsTitle": { "message": "Žádná aktivní Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Použijte Send pro bezpečné sdílení šifrovaných informací s kýmkoliv.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Posílejte citlivé informace bezpečně", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Sdílejte bezpečně soubory a data s kýmkoli na libovolné platformě. Vaše informace zůstanou šifrovány a zároveň omezují expozici.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Je vyžadován vstup." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Stáhnout Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Stáhnout Bitwarden na všech zařízeních" + }, + "getTheMobileApp": { + "message": "Získejte mobilní aplikaci" + }, + "getTheMobileAppDesc": { + "message": "Přistupujte k Vašim heslům pomocí mobilní aplikace Bitwarden." + }, + "getTheDesktopApp": { + "message": "Získejte desktopovou aplikaci" + }, + "getTheDesktopAppDesc": { + "message": "Přistupujte k Vašemu trezoru bez prohlížeče a poté nastavte odemknutí s biometrikou jak v desktopové aplikaci, tak v rozšíření prohlížeče." + }, + "downloadFromBitwardenNow": { + "message": "Stáhnout z bitwarden.com nyní" + }, + "getItOnGooglePlay": { + "message": "Získejte ji na Google Play" + }, + "downloadOnTheAppStore": { + "message": "Stáhnout v App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Opravdu chcete tuto přílohu navždy smazat?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometrické odemknutí je momentálně z neznámého důvodu nedostupné." }, + "unlockVault": { + "message": "Rychlé odemknutí trezoru" + }, + "unlockVaultDesc": { + "message": "Pro rychlejší přístup k trezoru můžete upravit nastavení odemknutí a vypršení časového limitu." + }, + "unlockPinSet": { + "message": "PIN pro odemknutí byl nastaven" + }, "authenticating": { "message": "Ověřování" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Důležité upozornění" - }, - "setupTwoStepLogin": { - "message": "Nastavit dvoufázové přihlášení" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden odešle kód na e-mail Vašeho účtu pro ověření přihlášení z nových zařízení počínaje únorem 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "Dvoufázové přihlášení můžete nastavit jako alternativní způsob ochrany Vašeho účtu nebo změnit svůj e-mail na ten, k němuž můžete přistupovat." - }, - "remindMeLater": { - "message": "Připomenout později" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Máte spolehlivý přístup ke svému e-mailu $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "Ne, nemám" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Ano, ke svému e-mailu mám přístup" - }, - "turnOnTwoStepLogin": { - "message": "Zapnout dvoufázové přihlášení" - }, - "changeAcctEmail": { - "message": "Změnit e-mail účtu" - }, "extensionWidth": { "message": "Šířka rozšíření" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Uložte neomezená hesla na neomezených zařízeních s Bitwardenem na mobilu, prohlížeči a desktopové aplikaci." }, + "nudgeBadgeAria": { + "message": "1 oznámení" + }, "emptyVaultNudgeTitle": { "message": "Importovat existující hesla" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Vítejte ve Vašem trezoru!" }, - "hasItemsVaultNudgeBody": { - "message": "Položky automatického vyplňování pro aktuální stránku\nOblíbené položky pro snadný přístup\nNajděte v trezoru něco jiného" + "hasItemsVaultNudgeBodyOne": { + "message": "Položky automatického vyplňování aktuální stránky" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Oblíbené položky pro snadný přístup" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Najít v trezoru něco jiného" }, "newLoginNudgeTitle": { "message": "Ušetřete čas s automatickým vyplňováním" }, - "newLoginNudgeBody": { - "message": "Zahrne webovou stránku, takže se toto přihlášení objeví jako návrh automatického vyplňování." + "newLoginNudgeBodyOne": { + "message": "Zahrne", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "webovou stránku, ", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "takže se toto přihlášení objeví jako návrh automatického vyplňování.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Bezproblémová online pokladna" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Přístup SSH pro vývojáře" }, - "newSshNudgeBody": { - "message": "Uložte své klíče a připojte se k SSH agentovi pro rychlé a šifrované ověření." + "newSshNudgeBodyOne": { + "message": "Uložte své klíče a připojte se k SSH agentovi pro rychlé a šifrované ověření.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Další informace o SSH agentovi", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Rychlé vytvoření hesla" + }, + "generatorNudgeBodyOne": { + "message": "Jednoduše vytvořte silná a unikátní hesla klepnutím na", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "aby Vám pomohlo udržet Vaše přihlašovací údaje v bezpečí.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Jednoduše vytvořte silná a unikátní hesla klepnutím na tlačítko Generovat heslo, které Vám pomůže udržet Vaše přihlašovací údaje v bezpečí.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "Nemáte oprávnění k zobrazení této stránky. Zkuste se přihlásit jiným účtem." } } diff --git a/apps/browser/src/_locales/cy/messages.json b/apps/browser/src/_locales/cy/messages.json index 5fa135a929d..eec15c8ed9a 100644 --- a/apps/browser/src/_locales/cy/messages.json +++ b/apps/browser/src/_locales/cy/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Cadw fel manylion mewngofnodi newydd", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Autofill suggestions" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Show autofill suggestions on form fields" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Defnyddio'r cyfrinair hwn" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Defnyddio'r enw defnyddiwr hwn" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Timeout action" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "Cloi", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "Pob Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Hide text by default" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ is using SSO with a self-hosted key server. A master password is no longer required to log in for members of this organization.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Leave organization" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Device trusted" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "No active Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Use Send to securely share encrypted information with anyone.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Input is required." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Are you sure you want to permanently delete this attachment?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Authenticating" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Important notice" - }, - "setupTwoStepLogin": { - "message": "Set up two-step login" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Remind me later" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "A oes gennych chi fynediad dibynadwy i'ch ebost, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "Nac oes" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Oes, mae gen i fynediad dibynadwy i fy ebost" - }, - "turnOnTwoStepLogin": { - "message": "Turn on two-step login" - }, - "changeAcctEmail": { - "message": "Change account email" - }, "extensionWidth": { "message": "Extension width" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/da/messages.json b/apps/browser/src/_locales/da/messages.json index f1c55f3557d..066ef9c9d9a 100644 --- a/apps/browser/src/_locales/da/messages.json +++ b/apps/browser/src/_locales/da/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Autoudfyldningsforslag" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Vis autoudfyld-menu i formularfelter" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Anvend denne adgangskode" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Anvend dette brugernavn" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Timeouthandling" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "Lås", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "Alle Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Skjul tekst som standard" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Ingen entydig identifikator fundet." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ bruger SSO med en selv-hostet nøgleserver. En hovedadgangskode er ikke længere påkrævet for at logge ind for medlemmer af denne organisation.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Forlad organisation" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Enhed betroet" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "Ingen aktive Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Brug Send til at dele krypterede oplysninger sikkert med nogen.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Input obligatorisk." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Sikker på, at denne vedhæftning skal slettes permanent?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometrisk oplåsning er p.t. utilgængelig grundet en ukendt årsag." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Godkender" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Vigtig notits" - }, - "setupTwoStepLogin": { - "message": "Opsæt totrins-login" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Startende i februar 2025, sender Bitwarden en kode til kontoe-mailadressen for at bekræfte logins fra nye enheder." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "Man kan opsætte totrins-login som en alternativ måde at beskytte sin konto på eller ændre sin e-mail til en, man kan tilgå." - }, - "remindMeLater": { - "message": "Påmind senere" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Er der pålidelig adgang til e-mailadressen, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "Nej, jeg gør ikke" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Ja, e-mailadressen kan pålideligt tilgås" - }, - "turnOnTwoStepLogin": { - "message": "Slå totrins-login til" - }, - "changeAcctEmail": { - "message": "Skift kontoe-mailadresse" - }, "extensionWidth": { "message": "Udvidelsesbredde" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/de/messages.json b/apps/browser/src/_locales/de/messages.json index 251a0323c60..f9818afe58f 100644 --- a/apps/browser/src/_locales/de/messages.json +++ b/apps/browser/src/_locales/de/messages.json @@ -620,7 +620,7 @@ } }, "website": { - "message": "Webseite" + "message": "Website" }, "toggleVisibility": { "message": "Sichtbarkeit umschalten" @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "Neuer Eintrag, öffnet sich in neuem Fenster", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Vor dem Speichern bearbeiten", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ in Bitwarden gespeichert.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "in Bitwarden gespeichert.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ in Bitwarden aktualisiert.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "in Bitwarden aktualisiert.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "$ITEMTYPE$, $ITEMNAME$ auswählen", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Als neue Zugangsdaten speichern", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Zugangsdaten aktualisieren", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Entsperren, um diese Zugangsdaten zu speichern", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Zugangsdaten speichern", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Vorschläge zum Auto-Ausfüllen" }, + "autofillSpotlightTitle": { + "message": "Auto-Ausfüllen-Vorschläge einfach finden" + }, + "autofillSpotlightDesc": { + "message": "Deaktiviere die Auto-Ausfüllen-Einstellungen deines Browsers, damit sie nicht mit Bitwarden in Konflikt geraten." + }, + "turnOffBrowserAutofill": { + "message": "$BROWSER$ Auto-Ausfüllen deaktivieren", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Auto-Ausfüllen deaktivieren" + }, "showInlineMenuLabel": { "message": "Vorschläge zum Auto-Ausfüllen in Formularfeldern anzeigen" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Dieses Passwort verwenden" }, + "useThisPassphrase": { + "message": "Diese Passphrase verwenden" + }, "useThisUsername": { "message": "Diesen Benutzernamen verwenden" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Timeout-Aktion" }, - "newCustomizationOptionsCalloutTitle": { - "message": "Neue Personalisierungs-Optionen" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Personalisiere deinen Tresor mit Schnellkopier-Aktionen, Kompaktmodus und mehr!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "Alle Aussehen-Einstellungen anzeigen" - }, "lock": { "message": "Sperren", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "Alle Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Text standardmäßig ausblenden" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Keine eindeutige Kennung gefunden." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ verwendet SSO mit einem selbst gehosteten Schlüsselserver. Ein Master-Passwort ist nicht mehr erforderlich, damit sich Mitglieder dieser Organisation anmelden können.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "Für Mitglieder der folgenden Organisation ist kein Master-Passwort mehr erforderlich. Bitte bestätige die folgende Domain bei deinem Organisations-Administrator." + }, + "organizationName": { + "message": "Name der Organisation" + }, + "keyConnectorDomain": { + "message": "Key Connector-Domain" }, "leaveOrganization": { "message": "Organisation verlassen" @@ -3173,7 +3199,7 @@ "description": "Displayed with the address on the forwarding service's configuration screen." }, "forwarderGeneratedByWithWebsite": { - "message": "Webseite: $WEBSITE$. Von Bitwarden generiert.", + "message": "Website: $WEBSITE$. Von Bitwarden generiert.", "description": "Displayed with the address on the forwarding service's configuration screen.", "placeholders": { "WEBSITE": { @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Gerät wird vertraut" }, + "trustOrganization": { + "message": "Organisation vertrauen" + }, + "trust": { + "message": "Vertrauen" + }, + "doNotTrust": { + "message": "Nicht vertrauen" + }, + "organizationNotTrusted": { + "message": "Organisation ist nicht vertrauenswürdig" + }, + "emergencyAccessTrustWarning": { + "message": "Bestätige zur Sicherheit deines Kontos nur, wenn du den Notfallzugriff diesem Benutzer gewährt hast und sein Fingerabdruck mit dem übereinstimmt, was in seinem Konto angezeigt wird" + }, + "orgTrustWarning": { + "message": "Fahre zur Sicherheit deines Kontos nur fort, wenn du ein Mitglied dieser Organisation bist, die Kontowiederherstellung aktiviert hast und der unten angezeigte Fingerabdruck mit dem Fingerabdruck der Organisation übereinstimmt." + }, + "orgTrustWarning1": { + "message": "Diese Organisation hat eine Unternehmensrichtlinie, die dich für die Kontowiederherstellung registriert. Die Registrierung wird es den Administratoren der Organisation erlauben, dein Passwort zu ändern. Fahre nur fort, wenn du diese Organisation kennst und die unten angezeigte Fingerabdruck-Phrase mit der der Organisation übereinstimmt." + }, + "trustUser": { + "message": "Benutzer vertrauen" + }, "sendsNoItemsTitle": { "message": "Keine aktiven Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Verwende Send, um verschlüsselte Informationen sicher mit anderen zu teilen.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Sensible Informationen sicher versenden", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Teile Dateien und Daten sicher mit jedem auf jeder Plattform. Deine Informationen bleiben Ende-zu-Ende-verschlüsselt, während die Verbreitung begrenzt wird.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Eingabe ist erforderlich." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Bitwarden herunterladen" + }, + "downloadBitwardenOnAllDevices": { + "message": "Bitwarden auf allen Geräten herunterladen" + }, + "getTheMobileApp": { + "message": "Smartphone-App herunterladen" + }, + "getTheMobileAppDesc": { + "message": "Greife von unterwegs mit der Bitwarden Smartphone-App auf deine Passwörter zu." + }, + "getTheDesktopApp": { + "message": "Desktop-App herunterladen" + }, + "getTheDesktopAppDesc": { + "message": "Greife ohne Browser auf deinen Tresor zu und richte dann das Entsperren mit Biometrie ein, um die Entsperrung sowohl in der Desktop-App als auch in der Browser-Erweiterung zu beschleunigen." + }, + "downloadFromBitwardenNow": { + "message": "Jetzt von bitwarden.com herunterladen" + }, + "getItOnGooglePlay": { + "message": "Verfügbar bei Google Play" + }, + "downloadOnTheAppStore": { + "message": "Im App Store herunterladen" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Bist du sicher, dass du diesen Anhang dauerhaft löschen möchtest?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometrisches Entsperren ist derzeit aus einem unbekannten Grund nicht verfügbar." }, + "unlockVault": { + "message": "Entsperre deinen Tresor in Sekunden" + }, + "unlockVaultDesc": { + "message": "Du kannst deine Entsperr- und Timeout-Einstellungen anpassen, um schneller auf deinen Tresor zuzugreifen." + }, + "unlockPinSet": { + "message": "Entsperr-PIN festgelegt" + }, "authenticating": { "message": "Authentifizierung" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Wichtiger Hinweis" - }, - "setupTwoStepLogin": { - "message": "Zwei-Faktor-Authentifizierung einrichten" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Ab Februar 2025 wird Bitwarden einen Code an deine Konto-E-Mail-Adresse senden, um Anmeldungen von neuen Geräten zu verifizieren." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "Du kannst die Zwei-Faktor-Authentifizierung als eine alternative Methode einrichten, um dein Konto zu schützen, oder deine E-Mail-Adresse zu einer anderen ändern, auf die du zugreifen kannst." - }, - "remindMeLater": { - "message": "Erinnere mich später" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Hast du zuverlässigen Zugriff auf deine E-Mail-Adresse $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "Nein, habe ich nicht" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Ja, ich kann zuverlässig auf meine E-Mails zugreifen" - }, - "turnOnTwoStepLogin": { - "message": "Zwei-Faktor-Authentifizierung aktivieren" - }, - "changeAcctEmail": { - "message": "E-Mail-Adresse des Kontos ändern" - }, "extensionWidth": { "message": "Breite der Erweiterung" }, @@ -5202,10 +5260,10 @@ "message": "Gefährdetes Passwort ändern" }, "settingsVaultOptions": { - "message": "Vault options" + "message": "Tresoroptionen" }, "emptyVaultDescription": { - "message": "The vault protects more than just your passwords. Store secure logins, IDs, cards and notes securely here." + "message": "Der Tresor schützt mehr als nur deine Passwörter. Speicher hier sicher Zugangsdaten, Identitäten, Karten und Notizen." }, "introCarouselLabel": { "message": "Willkommen bei Bitwarden" @@ -5234,49 +5292,97 @@ "secureDevicesBody": { "message": "Speicher eine unbegrenzte Anzahl von Passwörtern auf unbegrenzt vielen Geräten mit Bitwarden-Apps für Smartphones, Browser und Desktop." }, + "nudgeBadgeAria": { + "message": "1 Benachrichtigung" + }, "emptyVaultNudgeTitle": { - "message": "Import existing passwords" + "message": "Vorhandene Passwörter importieren" }, "emptyVaultNudgeBody": { - "message": "Use the importer to quickly transfer logins to Bitwarden without manually adding them." + "message": "Verwende den Importer, um Zugangsdaten schnell zu Bitwarden zu übertragen, ohne sie manuell hinzuzufügen." }, "emptyVaultNudgeButton": { - "message": "Import now" + "message": "Jetzt importieren" }, "hasItemsVaultNudgeTitle": { - "message": "Welcome to your vault!" + "message": "Willkommen in deinem Tresor!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Einträge für die aktuelle Seite automatisch ausfüllen" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favoriten-Einträge für einfachen Zugriff" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Deinen Tresor nach etwas anderem durchsuchen" }, "newLoginNudgeTitle": { - "message": "Save time with autofill" + "message": "Spare Zeit mit Auto-Ausfüllen" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Füge eine", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "hinzu, damit diese Zugangsdaten als Auto-Ausfüllen-Vorschlag erscheinen.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { - "message": "Seamless online checkout" + "message": "Nahtlose Online-Kaufabwicklung" }, "newCardNudgeBody": { - "message": "With cards, easily autofill payment forms securely and accurately." + "message": "Mit Karten kannst du Zahlungsformulare sicher und präzise einfach automatisch ausfüllen." }, "newIdentityNudgeTitle": { - "message": "Simplify creating accounts" + "message": "Erstellung von Konten vereinfachen" }, "newIdentityNudgeBody": { - "message": "With identities, quickly autofill long registration or contact forms." + "message": "Mit Identitäten kannst du lange Registrierungs- oder Kontaktformulare schnell automatisch ausfüllen." }, "newNoteNudgeTitle": { - "message": "Keep your sensitive data safe" + "message": "Bewahre deine sensiblen Daten sicher auf" }, "newNoteNudgeBody": { - "message": "With notes, securely store sensitive data like banking or insurance details." + "message": "Mit Notizen speicherst du sensible Daten wie Bank- oder Versicherungs-Informationen." }, "newSshNudgeTitle": { - "message": "Developer-friendly SSH access" + "message": "Entwickler-freundlicher SSH-Zugriff" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Speicher deine Schlüssel und verbinden dich mit dem SSH-Agenten für eine schnelle und verschlüsselte Authentifizierung.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Erfahre mehr über den SSH-Agenten", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Passwörter schnell erstellen" + }, + "generatorNudgeBodyOne": { + "message": "Generiere ganz einfach starke und einzigartige Passwörter, indem du auf den", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": ", um dir zu helfen, deine Zugangsdaten sicher zu halten.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Generiere ganz einfach starke und einzigartige Passwörter, indem du auf den \"Passwort generieren\"-Button klickst, um dir zu helfen, deine Zugangsdaten sicher zu halten.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "Du hast keine Berechtigung, diese Seite anzuzeigen. Versuche dich mit einem anderen Konto anzumelden." } } diff --git a/apps/browser/src/_locales/el/messages.json b/apps/browser/src/_locales/el/messages.json index 691f546b327..9d55ed3f0c7 100644 --- a/apps/browser/src/_locales/el/messages.json +++ b/apps/browser/src/_locales/el/messages.json @@ -3,7 +3,7 @@ "message": "Bitwarden" }, "appLogoLabel": { - "message": "Bitwarden logo" + "message": "Λογότυπο του Bitwarden" }, "extName": { "message": "Διαχειριστής Κωδικών Πρόσβασης Bitwarden", @@ -189,7 +189,7 @@ "message": "Αντιγραφή σημειώσεων" }, "copy": { - "message": "Copy", + "message": "Αντιγραφή", "description": "Copy to clipboard" }, "fill": { @@ -383,7 +383,7 @@ "message": "Επεξεργασία φακέλου" }, "editFolderWithName": { - "message": "Edit folder: $FOLDERNAME$", + "message": "Επεξεργασία φακέλου: $FOLDERNAME$", "placeholders": { "foldername": { "content": "$1", @@ -911,7 +911,7 @@ "message": "Όχι" }, "location": { - "message": "Location" + "message": "Τοποθεσία" }, "unexpectedError": { "message": "Παρουσιάστηκε ένα μη αναμενόμενο σφάλμα." @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1477,7 +1487,7 @@ "message": "Εισάγετε το κλειδί ασφαλείας στη θύρα USB του υπολογιστή σας. Αν έχει κουμπί, πατήστε το." }, "openInNewTab": { - "message": "Open in new tab" + "message": "Άνοιγμα σε νέα καρτέλα" }, "webAuthnAuthenticate": { "message": "Ταυτοποίηση WebAuthn" @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Πρόταση αυτόματης συμπλήρωσης" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Απενεργοποίηση αυτόματης συμπλήρωσης" + }, "showInlineMenuLabel": { "message": "Εμφάνιση μενού αυτόματης συμπλήρωσης στα πεδία της φόρμας" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Χρήση αυτού του κωδικού πρόσβασης" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Χρήση αυτού του ονόματος χρήστη" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Ενέργεια κατά τη λήξη χρονικού ορίου" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "Κλείδωμα", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "Όλα τα Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Απόκρυψη κειμένου από προεπιλογή" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Δε βρέθηκε μοναδικό αναγνωριστικό." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ χρησιμοποιεί SSO με έναν αυτοεξυπηρετητή κλειδιών. Ένας κύριος κωδικός πρόσβασης δεν απαιτείται πλέον για να συνδεθείτε για τα μέλη αυτού του οργανισμού.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Αποχώρηση από τον οργανισμό" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Αξιόπιστη συσκευή" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "Κανένα ενεργό Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Χρήση Send για ασφαλή κοινοποίηση κρυπτογραφημένων πληροφοριών με οποιονδήποτε.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Απαιτείται εισαγωγή." }, @@ -4113,7 +4171,7 @@ "message": "Ενεργός λογαριασμός" }, "bitwardenAccount": { - "message": "Bitwarden account" + "message": "Λογαριασμός Bitwarden" }, "availableAccounts": { "message": "Διαθέσιμοι λογαριασμοί" @@ -4304,7 +4362,7 @@ } }, "viewItemTitleWithField": { - "message": "View item - $ITEMNAME$ - $FIELD$", + "message": "Προβολή στοιχείου - $ITEMNAME$ - $FIELD$", "description": "Title for a link that opens a view for an item.", "placeholders": { "itemname": { @@ -4328,7 +4386,7 @@ } }, "autofillTitleWithField": { - "message": "Autofill - $ITEMNAME$ - $FIELD$", + "message": "Αυτόματη συμπλήρωση - $ITEMNAME$ - $FIELD$", "description": "Title for a button that autofills a login item.", "placeholders": { "itemname": { @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Λήψη του Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Είστε σίγουροι ότι θέλετε να διαγράψετε οριστικά αυτό το συνημμένο;" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Ταυτοποίηση" }, @@ -4961,7 +5055,7 @@ "description": "Notification message for when a password has been regenerated" }, "saveToBitwarden": { - "message": "Save to Bitwarden", + "message": "Αποθήκευση στο Bitwarden", "description": "Confirmation message for saving a login to Bitwarden" }, "spaceCharacterDescriptor": { @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta (Δοκιμαστική)" }, - "importantNotice": { - "message": "Σημαντική ειδοποίηση" - }, - "setupTwoStepLogin": { - "message": "Ρύθμιση σύνδεσης δύο βημάτων" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Το Bitwarden θα στείλει έναν κωδικό στο ηλ. ταχυδρομείο του λογαριασμού σας για να επαληθεύσει τις συνδέσεις από τις νέες συσκευές που ξεκινούν τον Φεβρουάριο του 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "Μπορείτε να ορίσετε σύνδεση δύο βημάτων ως εναλλακτικό τρόπο προστασίας του λογαριασμού σας ή να αλλάξετε το ηλ. ταχυδρομείο σας σε ένα που μπορείτε να έχετε πρόσβαση." - }, - "remindMeLater": { - "message": "Υπενθύμιση αργότερα" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Έχετε αξιόπιστη πρόσβαση στο ηλ. ταχυδρομείο σας, $EMAIL$;", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "Όχι, δεν έχω" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Ναι, μπορώ να συνδεθώ αξιόπιστα στο ηλ. ταχυδρομείο μου" - }, - "turnOnTwoStepLogin": { - "message": "Ενεργοποίηση σύνδεσης δύο βημάτων" - }, - "changeAcctEmail": { - "message": "Αλλαγή ηλ. ταχυδρομείου λογαριασμού" - }, "extensionWidth": { "message": "Πλάτος εφαρμογής" }, @@ -5160,10 +5218,10 @@ "message": "The password you entered is incorrect." }, "importSshKey": { - "message": "Import" + "message": "Εισαγωγή" }, "confirmSshKeyPassword": { - "message": "Confirm password" + "message": "Επιβεβαίωση κωδικού πρόσβασης" }, "enterSshKeyPasswordDesc": { "message": "Enter the password for the SSH key." @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5241,19 +5302,37 @@ "message": "Use the importer to quickly transfer logins to Bitwarden without manually adding them." }, "emptyVaultNudgeButton": { - "message": "Import now" + "message": "Εισαγωγή τώρα" }, "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Ιστότοπος", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index 6e1e2ef57ac..68f303dd538 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1355,8 +1365,8 @@ "featureUnavailable": { "message": "Feature unavailable" }, - "encryptionKeyMigrationRequired": { - "message": "Encryption key migration required. Please login through the web vault to update your encryption key." + "legacyEncryptionUnsupported": { + "message": "Legacy encryption is no longer supported. Please contact support to recover your account." }, "premiumMembership": { "message": "Premium membership" @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Autofill suggestions" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Show autofill suggestions on form fields" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Use this password" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Use this username" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Timeout action" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "Lock", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "All Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Hide text by default" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ is using SSO with a self-hosted key server. A master password is no longer required to log in for members of this organization.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Leave organization" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Device trusted" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "No active Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Use Send to securely share encrypted information with anyone.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Input is required." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Are you sure you want to permanently delete this attachment?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Authenticating" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Important notice" - }, - "setupTwoStepLogin": { - "message": "Set up two-step login" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Remind me later" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" - }, - "turnOnTwoStepLogin": { - "message": "Turn on two-step login" - }, - "changeAcctEmail": { - "message": "Change account email" - }, "extensionWidth": { "message": "Extension width" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/en_GB/messages.json b/apps/browser/src/_locales/en_GB/messages.json index 1e0def93584..bc9452a7cad 100644 --- a/apps/browser/src/_locales/en_GB/messages.json +++ b/apps/browser/src/_locales/en_GB/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Autofill suggestions" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Show autofill suggestions on form fields" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Use this password" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Use this username" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Timeout action" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customisation options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customise your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "Lock", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "All Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Hide text by default" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ is using SSO with a self-hosted key server. A master password is no longer required to log in for members of this organisation.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organisation. Please confirm the domain below with your organisation administrator." + }, + "organizationName": { + "message": "Organisation name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Leave organisation" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Device trusted" }, + "trustOrganization": { + "message": "Trust organisation" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organisation is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organisation, have account recovery enabled, and the fingerprint displayed below matches the organisation's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organisation has an Enterprise policy that will enrol you in account recovery. Enrolment will allow organisation administrators to change your password. Only proceed if you recognise this organisation and the fingerprint phrase displayed below matches the organisation's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "No active Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Use Send to securely share encrypted information with anyone.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Input is required." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Are you sure you want to permanently delete this attachment?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customise your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Authenticating" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Important notice" - }, - "setupTwoStepLogin": { - "message": "Set up two-step login" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Remind me later" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" - }, - "turnOnTwoStepLogin": { - "message": "Turn on two-step login" - }, - "changeAcctEmail": { - "message": "Change account email" - }, "extensionWidth": { "message": "Extension width" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavourite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favourite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/en_IN/messages.json b/apps/browser/src/_locales/en_IN/messages.json index 380eab31eda..ef329ac551c 100644 --- a/apps/browser/src/_locales/en_IN/messages.json +++ b/apps/browser/src/_locales/en_IN/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Autofill suggestions" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Show autofill suggestions on form fields" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Use this password" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Use this username" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Timeout action" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customisation options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customise your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "Lock", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "All Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Hide text by default" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ is using SSO with a self-hosted key server. A master password is no longer required to log in for members of this organization.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organisation. Please confirm the domain below with your organisation administrator." + }, + "organizationName": { + "message": "Organisation name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Leave Organization" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Device trusted" }, + "trustOrganization": { + "message": "Trust organisation" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organisation is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organisation, have account recovery enabled, and the fingerprint displayed below matches the organisation's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organisation has an Enterprise policy that will enrol you in account recovery. Enrolment will allow organisation administrators to change your password. Only proceed if you recognise this organisation and the fingerprint phrase displayed below matches the organisation's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "No active Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Use Send to securely share encrypted information with anyone.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Input is required." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Are you sure you want to permanently delete this attachment?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customise your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Authenticating" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Important notice" - }, - "setupTwoStepLogin": { - "message": "Set up two-step login" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Remind me later" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" - }, - "turnOnTwoStepLogin": { - "message": "Turn on two-step login" - }, - "changeAcctEmail": { - "message": "Change account email" - }, "extensionWidth": { "message": "Extension width" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavourite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favourite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/es/messages.json b/apps/browser/src/_locales/es/messages.json index 76401c685ad..7b970f996a9 100644 --- a/apps/browser/src/_locales/es/messages.json +++ b/apps/browser/src/_locales/es/messages.json @@ -3,7 +3,7 @@ "message": "Bitwarden" }, "appLogoLabel": { - "message": "Bitwarden logo" + "message": "Logo de Bitwarden" }, "extName": { "message": "Bitwarden - Administrador de contraseñas", @@ -656,7 +656,7 @@ "message": "Tu navegador web no soporta copiar al portapapeles facilmente. Cópialo manualmente." }, "verifyYourIdentity": { - "message": "Verify your identity" + "message": "Verifica tu identidad" }, "weDontRecognizeThisDevice": { "message": "No reconocemos este dispositivo. Introduce el código enviado a tu correo electrónico para verificar tu identidad." @@ -872,19 +872,19 @@ "message": "Iniciar sesión en Bitwarden" }, "enterTheCodeSentToYourEmail": { - "message": "Enter the code sent to your email" + "message": "Introduce el código enviado a tu correo electrónico" }, "enterTheCodeFromYourAuthenticatorApp": { "message": "Introduce el código de tu aplicación de autenticación" }, "pressYourYubiKeyToAuthenticate": { - "message": "Press your YubiKey to authenticate" + "message": "Pulsa tu YubiKey para identificarte" }, "duoTwoFactorRequiredPageSubtitle": { - "message": "Duo two-step login is required for your account. Follow the steps below to finish logging in." + "message": "Se requiere inicio de sesión en dos pasos para tu cuenta. Sigue los pasos siguientes para terminar de iniciar sesión." }, "followTheStepsBelowToFinishLoggingIn": { - "message": "Follow the steps below to finish logging in." + "message": "Sigue los pasos de abajo para terminar de iniciar sesión." }, "followTheStepsBelowToFinishLoggingInWithSecurityKey": { "message": "Follow the steps below to finish logging in with your security key." @@ -911,7 +911,7 @@ "message": "No" }, "location": { - "message": "Location" + "message": "Ubicación" }, "unexpectedError": { "message": "Ha ocurrido un error inesperado." @@ -1063,7 +1063,7 @@ "message": "Guardar" }, "notificationViewAria": { - "message": "View $ITEMNAME$, opens in new window", + "message": "Ver $ITEMNAME$, se abre en una nueva ventana", "placeholders": { "itemName": { "content": "$1" @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "Nuevo Elemento, se abre en una nueva ventana", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Sugerencias de autocompletar" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Show autofill suggestions on form fields" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Usar esta contraseña" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Usar este nombre de usuario" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Acción de tiempo agotado" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "Bloquear", "description": "Verb form: to make secure or inaccessible by" @@ -2575,7 +2597,7 @@ "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { - "message": "Update in Bitwarden" + "message": "Actualizar en Bitwarden" }, "updateInBitwardenSlideDesc": { "message": "Bitwarden will then prompt you to update the password in the password manager.", @@ -2655,6 +2677,10 @@ "message": "Todos los Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Hide text by default" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Identificador único no encontrado." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ está usando SSO con un servidor de claves autoalojado. Los miembros de esta organización ya no necesitarán una contraseña maestra para iniciar sesión.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "Ya no es necesaria una contraseña maestra para los miembros de la siguiente organización. Confirma el dominio que aparece a continuación con el administrador de tu organización." + }, + "organizationName": { + "message": "Nombre de la organización" + }, + "keyConnectorDomain": { + "message": "Dominio del conector de clave" }, "leaveOrganization": { "message": "Abandonar organización" @@ -3387,7 +3413,7 @@ "message": "Inicio de sesión en proceso" }, "logInRequestSent": { - "message": "Request sent" + "message": "Solicitud enviada" }, "exposedMasterPassword": { "message": "Contraseña maestra comprometida" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Dispositivo de confianza" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "No active Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Use Send to securely share encrypted information with anyone.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Entrada requerida." }, @@ -3774,7 +3832,7 @@ "description": "Screen reader text (aria-label) for new login button within inline menu" }, "newCard": { - "message": "New card", + "message": "Nueva tarjeta", "description": "Button text to display within inline menu when there are no matching items on a credit card field" }, "addNewCardItemAria": { @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Consíguela en Google Play" + }, + "downloadOnTheAppStore": { + "message": "Descarga en la App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "¿Estás seguro de que deseas eliminar permanentemente este adjunto?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Autenticando" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Aviso importante" - }, - "setupTwoStepLogin": { - "message": "Set up two-step login" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Recuérdame más tarde" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "¿Tienes acceso fiable a tu correo electrónico, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, no lo tengo" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Sí, puedo acceder a mi correo electrónico de forma fiable" - }, - "turnOnTwoStepLogin": { - "message": "Activar inicio de sesión en dos pasos" - }, - "changeAcctEmail": { - "message": "Cambiar la cuenta de correo electrónico" - }, "extensionWidth": { "message": "Ancho de extensión" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Guarda contraseñas ilimitadas a través de dispositivos ilimitados con aplicaciones móviles, de navegador y de escritorio de Bitwarden." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/et/messages.json b/apps/browser/src/_locales/et/messages.json index f76adcc27e2..9ca7d15e72a 100644 --- a/apps/browser/src/_locales/et/messages.json +++ b/apps/browser/src/_locales/et/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Autofill suggestions" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Show autofill suggestions on form fields" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Kasuta seda parooli" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Kasuta seda kasutajanime" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Timeout action" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "Lukusta", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "Kõik Sendid", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Hide text by default" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Unikaalset identifikaatorit ei leitud." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ kasutab SSO-d koos enda majutatud võtmeserveriga. Selle organisatsiooni liikmed ei pea sisselogimisel enam ülemparooli kasutama.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Lahku organisatsioonist" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Seade on usaldusväärne" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "No active Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Use Send to securely share encrypted information with anyone.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Sisestus on nõutav." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Are you sure you want to permanently delete this attachment?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Authenticating" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Important notice" - }, - "setupTwoStepLogin": { - "message": "Set up two-step login" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Remind me later" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" - }, - "turnOnTwoStepLogin": { - "message": "Turn on two-step login" - }, - "changeAcctEmail": { - "message": "Change account email" - }, "extensionWidth": { "message": "Extension width" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/eu/messages.json b/apps/browser/src/_locales/eu/messages.json index cd3d58896d4..3c7192e465e 100644 --- a/apps/browser/src/_locales/eu/messages.json +++ b/apps/browser/src/_locales/eu/messages.json @@ -17,7 +17,7 @@ "message": "Saioa hasi edo sortu kontu berri bat zure kutxa gotorrera sartzeko." }, "inviteAccepted": { - "message": "Invitation accepted" + "message": "Gonbidapena onartua" }, "createAccount": { "message": "Sortu kontua" @@ -150,7 +150,7 @@ "message": "Kopiatu segurtasun-kodea" }, "copyName": { - "message": "Copy name" + "message": "Izena kopiatu" }, "copyCompany": { "message": "Copy company" @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Autofill suggestions" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Show autofill suggestions on form fields" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Use this password" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Use this username" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Timeout action" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "Blokeatu", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "Send guztiak", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Hide text by default" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Ez da identifikatzaile bakarrik aurkitu." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ SSO erabiltzen ari da ostatatze propioa duen gako-zerbitzari batekin. Dagoeneko ez da pasahitz nagusirik behar erakunde honetako kideentzat saioa hasteko.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Utzi erakundea" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Device trusted" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "No active Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Use Send to securely share encrypted information with anyone.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Input is required." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Are you sure you want to permanently delete this attachment?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Authenticating" }, @@ -5100,53 +5194,17 @@ "message": "Lowercase" }, "uppercaseAriaLabel": { - "message": "Uppercase" + "message": "Maiuskulak" }, "generatedPassword": { - "message": "Generated password" + "message": "Sortutako pasahitza" }, "compactMode": { - "message": "Compact mode" + "message": "Modu trinkoa" }, "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Important notice" - }, - "setupTwoStepLogin": { - "message": "Set up two-step login" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Remind me later" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" - }, - "turnOnTwoStepLogin": { - "message": "Turn on two-step login" - }, - "changeAcctEmail": { - "message": "Change account email" - }, "extensionWidth": { "message": "Extension width" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/fa/messages.json b/apps/browser/src/_locales/fa/messages.json index b8f8d2ccdbf..c40af49d97c 100644 --- a/apps/browser/src/_locales/fa/messages.json +++ b/apps/browser/src/_locales/fa/messages.json @@ -3,10 +3,10 @@ "message": "Bitwarden" }, "appLogoLabel": { - "message": "Bitwarden logo" + "message": "لوگو Bitwarden" }, "extName": { - "message": "مدیریت رمز عبور Bitwarden", + "message": "مدیریت کلمه عبور Bitwarden", "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { @@ -17,28 +17,28 @@ "message": "وارد شوید یا یک حساب کاربری بسازید تا به گاوصندوق امن‌تان دسترسی یابید." }, "inviteAccepted": { - "message": "Invitation accepted" + "message": "دعوتنامه پذیرفته شد" }, "createAccount": { "message": "ایجاد حساب کاربری" }, "newToBitwarden": { - "message": "New to Bitwarden?" + "message": "در Bitwarden تازه وارد هستید؟" }, "logInWithPasskey": { - "message": "Log in with passkey" + "message": "با کلید عبور وارد شوید" }, "useSingleSignOn": { - "message": "Use single sign-on" + "message": "استفاده از ورود تک مرحله‌ای" }, "welcomeBack": { - "message": "Welcome back" + "message": "خوش آمدید" }, "setAStrongPassword": { - "message": "تنظیم رمز عبور قوی" + "message": "تنظیم کلمه عبور قوی" }, "finishCreatingYourAccountBySettingAPassword": { - "message": "ایجاد حساب خود را با تنظیم رمز عبور تکمیل کنید" + "message": "ایجاد حساب کاربری خود را با تنظیم کلمه عبور تکمیل کنید" }, "enterpriseSingleSignOn": { "message": "ورود به سیستم پروژه" @@ -65,7 +65,7 @@ "message": "یادآور کلمه عبور اصلی کمک می‌کند در صورت فراموشی آن را به یاد بیارید." }, "masterPassHintText": { - "message": "If you forget your password, the password hint can be sent to your email. $CURRENT$/$MAXIMUM$ character maximum.", + "message": "اگر کلمه عبور خود را فراموش کنید، یادآور کلمه عبور می‌تواند به ایمیل شما ارسال شود. حداکثر $CURRENT$/$MAXIMUM$ کاراکتر.", "placeholders": { "current": { "content": "$1", @@ -84,7 +84,7 @@ "message": "یادآور کلمه عبور اصلی (اختیاری)" }, "passwordStrengthScore": { - "message": "Password strength score $SCORE$", + "message": "امتیاز قدرت کلمه عبور $SCORE$", "placeholders": { "score": { "content": "$1", @@ -93,10 +93,10 @@ } }, "joinOrganization": { - "message": "Join organization" + "message": "به سازمان بپیوندید" }, "joinOrganizationName": { - "message": "Join $ORGANIZATIONNAME$", + "message": "به $ORGANIZATIONNAME$ بپیوندید", "placeholders": { "organizationName": { "content": "$1", @@ -105,7 +105,7 @@ } }, "finishJoiningThisOrganizationBySettingAMasterPassword": { - "message": "Finish joining this organization by setting a master password." + "message": "با تعیین یک کلمه عبور اصلی، عضویت خود در این سازمان را کامل کنید." }, "tab": { "message": "زبانه" @@ -132,7 +132,7 @@ "message": "کپی کلمه عبور" }, "copyPassphrase": { - "message": "Copy passphrase" + "message": "کپی عبارت عبور" }, "copyNote": { "message": "کپی یادداشت" @@ -150,31 +150,31 @@ "message": "کپی کد امنیتی" }, "copyName": { - "message": "Copy name" + "message": "کپی نام" }, "copyCompany": { - "message": "Copy company" + "message": "کپی شرکت" }, "copySSN": { - "message": "Copy Social Security number" + "message": "کپی شماره کد ملی" }, "copyPassportNumber": { - "message": "Copy passport number" + "message": "کپی شماره گذرنامه" }, "copyLicenseNumber": { - "message": "Copy license number" + "message": "کپی شماره گواهینامه" }, "copyPrivateKey": { - "message": "Copy private key" + "message": "کپی کلید خصوصی" }, "copyPublicKey": { - "message": "Copy public key" + "message": "کپی کلید عمومی" }, "copyFingerprint": { - "message": "Copy fingerprint" + "message": "کپی اثر انگشت" }, "copyCustomField": { - "message": "Copy $FIELD$", + "message": "کپی $FIELD$", "placeholders": { "field": { "content": "$1", @@ -183,17 +183,17 @@ } }, "copyWebsite": { - "message": "Copy website" + "message": "کپی وب‌سایت" }, "copyNotes": { - "message": "Copy notes" + "message": "کپی یادداشت‌ها" }, "copy": { - "message": "Copy", + "message": "کپی", "description": "Copy to clipboard" }, "fill": { - "message": "Fill", + "message": "پر کردن", "description": "This string is used on the vault page to indicate autofilling. Horizontal space is limited in the interface here so try and keep translations as concise as possible." }, "autoFill": { @@ -209,10 +209,10 @@ "message": "پر کردن خودکار هویت" }, "fillVerificationCode": { - "message": "Fill verification code" + "message": "پر کردن کد تأیید" }, "fillVerificationCodeAria": { - "message": "Fill Verification Code", + "message": "پر کردن کد تأیید", "description": "Aria label for the heading displayed the inline menu for totp code autofill" }, "generatePasswordCopied": { @@ -255,16 +255,16 @@ "message": "افزودن مورد" }, "accountEmail": { - "message": "Account email" + "message": "حساب ایمیل" }, "requestHint": { - "message": "Request hint" + "message": "درخواست راهنمایی" }, "requestPasswordHint": { - "message": "Request password hint" + "message": "درخواست یادآور کلمه عبور" }, "enterYourAccountEmailAddressAndYourPasswordHintWillBeSentToYou": { - "message": "Enter your account email address and your password hint will be sent to you" + "message": "نشانی ایمیل حساب کاربری خود را وارد کنید تا راهنمای کلمه عبور برای شما ارسال شود" }, "getMasterPasswordHint": { "message": "دریافت یادآور کلمه عبور اصلی" @@ -291,25 +291,25 @@ "message": "تغییر کلمه عبور اصلی" }, "continueToWebApp": { - "message": "Continue to web app?" + "message": "با برنامه وب ادامه می‌دهید؟" }, "continueToWebAppDesc": { "message": "ویژگی‌های بیشتر حساب Bitwarden خود را در برنامه وب کاوش کنید." }, "continueToHelpCenter": { - "message": "Continue to Help Center?" + "message": "به مرکز راهنمایی ادامه می‌دهید؟" }, "continueToHelpCenterDesc": { "message": "درباره استفاده از Bitwarden در مرکز راهنما بیشتر بیاموزید." }, "continueToBrowserExtensionStore": { - "message": "آیا میخواهید به فروشگاه افزونه مرورگر ادامه دهید?" + "message": "آیا می‌خواهید به فروشگاه افزونه مرورگر ادامه دهید؟" }, "continueToBrowserExtensionStoreDesc": { "message": "به دیگران کمک کنید تا بفهمند آیا Bitwarden برایشان مناسب است یا نه. به فروشگاه افزونه مرورگر خود بروید و نظر خود را به اشتراک بگذارید." }, "changeMasterPasswordOnWebConfirmation": { - "message": "You can change your master password on the Bitwarden web app." + "message": "می‌توانید کلمه عبور اصلی خود را در برنامه وب Bitwarden تغییر دهید." }, "fingerprintPhrase": { "message": "عبارت اثر انگشت", @@ -332,37 +332,37 @@ "message": "درباره" }, "moreFromBitwarden": { - "message": "More from Bitwarden" + "message": "موارد بیشتر از Bitwarden" }, "continueToBitwardenDotCom": { - "message": "Continue to bitwarden.com?" + "message": "به bitwarden.com ادامه می‌دهید؟" }, "bitwardenForBusiness": { "message": "Bitwarden برای کسب و کارها" }, "bitwardenAuthenticator": { - "message": "تاییدکننده هویت Bitwarden" + "message": "تأییدکننده هویت Bitwarden" }, "continueToAuthenticatorPageDesc": { - "message": "Bitwarden Authenticator allows you to store authenticator keys and generate TOTP codes for 2-step verification flows. Learn more on the bitwarden.com website" + "message": "احراز هویت کننده Bitwarden به شما امکان می‌دهد کلیدهای احراز هویت را ذخیره کرده و کدهای TOTP را برای فرآیندهای تأیید دومرحله‌ای تولید کنید. برای اطلاعات بیشتر به وب‌سایت bitwarden.com مراجعه کنید" }, "bitwardenSecretsManager": { - "message": "Bitwarden Secrets Manager" + "message": "مدیر اسرار Bitwarden" }, "continueToSecretsManagerPageDesc": { - "message": "Securely store, manage, and share developer secrets with Bitwarden Secrets Manager. Learn more on the bitwarden.com website." + "message": "اسرار توسعه دهنده را با مدیر اسرا Bitwarden به‌صورت ایمن ذخیره، مدیریت و به اشتراک بگذارید. برای اطلاعات بیشتر به وب‌سایت bitwarden.com مراجعه کنید." }, "passwordlessDotDev": { "message": "Passwordless.dev" }, "continueToPasswordlessDotDevPageDesc": { - "message": "Create smooth and secure login experiences free from traditional passwords with Passwordless.dev. Learn more on the bitwarden.com website." + "message": "با استفاده از Passwordless.dev تجربه‌های ورود روان و ایمنی را بدون نیاز به کلمات عبور سنتی ایجاد کنید. برای اطلاعات بیشتر به وب‌سایت bitwarden.com مراجعه کنید." }, "freeBitwardenFamilies": { "message": "خانواده‌های رایگان Bitwarden" }, "freeBitwardenFamiliesPageDesc": { - "message": "You are eligible for Free Bitwarden Families. Redeem this offer today in the web app." + "message": "شما واجد شرایط استفاده رایگان از Bitwarden Families هستید. این پیشنهاد را امروز در نسخه وب دریافت کنید." }, "version": { "message": "نسخه" @@ -383,7 +383,7 @@ "message": "ويرايش پوشه" }, "editFolderWithName": { - "message": "Edit folder: $FOLDERNAME$", + "message": "ویرایش پوشه: $FOLDERNAME$", "placeholders": { "foldername": { "content": "$1", @@ -392,22 +392,22 @@ } }, "newFolder": { - "message": "New folder" + "message": "پوشه جدید" }, "folderName": { - "message": "Folder name" + "message": "نام پوشه" }, "folderHintText": { - "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + "message": "برای تو در تو کردن یک پوشه، نام پوشه والد را وارد کرده و سپس یک “/” اضافه کنید. مثال: Social/Forums" }, "noFoldersAdded": { - "message": "No folders added" + "message": "هیچ پوشه‌ای اضافه نشد" }, "createFoldersToOrganize": { - "message": "Create folders to organize your vault items" + "message": "برای سامان‌دهی موردهای گاوصندوق خود پوشه ایجاد کنید" }, "deleteFolderPermanently": { - "message": "Are you sure you want to permanently delete this folder?" + "message": "مطمئنید می‌خواهید این پوشه را برای همیشه پاک کنید؟" }, "deleteFolder": { "message": "حذف پوشه" @@ -450,7 +450,7 @@ "message": "به طور خودکار کلمه‌های عبور قوی و منحصر به فرد برای ورود به سیستم خود ایجاد کنید." }, "bitWebVaultApp": { - "message": "Bitwarden web app" + "message": "برنامه وب Bitwarden" }, "importItems": { "message": "درون ریزی موارد" @@ -462,19 +462,19 @@ "message": "تولید کلمه عبور" }, "generatePassphrase": { - "message": "Generate passphrase" + "message": "تولید عبارت عبور" }, "passwordGenerated": { - "message": "Password generated" + "message": "کلمه عبور تولید شد" }, "passphraseGenerated": { - "message": "Passphrase generated" + "message": "عبارت عبور تولید شد" }, "usernameGenerated": { - "message": "Username generated" + "message": "نام کاربری تولید شد" }, "emailGenerated": { - "message": "Email generated" + "message": "ایمیل تولید شد" }, "regeneratePassword": { "message": "تولید مجدد کلمه عبور" @@ -486,11 +486,11 @@ "message": "طول" }, "include": { - "message": "Include", + "message": "شامل", "description": "Card header for password generator include block" }, "uppercaseDescription": { - "message": "Include uppercase characters", + "message": "شامل حروف بزرگ باشد", "description": "Tooltip for the password generator uppercase character checkbox" }, "uppercaseLabel": { @@ -498,7 +498,7 @@ "description": "Label for the password generator uppercase character checkbox" }, "lowercaseDescription": { - "message": "Include lowercase characters", + "message": "شامل حروف کوچک باشد", "description": "Full description for the password generator lowercase character checkbox" }, "lowercaseLabel": { @@ -506,7 +506,7 @@ "description": "Label for the password generator lowercase character checkbox" }, "numbersDescription": { - "message": "Include numbers", + "message": "شامل اعداد", "description": "Full description for the password generator numbers checkbox" }, "numbersLabel": { @@ -514,7 +514,7 @@ "description": "Label for the password generator numbers checkbox" }, "specialCharactersDescription": { - "message": "Include special characters", + "message": "افزودن کاراکترهای خاص", "description": "Full description for the password generator special characters checkbox" }, "numWords": { @@ -537,11 +537,11 @@ "message": "حداقل حرف خاص" }, "avoidAmbiguous": { - "message": "Avoid ambiguous characters", + "message": "از کاراکترهای مبهم خودداری کن", "description": "Label for the avoid ambiguous characters checkbox." }, "generatorPolicyInEffect": { - "message": "Enterprise policy requirements have been applied to your generator options.", + "message": "نیازمندی‌های سیاست سازمانی بر گزینه‌های تولید کننده شما اعمال شده‌اند.", "description": "Indicates that a policy limits the credential generator screen." }, "searchVault": { @@ -566,7 +566,7 @@ "message": "کلمه عبور" }, "totp": { - "message": "Authenticator secret" + "message": "کلید مخفی احراز کننده هویت‌" }, "passphrase": { "message": "عبارت عبور" @@ -587,7 +587,7 @@ "message": "یادداشت‌ها" }, "privateNote": { - "message": "Private note" + "message": "یادداشت خصوصی" }, "note": { "message": "یادداشت" @@ -608,10 +608,10 @@ "message": "راه اندازی" }, "launchWebsite": { - "message": "Launch website" + "message": "باز کردن وب‌سایت" }, "launchWebsiteName": { - "message": "Launch website $ITEMNAME$", + "message": "باز کردن وب‌سایت $ITEMNAME$", "placeholders": { "itemname": { "content": "$1", @@ -632,19 +632,19 @@ "message": "ساير" }, "unlockMethods": { - "message": "Unlock options" + "message": "باز کردن امکانات" }, "unlockMethodNeededToChangeTimeoutActionDesc": { "message": "یک روش بازگشایی برای پایان زمان مجاز تنظیم کنید." }, "unlockMethodNeeded": { - "message": "Set up an unlock method in Settings" + "message": "یک روش باز کردن قفل را در تنظیمات راه‌اندازی کنید" }, "sessionTimeoutHeader": { - "message": "Session timeout" + "message": "پایان زمان نشست" }, "vaultTimeoutHeader": { - "message": "Vault timeout" + "message": "متوقف شدن گاو‌صندوق" }, "otherOptions": { "message": "سایر گزینه‌ها" @@ -656,25 +656,25 @@ "message": "مرورگر شما از کپی کلیپ بورد آسان پشتیبانی نمی‌کند. به جای آن به صورت دستی کپی کنید." }, "verifyYourIdentity": { - "message": "Verify your identity" + "message": "هویت خود را تأیید کنید" }, "weDontRecognizeThisDevice": { - "message": "We don't recognize this device. Enter the code sent to your email to verify your identity." + "message": "ما این دستگاه را نمی‌شناسیم. برای تأیید هویت خود، کدی را که به ایمیلتان ارسال شده وارد کنید." }, "continueLoggingIn": { - "message": "Continue logging in" + "message": "ادامه ورود" }, "yourVaultIsLocked": { "message": "گاوصندوق شما قفل شده است. برای ادامه هویت خود را تأیید کنید." }, "yourVaultIsLockedV2": { - "message": "Your vault is locked" + "message": "گاوصندوق‌تان قفل شد" }, "yourAccountIsLocked": { - "message": "Your account is locked" + "message": "حساب شما قفل شده است" }, "or": { - "message": "or" + "message": "یا" }, "unlock": { "message": "باز کردن قفل" @@ -699,13 +699,13 @@ "message": "متوقف شدن گاو‌صندوق" }, "vaultTimeout1": { - "message": "Timeout" + "message": "پایان زمان" }, "lockNow": { "message": "الان قفل شود" }, "lockAll": { - "message": "Lock all" + "message": "قفل کردن همه" }, "immediately": { "message": "بلافاصله" @@ -753,16 +753,16 @@ "message": "امنیت" }, "confirmMasterPassword": { - "message": "Confirm master password" + "message": "تأیید کلمه عبور اصلی" }, "masterPassword": { - "message": "Master password" + "message": "کلمه عبور اصلی" }, "masterPassImportant": { - "message": "Your master password cannot be recovered if you forget it!" + "message": "کلمه‌های عبور اصلی در صورت فراموشی قابل بازیابی نیستند!" }, "masterPassHintLabel": { - "message": "Master password hint" + "message": "یادآور کلمه عبور اصلی" }, "errorOccurred": { "message": "خطایی رخ داده است" @@ -796,10 +796,10 @@ "message": "حساب کاربری جدید شما ساخته شد! حالا می‌توانید وارد شوید." }, "newAccountCreated2": { - "message": "Your new account has been created!" + "message": "حساب کاربری جدید شما ایجاد شده است!" }, "youHaveBeenLoggedIn": { - "message": "You have been logged in!" + "message": "شما با موفقیت وارد شدید!" }, "youSuccessfullyLoggedIn": { "message": "شما با موفقیت وارد شدید" @@ -814,7 +814,7 @@ "message": "کد تأیید مورد نیاز است." }, "webauthnCancelOrTimeout": { - "message": "The authentication was cancelled or took too long. Please try again." + "message": "احراز هویت لغو شد یا بیش از حد طول کشید. لطفاً دوباره تلاش کنید." }, "invalidVerificationCode": { "message": "کد تأیید نامعتبر است" @@ -833,73 +833,73 @@ "message": "ناتوان در پر کردن خودکار مورد انتخاب شده در این صفحه. اطلاعات را کپی و جای‌گذاری کنید." }, "totpCaptureError": { - "message": "Unable to scan QR code from the current webpage" + "message": "امکان اسکن کد QR از صفحه وب فعلی وجود ندارد" }, "totpCaptureSuccess": { "message": "کلید احراز هویت اضافه شد" }, "totpCapture": { - "message": "Scan authenticator QR code from current webpage" + "message": "اسکن کد QR احراز هویت کننده از صفحه وب فعلی" }, "totpHelperTitle": { - "message": "Make 2-step verification seamless" + "message": "تأیید دو مرحله‌ای را بدون دردسر کنید" }, "totpHelper": { - "message": "Bitwarden can store and fill 2-step verification codes. Copy and paste the key into this field." + "message": "Bitwarden می‌تواند کدهای تأیید دو مرحله‌ای را ذخیره و پر کند. کلید را کپی کرده و در این فیلد قرار دهید." }, "totpHelperWithCapture": { - "message": "Bitwarden can store and fill 2-step verification codes. Select the camera icon to take a screenshot of this website's authenticator QR code, or copy and paste the key into this field." + "message": "Bitwarden می‌تواند کدهای تأیید دو مرحله‌ای را ذخیره و پر کند. برای اسکن کد QR احراز هویت کننده این وب‌سایت، روی آیکون دوربین کلیک کنید یا کلید را کپی کرده و در این فیلد قرار دهید." }, "learnMoreAboutAuthenticators": { - "message": "Learn more about authenticators" + "message": "درباره احراز هویت کننده‌ها بیشتر بدانید" }, "copyTOTP": { - "message": "Copy Authenticator key (TOTP)" + "message": "کپی کلید احراز هویت (TOTP)" }, "loggedOut": { "message": "خارج شد" }, "loggedOutDesc": { - "message": "You have been logged out of your account." + "message": "شما از حساب خود خارج شده‌اید." }, "loginExpired": { "message": "نشست ورود شما منقضی شده است." }, "logIn": { - "message": "Log in" + "message": "ورود" }, "logInToBitwarden": { - "message": "Log in to Bitwarden" + "message": "وارد Bitwarden شوید" }, "enterTheCodeSentToYourEmail": { - "message": "Enter the code sent to your email" + "message": "کدی را که به ایمیل شما ارسال شده وارد کنید" }, "enterTheCodeFromYourAuthenticatorApp": { - "message": "Enter the code from your authenticator app" + "message": "کد سامانه تأیید کننده را وارد نمایید" }, "pressYourYubiKeyToAuthenticate": { - "message": "Press your YubiKey to authenticate" + "message": "برای احراز هویت، کلید YubiKey خود را فشار دهید" }, "duoTwoFactorRequiredPageSubtitle": { - "message": "Duo two-step login is required for your account. Follow the steps below to finish logging in." + "message": "برای حساب کاربری شما ورود دو مرحله‌ای Duo لازم است. مراحل زیر را دنبال کنید تا ورود خود را کامل کنید." }, "followTheStepsBelowToFinishLoggingIn": { - "message": "Follow the steps below to finish logging in." + "message": "مراحل زیر را دنبال کنید تا وارد سیستم شوید." }, "followTheStepsBelowToFinishLoggingInWithSecurityKey": { - "message": "Follow the steps below to finish logging in with your security key." + "message": "مراحل زیر را برای کامل کردن ورود با کلید امنیتی خود دنبال کنید." }, "restartRegistration": { - "message": "Restart registration" + "message": "ثبت‌نام را دوباره آغاز کنید" }, "expiredLink": { - "message": "Expired link" + "message": "پیوند منقضی شد" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "لطفاً ثبت نام را مجدداً شروع کنید یا دوباره وارد شوید." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "ممکن است قبلاً حساب کاربری داشته باشید" }, "logOutConfirmation": { "message": "آیا مطمئنید که می‌خواهید خارج شوید؟" @@ -911,7 +911,7 @@ "message": "خیر" }, "location": { - "message": "Location" + "message": "موقعیت" }, "unexpectedError": { "message": "یک خطای غیر منتظره رخ داده است." @@ -926,10 +926,10 @@ "message": "ورود دو مرحله ای باعث می‌شود که حساب کاربری شما با استفاده از یک دستگاه دیگر مانند کلید امنیتی، برنامه احراز هویت، پیامک، تماس تلفنی و یا ایمیل، اعتبار خود را با ایمنی بیشتر اثبات کند. ورود دو مرحله ای می تواند در bitwarden.com فعال شود. آیا می‌خواهید از سایت بازدید کنید؟" }, "twoStepLoginConfirmationContent": { - "message": "Make your account more secure by setting up two-step login in the Bitwarden web app." + "message": "با راه‌اندازی ورود دو مرحله‌ای در برنامه وب Bitwarden، حساب کاربری خود را ایمن‌تر کنید." }, "twoStepLoginConfirmationTitle": { - "message": "Continue to web app?" + "message": "با برنامه وب ادامه می‌دهید؟" }, "editedFolder": { "message": "پوشه ذخیره شد" @@ -1016,16 +1016,16 @@ "message": "درخواست افزودن ورود به سیستم" }, "vaultSaveOptionsTitle": { - "message": "Save to vault options" + "message": "گزینه‌های ذخیره در گاوصندوق" }, "addLoginNotificationDesc": { "message": "در صورتی که موردی در گاوصندوق شما یافت نشد، درخواست افزودن کنید." }, "addLoginNotificationDescAlt": { - "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." + "message": "اگر موردی در گاوصندوق شما یافت نشد، درخواست افزودن آن را بدهید. این مورد برای همه حساب‌های وارد شده اعمال می‌شود." }, "showCardsInVaultViewV2": { - "message": "Always show cards as Autofill suggestions on Vault view" + "message": "همیشه کارت‌ها را به‌عنوان پیشنهادهای پر کردن خودکار در نمای گاوصندوق نمایش بده" }, "showCardsCurrentTab": { "message": "نمایش کارت‌ها در صفحه برگه" @@ -1034,7 +1034,7 @@ "message": "برای پر کردن خودکار آسان، موارد کارت را در صفحه برگه فهرست کن." }, "showIdentitiesInVaultViewV2": { - "message": "Always show identities as Autofill suggestions on Vault view" + "message": "همیشه هویت‌ها را به‌عنوان پیشنهادهای پر کردن خودکار در نمای گاوصندوق نمایش بده" }, "showIdentitiesCurrentTab": { "message": "نشان دادن هویت در صفحه برگه" @@ -1043,10 +1043,10 @@ "message": "موارد هویتی را در صفحه برگه برای پر کردن خودکار آسان فهرست کن." }, "clickToAutofillOnVault": { - "message": "Click items to autofill on Vault view" + "message": "برای پر کردن خودکار، روی موردها در نمای گاوصندوق کلیک کنید" }, "clickToAutofill": { - "message": "Click items in autofill suggestion to fill" + "message": "برای پر کردن، روی موردها در پیشنهادهای پرکردن خودکار کلیک کنید" }, "clearClipboard": { "message": "پاکسازی کلیپ بورد", @@ -1063,7 +1063,7 @@ "message": "ذخیره" }, "notificationViewAria": { - "message": "View $ITEMNAME$, opens in new window", + "message": "مشاهده $ITEMNAME$، در پنجره جدید باز می‌شود", "placeholders": { "itemName": { "content": "$1" @@ -1071,15 +1071,19 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "مورد جدید، در پنجره جدید باز می‌شود", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { - "message": "Edit before saving", + "message": "ویرایش قبل ذخیره کردن", "description": "Tooltip and Aria label for edit button on cipher item" }, "newNotification": { - "message": "New notification" + "message": "اعلان جدید" }, "labelWithNotification": { - "message": "$LABEL$: New notification", + "message": "$LABEL$: اعلان جدید", "description": "Label for the notification with a new login suggestion.", "placeholders": { "label": { @@ -1088,50 +1092,56 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "در Bitwarden ذخیره شد.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "در Bitwarden به‌روزرسانی شد.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "انتخاب $ITEMTYPE$، $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { - "message": "Save as new login", + "message": "ذخیره به عنوان ورود جدید", "description": "Button text for saving login details as a new entry." }, "updateLoginAction": { - "message": "Update login", + "message": "به‌روزرسانی ورود", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "برای ذخیره این ورود، قفل را باز کنید", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { - "message": "Save login", + "message": "ذخیره ورود", "description": "Prompt asking the user if they want to save their login details." }, "updateLogin": { - "message": "Update existing login", + "message": "به‌روزرسانی ورود به سیستم موجود", "description": "Prompt asking the user if they want to update an existing login entry." }, "loginSaveSuccess": { - "message": "Login saved", + "message": "ورود ذخیره شد", "description": "Message displayed when login details are successfully saved." }, "loginUpdateSuccess": { - "message": "Login updated", + "message": "ورود به‌روزرسانی شد", "description": "Message displayed when login details are successfully updated." }, "loginUpdateTaskSuccess": { - "message": "Great job! You took the steps to make you and $ORGANIZATION$ more secure.", + "message": "آفرین! شما اقداماتی را انجام دادید تا خودتان و $ORGANIZATION$ را ایمن‌تر کنید.", "placeholders": { "organization": { "content": "$1" @@ -1140,7 +1150,7 @@ "description": "Shown to user after login is updated." }, "loginUpdateTaskSuccessAdditional": { - "message": "Thank you for making $ORGANIZATION$ more secure. You have $TASK_COUNT$ more passwords to update.", + "message": "ممنون که $ORGANIZATION$ را ایمن‌تر کردید. شما $TASK_COUNT$ کلمات عبور دیگر برای به‌روزرسانی دارید.", "placeholders": { "organization": { "content": "$1" @@ -1152,15 +1162,15 @@ "description": "Shown to user after login is updated." }, "nextSecurityTaskAction": { - "message": "Change next password", + "message": "تغییر کلمه عبور بعدی", "description": "Message prompting user to undertake completion of another security task." }, "saveFailure": { - "message": "Error saving", + "message": "خطای ذخیره", "description": "Error message shown when the system fails to save login details." }, "saveFailureDetails": { - "message": "Oh no! We couldn't save this. Try entering the details manually.", + "message": "اوه نه! نتوانستیم این را ذخیره کنیم. لطفاً جزئیات را به‌صورت دستی وارد کنید.", "description": "Detailed error message shown when saving login details fails." }, "enableChangedPasswordNotification": { @@ -1170,13 +1180,13 @@ "message": "هنگامی که تغییری در یک وب‌سایت شناسایی شد، درخواست به‌روزرسانی کلمه عبور ورود کن." }, "changedPasswordNotificationDescAlt": { - "message": "Ask to update a login's password when a change is detected on a website. Applies to all logged in accounts." + "message": "هنگامی که تغییری در کلمه عبور یک ورود در وب‌سایت شناسایی شود، درخواست به‌روزرسانی آن را بده. این مورد برای همه حساب‌های وارد شده اعمال می‌شود." }, "enableUsePasskeys": { "message": "برای ذخیره و استفاده از passkey اجازه بگیر" }, "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 هستید؟" @@ -1200,7 +1210,7 @@ "message": "از یک کلیک ثانویه برای دسترسی به تولید کلمه عبور و ورودهای منطبق برای وب سایت استفاده کن." }, "contextMenuItemDescAlt": { - "message": "Use a secondary click to access password generation and matching logins for the website. Applies to all logged in accounts." + "message": "برای دسترسی به تولید کلمه عبور و ورودهای منطبق با وب‌سایت، از کلیک ثانویه استفاده کنید. این مورد برای همه حساب‌های کاربری وارد شده اعمال می‌شود." }, "defaultUriMatchDetection": { "message": "بررسی مطابقت نشانی اینترنتی پیش‌فرض", @@ -1216,7 +1226,7 @@ "message": "تغییر رنگ پوسته برنامه." }, "themeDescAlt": { - "message": "Change the application's color theme. Applies to all logged in accounts." + "message": "تغییر تم رنگی برنامه. این مورد برای همه حساب‌های کاربری وارد شده اعمال می‌شود." }, "dark": { "message": "تاریک", @@ -1227,7 +1237,7 @@ "description": "Light color" }, "exportFrom": { - "message": "صادرات از" + "message": "برون ریزی از" }, "exportVault": { "message": "برون ریزی گاوصندوق" @@ -1236,35 +1246,35 @@ "message": "فرمت پرونده" }, "fileEncryptedExportWarningDesc": { - "message": "This file export will be password protected and require the file password to decrypt." + "message": "این پرونده برون ریزی با کلمه عبور محافظت می‌شود و برای رمزگشایی به کلمه عبور پرونده نیاز دارد." }, "filePassword": { - "message": "رمز فایل" + "message": "کلمه عبور پرونده" }, "exportPasswordDescription": { - "message": "This password will be used to export and import this file" + "message": "این کلمه عبور برای برون ریزی و درون ریزی این پرونده استفاده می‌شود" }, "accountRestrictedOptionDescription": { - "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account." + "message": "برای رمزگذاری برون ریزی و محدود کردن درون ریزی فقط به حساب کاربری فعلی Bitwarden، از کلید رمزگذاری حساب خود که از نام کاربری و کلمه عبور اصلی حساب شما مشتق شده است استفاده کنید." }, "passwordProtectedOptionDescription": { - "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption." + "message": "یک کلمه عبور برای پرونده به‌منظور رمزگذاری تنظیم کنید تا برون ریزی و درون ریزی آن به هر حساب Bitwarden با استفاده از کلمه عبور رمزگشایی شود." }, "exportTypeHeading": { - "message": "نوع صادرات" + "message": "نوع برون ریزی" }, "accountRestricted": { "message": "حساب کاربری محدود شده است" }, "filePasswordAndConfirmFilePasswordDoNotMatch": { - "message": "عدم تطابق \"رمز فایل\" و \"تایید رمز فایل\" با یکدیگر." + "message": "عدم تطابق \"کلمه عبور پرونده\" و \"تأیید کلمه عبور پرونده\" با یکدیگر." }, "warning": { "message": "اخطار", "description": "WARNING (should stay in capitalized letters if the language permits)" }, "warningCapitalized": { - "message": "Warning", + "message": "هشدار", "description": "Warning (should maintain locale-relevant capitalization)" }, "confirmVaultExport": { @@ -1286,7 +1296,7 @@ "message": "اشتراک گذاری شد" }, "bitwardenForBusinessPageDesc": { - "message": "Bitwarden for Business allows you to share your vault items with others by using an organization. Learn more on the bitwarden.com website." + "message": "Bitwarden for Business به شما اجازه می‌دهد تا با استفاده از یک سازمان، موارد گاوصندوق خود را با دیگران به اشتراک بگذارید. در وب سایت bitwarden.com بیشتر بیاموزید." }, "moveToOrganization": { "message": "انتقال به سازمان" @@ -1344,7 +1354,7 @@ "message": "پرونده" }, "fileToShare": { - "message": "File to share" + "message": "پرونده‌ای برای اشتراک‌گذاری" }, "selectFile": { "message": "ﺍﻧﺘﺨﺎﺏ یک ﭘﺮﻭﻧﺪﻩ" @@ -1380,13 +1390,13 @@ "message": "۱ گیگابایت فضای ذخیره سازی رمزگذاری شده برای پیوست های پرونده." }, "premiumSignUpEmergency": { - "message": "Emergency access." + "message": "دسترسی اضطراری." }, "premiumSignUpTwoStepOptions": { "message": "گزینه های ورود اضافی دو مرحله ای مانند YubiKey و Duo." }, "ppremiumSignUpReports": { - "message": "گزارش‌های بهداشت رمز عبور، سلامت حساب و نقض داده‌ها برای ایمن نگهداشتن گاوصندوق شما." + "message": "گزارش‌های بهداشت کلمه عبور، سلامت حساب و نقض داده‌ها برای ایمن نگهداشتن گاوصندوق شما." }, "ppremiumSignUpTotp": { "message": "تولید کننده کد تأیید (2FA) از نوع TOTP برای ورودهای در گاوصندوقتان." @@ -1401,7 +1411,7 @@ "message": "خرید پرمیوم" }, "premiumPurchaseAlertV2": { - "message": "You can purchase Premium from your account settings on the Bitwarden web app." + "message": "می‌توانید نسخه پرمیوم را از تنظیمات حساب کاربری خود در اپلیکیشن وب Bitwarden خریداری کنید." }, "premiumCurrentMember": { "message": "شما یک عضو پرمیوم هستید!" @@ -1410,7 +1420,7 @@ "message": "برای حمایتتان از Bitwarden سپاسگزاریم." }, "premiumFeatures": { - "message": "Upgrade to Premium and receive:" + "message": "ارتقا به نسخه پرمیوم و دریافت:" }, "premiumPrice": { "message": "تمامش فقط $PRICE$ در سال!", @@ -1422,7 +1432,7 @@ } }, "premiumPriceV2": { - "message": "All for just $PRICE$ per year!", + "message": "تمامش فقط $PRICE$ در سال!", "placeholders": { "price": { "content": "$1", @@ -1449,10 +1459,10 @@ "message": "برای استفاده از این ویژگی عضویت پرمیوم لازم است." }, "authenticationTimeout": { - "message": "Authentication timeout" + "message": "پایان زمان احراز هویت" }, "authenticationSessionTimedOut": { - "message": "The authentication session timed out. Please restart the login process." + "message": "نشست احراز هویت منقضی شد. لطفاً فرایند ورود را دوباره شروع کنید." }, "verificationCodeEmailSent": { "message": "ایمیل تأیید به $EMAIL$ ارسال شد.", @@ -1464,29 +1474,29 @@ } }, "dontAskAgainOnThisDeviceFor30Days": { - "message": "Don't ask again on this device for 30 days" + "message": "در این دستگاه به مدت ۳۰ روز دوباره نپرس" }, "selectAnotherMethod": { - "message": "Select another method", + "message": "انتخاب روش دیگر", "description": "Select another two-step login method" }, "useYourRecoveryCode": { - "message": "Use your recovery code" + "message": "از کد بازیابی‌تان استفاده کنید" }, "insertU2f": { "message": "کلید امنیتی خود را وارد پورت USB رایانه کنید، اگر دکمه ای دارد آن را بفشارید." }, "openInNewTab": { - "message": "Open in new tab" + "message": "گشودن در زبانهٔ جدید" }, "webAuthnAuthenticate": { "message": "تأیید اعتبار در WebAuthn" }, "readSecurityKey": { - "message": "Read security key" + "message": "خواندن کلید امنیتی" }, "awaitingSecurityKeyInteraction": { - "message": "Awaiting security key interaction..." + "message": "در انتظار تعامل با کلید امنیتی..." }, "loginUnavailable": { "message": "ورود به سیستم در دسترس نیست" @@ -1501,7 +1511,7 @@ "message": "گزینه‌های ورود دو مرحله‌ای" }, "selectTwoStepLoginMethod": { - "message": "Select two-step login method" + "message": "انتخاب ورود دو مرحله‌ای" }, "recoveryCodeDesc": { "message": "دسترسی به تمامی ارائه‌دهندگان دو مرحله‌ای را از دست داده‌اید؟ از کد بازیابی خود برای غیرفعال‌سازی ارائه‌دهندگان دو مرحله‌ای از حسابتان استفاده کنید." @@ -1513,17 +1523,17 @@ "message": "برنامه احراز هویت" }, "authenticatorAppDescV2": { - "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "message": "کدی را وارد کنید که توسط یک برنامه احراز هویت مانند Bitwarden Authenticator تولید شده است.", "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, "yubiKeyTitleV2": { - "message": "Yubico OTP Security Key" + "message": "کلید امنیت Yubico OTP" }, "yubiKeyDesc": { "message": "از یک YubiKey برای دسترسی به حسابتان استفاده کنید. همراه با دستگاه‌های YubiKey 4 ،4 Nano ،NEO کار می‌کند." }, "duoDescV2": { - "message": "Enter a code generated by Duo Security.", + "message": "کدی را وارد کنید که توسط Duo Security تولید شده است.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1540,19 +1550,19 @@ "message": "ایمیل" }, "emailDescV2": { - "message": "Enter a code sent to your email." + "message": "کدی را که به ایمیل شما ارسال شده وارد کنید." }, "selfHostedEnvironment": { "message": "محیط خود میزبان" }, "selfHostedBaseUrlHint": { - "message": "Specify the base URL of your on-premises hosted Bitwarden installation. Example: https://bitwarden.company.com" + "message": "نشانی اینترنتی پایه نصب Bitwarden خود را که به‌صورت داخلی میزبانی شده مشخص کنید.\nمثال: https://bitwarden.company.com" }, "selfHostedCustomEnvHeader": { - "message": "For advanced configuration, you can specify the base URL of each service independently." + "message": "برای پیکربندی پیشرفته، می‌توانید نشانی اینترنتی پایه هر سرویس را به‌صورت مستقل مشخص کنید." }, "selfHostedEnvFormInvalid": { - "message": "You must add either the base Server URL or at least one custom environment." + "message": "شما باید یا نشانی اینترنتی پایه سرور را اضافه کنید، یا حداقل یک محیط سفارشی تعریف کنید." }, "customEnvironment": { "message": "محیط سفارشی" @@ -1561,7 +1571,7 @@ "message": "نشانی اینترنتی سرور" }, "selfHostBaseUrl": { - "message": "Self-host server URL", + "message": "نشانی اینترنتی سرور خود میزبان", "description": "Label for field requesting a self-hosted integration service URL" }, "apiUrl": { @@ -1583,29 +1593,47 @@ "message": "نشانی‌های اینترنتی محیط ذخیره شد" }, "showAutoFillMenuOnFormFields": { - "message": "Show autofill menu on form fields", + "message": "نمایش منوی پر کردن خودکار روی فیلدهای فرم", "description": "Represents the message for allowing the user to enable the autofill overlay" }, "autofillSuggestionsSectionTitle": { - "message": "Autofill suggestions" + "message": "پیشنهادهای پر کردن خودکار" + }, + "autofillSpotlightTitle": { + "message": "یافتن آسان پیشنهادهای پر کردن خودکار" + }, + "autofillSpotlightDesc": { + "message": "تنظیمات پر کردن خودکار مرورگر خود را غیرفعال کنید تا با Bitwarden تداخل نداشته باشد." + }, + "turnOffBrowserAutofill": { + "message": "پر کردن خودکار $BROWSER$ را غیرفعال کنید", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "پر کردن خودکار را خاموش کنید" }, "showInlineMenuLabel": { - "message": "Show autofill suggestions on form fields" + "message": "نمایش پیشنهادهای پر کردن خودکار روی فیلدهای فرم" }, "showInlineMenuIdentitiesLabel": { - "message": "Display identities as suggestions" + "message": "نمایش هویت‌ها به‌عنوان پیشنهاد" }, "showInlineMenuCardsLabel": { - "message": "Display cards as suggestions" + "message": "نمایش کارت‌ها به‌عنوان پیشنهاد" }, "showInlineMenuOnIconSelectionLabel": { - "message": "Display suggestions when icon is selected" + "message": "نمایش پیشنهادها هنگام انتخاب آیکون" }, "showInlineMenuOnFormFieldsDescAlt": { - "message": "Applies to all logged in accounts." + "message": "برای تمام حساب‌های کاربری وارد شده اعمال می‌شود." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser's built in password manager settings to avoid conflicts." + "message": "تنظیمات مدیر کلمه عبور داخلی مرورگر خود را غیرفعال کنید تا از بروز تداخل جلوگیری شود." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "ویرایش تنظیمات مرورگر." @@ -1615,15 +1643,15 @@ "description": "Overlay setting select option for disabling autofill overlay" }, "autofillOverlayVisibilityOnFieldFocus": { - "message": "When field is selected (on focus)", + "message": "وقتی فیلد انتخاب شد (در حالت فوکوس)", "description": "Overlay appearance select option for showing the field on focus of the input element" }, "autofillOverlayVisibilityOnButtonClick": { - "message": "When autofill icon is selected", + "message": "وقتی آیکون پر کردن خودکار انتخاب شود", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, "enableAutoFillOnPageLoadSectionTitle": { - "message": "Autofill on page load" + "message": "پر کردن خودکار هنگام بارگذاری صفحه" }, "enableAutoFillOnPageLoad": { "message": "پر کردن خودکار هنگام بارگذاری صفحه" @@ -1635,7 +1663,7 @@ "message": "وب‌سایت‌های در معرض خطر یا نامعتبر می‌توانند از پر کردن خودکار در بارگذاری صفحه سوء استفاده کنند." }, "learnMoreAboutAutofillOnPageLoadLinkText": { - "message": "Learn more about risks" + "message": "درباره‌ خطراتش بیش‌تر بدانید" }, "learnMoreAboutAutofill": { "message": "درباره پر کردن خودکار بیشتر بدانید" @@ -1665,13 +1693,13 @@ "message": "باز کردن گاوصندوق در نوار کناری" }, "commandAutofillLoginDesc": { - "message": "Autofill the last used login for the current website" + "message": "آخرین ورودی مورد استفاده برای وب سایت فعلی را به صورت خودکار پر کنید" }, "commandAutofillCardDesc": { - "message": "Autofill the last used card for the current website" + "message": "آخرین کارت مورد استفاده برای وب سایت فعلی را به صورت خودکار پر کنید" }, "commandAutofillIdentityDesc": { - "message": "Autofill the last used identity for the current website" + "message": "آخرین هویت مورد استفاده برای وب سایت فعلی را به صورت خودکار پر کنید" }, "commandGeneratePasswordDesc": { "message": "یک کلمه عبور تصادفی جدید ایجاد کنید و آن را در کلیپ بورد کپی کنید" @@ -1695,7 +1723,7 @@ "message": "برای مرتب‌سازی بکشید" }, "dragToReorder": { - "message": "Drag to reorder" + "message": "برای تغییر ترتیب، بکشید و رها کنید" }, "cfTypeText": { "message": "متن" @@ -1707,7 +1735,7 @@ "message": "منطقی" }, "cfTypeCheckbox": { - "message": "Checkbox" + "message": "کادر انتخاب" }, "cfTypeLinked": { "message": "پیوند شده", @@ -1730,7 +1758,7 @@ "message": "یک تصویر قابل تشخیص در کنار هر ورود نشان دهید." }, "faviconDescAlt": { - "message": "Show a recognizable image next to each login. Applies to all logged in accounts." + "message": "نمایش تصویر قابل تشخیص کنار هر ورود به سیستم. برای تمام حساب‌های کاربری وارد شده اعمال می‌شود." }, "enableBadgeCounter": { "message": "نمایش شمارنده نشان" @@ -1892,7 +1920,7 @@ "message": "هویت" }, "typeSshKey": { - "message": "SSH key" + "message": "کلید SSH" }, "newItemHeader": { "message": "$TYPE$ جدید", @@ -1913,7 +1941,7 @@ } }, "viewItemHeader": { - "message": "View $TYPE$", + "message": "مشاهده $TYPE$", "placeholders": { "type": { "content": "$1", @@ -1925,13 +1953,13 @@ "message": "تاریخچه کلمه عبور" }, "generatorHistory": { - "message": "Generator history" + "message": "تاریخچه تولید کننده" }, "clearGeneratorHistoryTitle": { - "message": "Clear generator history" + "message": "پاک کردن تاریخچه تولید کننده" }, "cleargGeneratorHistoryDescription": { - "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + "message": "اگر ادامه دهید، تمام ورودی‌ها به‌طور دائمی از تاریخچه تولید کننده حذف خواهند شد. آیا مطمئن هستید که می‌خواهید ادامه دهید؟" }, "back": { "message": "بازگشت" @@ -1940,7 +1968,7 @@ "message": "مجموعه‌ها" }, "nCollections": { - "message": "$COUNT$ collections", + "message": "$COUNT$ مجموعه‌ها", "placeholders": { "count": { "content": "$1", @@ -1970,7 +1998,7 @@ "message": "یادداشت‌های امن" }, "sshKeys": { - "message": "SSH Keys" + "message": "کلید‌‌های SSH" }, "clear": { "message": "پاک کردن", @@ -1996,7 +2024,7 @@ "description": "Domain name. Ex. website.com" }, "baseDomainOptionRecommended": { - "message": "Base domain (recommended)", + "message": "دامنه پایه (پیشنهادی)", "description": "Domain name. Ex. website.com" }, "domainName": { @@ -2050,13 +2078,13 @@ "message": "هیچ کلمه عبوری برای فهرست کردن وجود ندارد." }, "clearHistory": { - "message": "Clear history" + "message": "پاک کردن تاریخچه" }, "nothingToShow": { - "message": "Nothing to show" + "message": "چیزی برای نشان دادن موجود نیست" }, "nothingGeneratedRecently": { - "message": "You haven't generated anything recently" + "message": "شما اخیراً چیزی تولید نکرده‌اید" }, "remove": { "message": "حذف" @@ -2117,16 +2145,16 @@ "message": "باز کردن با پین" }, "setYourPinTitle": { - "message": "Set PIN" + "message": "تنظیم کد پین" }, "setYourPinButton": { - "message": "Set PIN" + "message": "تنظیم کد پین" }, "setYourPinCode": { "message": "کد پین خود را برای باز کردن Bitwarden تنظیم کنید. اگر به طور کامل از برنامه خارج شوید، تنظیمات پین شما از بین می‌رود." }, "setYourPinCode1": { - "message": "Your PIN will be used to unlock Bitwarden instead of your master password. Your PIN will reset if you ever fully log out of Bitwarden." + "message": "کد پین شما برای باز کردن Bitwarden به جای کلمه عبور اصلی استفاده خواهد شد. در صورتی که کاملاً از Bitwarden خارج شوید، کد پین شما ریست خواهد شد." }, "pinRequired": { "message": "کد پین الزامیست." @@ -2135,13 +2163,13 @@ "message": "کد پین معتبر نیست." }, "tooManyInvalidPinEntryAttemptsLoggingOut": { - "message": "Too many invalid PIN entry attempts. Logging out." + "message": "تعداد تلاش‌های ناموفق پین زیاد شد. خارج می‌شوید." }, "unlockWithBiometrics": { "message": "با استفاده از بیومتریک باز کنید" }, "unlockWithMasterPassword": { - "message": "Unlock with master password" + "message": "باز کردن قفل با کلمه عبور اصلی" }, "awaitDesktop": { "message": "در انتظار تأیید از دسکتاپ" @@ -2153,7 +2181,7 @@ "message": "در زمان شروع مجدد، با کلمه عبور اصلی قفل کن" }, "lockWithMasterPassOnRestart1": { - "message": "Require master password on browser restart" + "message": "در زمان شروع مجدد، کلمه عبور اصلی نیاز است" }, "selectOneCollection": { "message": "شما باید حداقل یک مجموعه را انتخاب کنید." @@ -2165,48 +2193,42 @@ "message": "شبیه سازی" }, "passwordGenerator": { - "message": "Password generator" + "message": "تولید کننده کلمه عبور" }, "usernameGenerator": { - "message": "Username generator" + "message": "تولید کننده نام کاربری" }, "useThisEmail": { - "message": "Use this email" + "message": "از این ایمیل استفاده شود" }, "useThisPassword": { - "message": "Use this password" + "message": "از این کلمه عبور استفاده کن" + }, + "useThisPassphrase": { + "message": "Use this passphrase" }, "useThisUsername": { - "message": "Use this username" + "message": "از این نام کاربری استفاده کن" }, "securePasswordGenerated": { - "message": "Secure password generated! Don't forget to also update your password on the website." + "message": "کلمه عبور ایمن ساخته شد! فراموش نکنید کلمه عبور خود را در وب‌سایت نیز به‌روزرسانی کنید." }, "useGeneratorHelpTextPartOne": { - "message": "Use the generator", + "message": "از تولید کننده استفاده کنید", "description": "This will be used as part of a larger sentence, broken up to include the generator icon. The full sentence will read 'Use the generator [GENERATOR_ICON] to create a strong unique password'" }, "useGeneratorHelpTextPartTwo": { - "message": "to create a strong unique password", + "message": "برای ایجاد یک کلمه عبور قوی و منحصر به فرد", "description": "This will be used as part of a larger sentence, broken up to include the generator icon. The full sentence will read 'Use the generator [GENERATOR_ICON] to create a strong unique password'" }, "vaultCustomization": { - "message": "Vault customization" + "message": "سفارشی‌سازی گاوصندوق" }, "vaultTimeoutAction": { "message": "عمل متوقف شدن گاو‌صندوق" }, "vaultTimeoutAction1": { - "message": "Timeout action" - }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" + "message": "اقدام در صورت پایان زمان" }, "lock": { "message": "قفل", @@ -2235,7 +2257,7 @@ "message": "مورد بازیابی شد" }, "alreadyHaveAccount": { - "message": "Already have an account?" + "message": "در حال حاضر حساب کاربری دارید؟" }, "vaultTimeoutLogOutConfirmation": { "message": "خروج از سیستم، تمام دسترسی ها به گاو‌صندوق شما را از بین می‌برد و نیاز به احراز هویت آنلاین پس از مدت زمان توقف دارد. آیا مطمئن هستید که می‌خواهید از این تنظیمات استفاده کنید؟" @@ -2328,7 +2350,7 @@ "message": "کلمه عبور اصلی جدید شما از شرایط سیاست پیروی نمی‌کند." }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "پیشنهادها، اعلان‌ها و فرصت‌های تحقیقاتی Bitwarden را در صندوق ورودی خود دریافت کنید." }, "unsubscribe": { "message": "لغو اشتراک" @@ -2355,7 +2377,7 @@ "message": "سیاست حفظ حریم خصوصی" }, "yourNewPasswordCannotBeTheSameAsYourCurrentPassword": { - "message": "Your new password cannot be the same as your current password." + "message": "کلمه عبور جدید شما نمی‌تواند با کلمه عبور فعلی‌تان یکسان باشد." }, "hintEqualsPassword": { "message": "اشاره به کلمه عبور شما نمی‌تواند همان کلمه عبور شما باشد." @@ -2364,10 +2386,10 @@ "message": "تأیید" }, "errorRefreshingAccessToken": { - "message": "Access Token Refresh Error" + "message": "خطای به‌روزرسانی توکن دسترسی" }, "errorRefreshingAccessTokenDesc": { - "message": "No refresh token or API keys found. Please try logging out and logging back in." + "message": "هیچ توکن به‌روزرسانی یا کلید API یافت نشد. لطفاً از حساب کاربری خود خارج شده و دوباره وارد شوید." }, "desktopSyncVerificationTitle": { "message": "تأیید همگام‌سازی دسکتاپ" @@ -2406,10 +2428,10 @@ "message": "عدم مطابقت حساب کاربری" }, "nativeMessagingWrongUserKeyTitle": { - "message": "Biometric key missmatch" + "message": "عدم تطابق کلید بیومتریک" }, "nativeMessagingWrongUserKeyDesc": { - "message": "Biometric unlock failed. The biometric secret key failed to unlock the vault. Please try to set up biometrics again." + "message": "باز کردن قفل بیومتریک ناموفق بود. کلید مخفی بیومتریک نتوانست گاوصندوق را باز کند. لطفاً دوباره تنظیمات بیومتریک را انجام دهید." }, "biometricsNotEnabledTitle": { "message": "بیومتریک برپا نشده" @@ -2427,13 +2449,13 @@ "message": "کاربر قفل یا خارج شد" }, "biometricsNotUnlockedDesc": { - "message": "Please unlock this user in the desktop application and try again." + "message": "لطفاً این کاربر را در برنامه دسکتاپ باز کنید و دوباره تلاش کنید." }, "biometricsNotAvailableTitle": { - "message": "Biometric unlock unavailable" + "message": "باز کردن قفل بیومتریک در دسترس نیست" }, "biometricsNotAvailableDesc": { - "message": "Biometric unlock is currently unavailable. Please try again later." + "message": "باز کردن قفل بیومتریک در حال حاضر در دسترس نیست. لطفاً بعداً دوباره تلاش کنید." }, "biometricsFailedTitle": { "message": "زیست‌سنجی ناموفق بود" @@ -2460,17 +2482,17 @@ "message": "سیاست سازمانی بر تنظیمات مالکیت شما تأثیر می‌گذارد." }, "personalOwnershipPolicyInEffectImports": { - "message": "An organization policy has blocked importing items into your individual vault." + "message": "یک سیاست سازمانی، درون ریزی موارد به گاوصندوق فردی شما را مسدود کرده است." }, "domainsTitle": { - "message": "Domains", + "message": "دامنه‌ها", "description": "A category title describing the concept of web domains" }, "blockedDomains": { - "message": "Blocked domains" + "message": "دامنه‌های مسدود شده" }, "learnMoreAboutBlockedDomains": { - "message": "Learn more about blocked domains" + "message": "اطلاعات بیشتر درباره دامنه‌های مسدود شده" }, "excludedDomains": { "message": "دامنه های مستثنی" @@ -2479,22 +2501,22 @@ "message": "Bitwarden برای ذخیره جزئیات ورود به سیستم این دامنه ها سوال نمی‌کند. برای اینکه تغییرات اعمال شود باید صفحه را تازه کنید." }, "excludedDomainsDescAlt": { - "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." + "message": "Bitwarden برای هیچ یک از حساب‌های کاربری وارد شده، درخواست ذخیره اطلاعات ورود برای این دامنه‌ها را نخواهد داد. برای اعمال تغییرات باید صفحه را تازه‌سازی کنید." }, "blockedDomainsDesc": { - "message": "Autofill and other related features will not be offered for these websites. You must refresh the page for changes to take effect." + "message": "ویژگی‌های پر کردن خودکار و سایر قابلیت‌های مرتبط برای این وب‌سایت‌ها ارائه نخواهند شد. برای اعمال تغییرات باید صفحه را تازه‌سازی کنید." }, "autofillBlockedNoticeV2": { - "message": "Autofill is blocked for this website." + "message": "پر کردن خودکار برای این وب‌سایت مسدود شده است." }, "autofillBlockedNoticeGuidance": { - "message": "Change this in settings" + "message": "این مورد را در تنظیمات تغییر دهید" }, "change": { - "message": "Change" + "message": "تغییر" }, "changeButtonTitle": { - "message": "Change password - $ITEMNAME$", + "message": "تغییر کلمه عبور - $ITEMNAME$", "placeholders": { "itemname": { "content": "$1", @@ -2503,10 +2525,10 @@ } }, "atRiskPasswords": { - "message": "At-risk passwords" + "message": "کلمات عبور در معرض خطر" }, "atRiskPasswordDescSingleOrg": { - "message": "$ORGANIZATION$ is requesting you change one password because it is at-risk.", + "message": "$ORGANIZATION$ از شما درخواست کرده یک کلمه عبور را به دلیل در معرض خطر بودن تغییر دهید.", "placeholders": { "organization": { "content": "$1", @@ -2515,7 +2537,7 @@ } }, "atRiskPasswordsDescSingleOrgPlural": { - "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at-risk.", + "message": "$ORGANIZATION$ از شما درخواست کرده $COUNT$ کلمه عبور را به دلیل در معرض خطر بودن تغییر دهید.", "placeholders": { "organization": { "content": "$1", @@ -2528,7 +2550,7 @@ } }, "atRiskPasswordsDescMultiOrgPlural": { - "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at-risk.", + "message": "سازمان‌های شما از شما درخواست کرده‌اند که $COUNT$ کلمه عبور را به دلیل در معرض خطر بودن تغییر دهید.", "placeholders": { "count": { "content": "$1", @@ -2537,10 +2559,10 @@ } }, "reviewAndChangeAtRiskPassword": { - "message": "Review and change one at-risk password" + "message": "بررسی و تغییر یک کلمه عبور در معرض خطر" }, "reviewAndChangeAtRiskPasswordsPlural": { - "message": "Review and change $COUNT$ at-risk passwords", + "message": "بررسی و تغییر $COUNT$ کلمه عبور در معرض خطر", "placeholders": { "count": { "content": "$1", @@ -2549,52 +2571,52 @@ } }, "changeAtRiskPasswordsFaster": { - "message": "Change at-risk passwords faster" + "message": "تغییر سریع‌تر کلمات عبور در معرض خطر" }, "changeAtRiskPasswordsFasterDesc": { - "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + "message": "تنظیمات خود را به‌روزرسانی کنید تا بتوانید به‌سرعت کلمات عبور خود را به‌صورت خودکار وارد کرده و کلمات جدید تولید کنید" }, "reviewAtRiskLogins": { - "message": "Review at-risk logins" + "message": "بررسی ورودهای در معرض خطر" }, "reviewAtRiskPasswords": { - "message": "Review at-risk passwords" + "message": "بررسی کلمات عبور در معرض خطر" }, "reviewAtRiskLoginsSlideDesc": { - "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", + "message": "کلمات عبور سازمان شما در معرض خطر هستند زیرا ضعیف، تکراری و یا افشا شده‌اند.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, "reviewAtRiskLoginSlideImgAltPeriod": { - "message": "Illustration of a list of logins that are at-risk." + "message": "تصویری از فهرست ورودهایی که در معرض خطر هستند." }, "generatePasswordSlideDesc": { - "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", + "message": "با استفاده از منوی پر کردن خودکار Bitwarden در سایت در معرض خطر، به‌سرعت یک کلمه عبور قوی و منحصر به فرد تولید کنید.", "description": "Description of the generate password slide on the at-risk password page carousel" }, "generatePasswordSlideImgAltPeriod": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password." + "message": "تصویری از منوی پر کردن خودکار Bitwarden که یک کلمه عبور تولید شده را نمایش می‌دهد." }, "updateInBitwarden": { - "message": "Update in Bitwarden" + "message": "به‌روزرسانی در Bitwarden" }, "updateInBitwardenSlideDesc": { - "message": "Bitwarden will then prompt you to update the password in the password manager.", + "message": "سپس Bitwarden از شما می‌خواهد کلمه عبور را در مدیریت کلمه عبور به‌روزرسانی کنید.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, "updateInBitwardenSlideImgAltPeriod": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." + "message": "تصویری از اعلان Bitwarden که از کاربر می‌خواهد ورود خود را به‌روزرسانی کند." }, "turnOnAutofill": { - "message": "Turn on autofill" + "message": "پر کردن خودکار را فعال کنید" }, "turnedOnAutofill": { - "message": "Turned on autofill" + "message": "پر کردن خودکار فعال شد" }, "dismiss": { - "message": "Dismiss" + "message": "نادیده گرفتن" }, "websiteItemLabel": { - "message": "Website $number$ (URI)", + "message": "وب‌سایت $number$ (نشانی اینترنتی)", "placeholders": { "number": { "content": "$1", @@ -2612,20 +2634,20 @@ } }, "blockedDomainsSavedSuccess": { - "message": "Blocked domain changes saved" + "message": "تغییرات دامنه مسدود شده ذخیره شد" }, "excludedDomainsSavedSuccess": { - "message": "Excluded domain changes saved" + "message": "تغییرات دامنه مستثنی شده ذخیره شد" }, "limitSendViews": { - "message": "Limit views" + "message": "محدود کردن نمایش‌ها" }, "limitSendViewsHint": { - "message": "No one can view this Send after the limit is reached.", + "message": "هیچ‌کس نمی‌تواند این را پس از رسیدن به محدودیت مشاهده کند.", "description": "Displayed under the limit views field on Send" }, "limitSendViewsCount": { - "message": "$ACCESSCOUNT$ views left", + "message": "$ACCESSCOUNT$ بازدید باقی مانده", "description": "Displayed under the limit views field on Send", "placeholders": { "accessCount": { @@ -2639,14 +2661,14 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendDetails": { - "message": "Send details", + "message": "جزئیات ارسال", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendTypeText": { "message": "متن" }, "sendTypeTextToShare": { - "message": "Text to share" + "message": "متن برای اشتراک گذاری" }, "sendTypeFile": { "message": "پرونده" @@ -2655,8 +2677,12 @@ "message": "همه ارسال ها", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { - "message": "Hide text by default" + "message": "متن را به‌صورت پیش‌فرض مخفی کن" }, "expired": { "message": "منقضی شده" @@ -2665,7 +2691,7 @@ "message": "محافظت ‌شده با کلمه عبور" }, "copyLink": { - "message": "Copy link" + "message": "کپی پیوند" }, "copySendLink": { "message": "پیوند ارسال را کپی کن", @@ -2703,7 +2729,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "deleteSendPermanentConfirmation": { - "message": "Are you sure you want to permanently delete this Send?", + "message": "مطمئن هستید می‌خواهید این ارسال را برای همیشه پاک کنید؟", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "editSend": { @@ -2714,7 +2740,7 @@ "message": "تاریخ حذف" }, "deletionDateDescV2": { - "message": "The Send will be permanently deleted on this date.", + "message": "ارسال در این تاریخ به‌طور دائمی حذف خواهد شد.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "expirationDate": { @@ -2736,7 +2762,7 @@ "message": "سفارشی" }, "sendPasswordDescV3": { - "message": "Add an optional password for recipients to access this Send.", + "message": "یک کلمه عبور اختیاری برای دریافت‌کنندگان اضافه کنید تا بتوانند به این ارسال دسترسی داشته باشند.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "createSend": { @@ -2759,15 +2785,15 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "createdSendSuccessfully": { - "message": "Send created successfully!", + "message": "ارسال با موفقیت ساخته شد!", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendExpiresInHoursSingle": { - "message": "The Send will be available to anyone with the link for the next 1 hour.", + "message": "این ارسال به مدت ۱ ساعت برای هر کسی که لینک را دارد در دسترس خواهد بود.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendExpiresInHours": { - "message": "The Send will be available to anyone with the link for the next $HOURS$ hours.", + "message": "این ارسال به مدت $HOURS$ ساعت برای هر کسی که لینک را دارد در دسترس خواهد بود.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.", "placeholders": { "hours": { @@ -2777,11 +2803,11 @@ } }, "sendExpiresInDaysSingle": { - "message": "The Send will be available to anyone with the link for the next 1 day.", + "message": "این ارسال به مدت ۱ روز برای هر کسی که لینک را دارد در دسترس خواهد بود.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendExpiresInDays": { - "message": "The Send will be available to anyone with the link for the next $DAYS$ days.", + "message": "این ارسال به مدت $DAYS$ روز برای هر کسی که لینک را دارد در دسترس خواهد بود.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.", "placeholders": { "days": { @@ -2791,7 +2817,7 @@ } }, "sendLinkCopied": { - "message": "Send link copied", + "message": "لینک ارسال کپی شد", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "editedSend": { @@ -2799,11 +2825,11 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendFilePopoutDialogText": { - "message": "Pop out extension?", + "message": "باز کردن پنجره جداگانه افزونه؟", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendFilePopoutDialogDesc": { - "message": "To create a file Send, you need to pop out the extension to a new window.", + "message": "برای ایجاد یک ارسال پرونده، باید افزونه را در پنجره‌ای جدید باز کنید.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendLinuxChromiumFileWarning": { @@ -2816,7 +2842,7 @@ "message": "برای انتخاب پرونده ای با استفاده از Safari، با کلیک روی این بنر پنجره جدیدی باز کنید." }, "popOut": { - "message": "Pop out" + "message": "باز کردن در پنجره جداگانه" }, "sendFileCalloutHeader": { "message": "قبل از اینکه شروع کنی" @@ -2837,7 +2863,7 @@ "message": "هنگام ذخیره حذف و تاریخ انقضاء شما خطایی روی داد." }, "hideYourEmail": { - "message": "Hide your email address from viewers." + "message": "آدرس ایمیل خود را از بینندگان مخفی کنید." }, "passwordPrompt": { "message": "درخواست مجدد کلمه عبور اصلی" @@ -2852,7 +2878,7 @@ "message": "تأیید ایمیل لازم است" }, "emailVerifiedV2": { - "message": "Email verified" + "message": "ایمیل تأیید شد" }, "emailVerificationRequiredDesc": { "message": "برای استفاده از این ویژگی باید ایمیل خود را تأیید کنید. می‌توانید ایمیل خود را در گاوصندوق وب تأیید کنید." @@ -2870,7 +2896,7 @@ "message": "کلمه عبور اصلی شما با یک یا چند سیاست سازمان‌تان مطابقت ندارد. برای دسترسی به گاوصندوق، باید همین حالا کلمه عبور اصلی خود را به‌روز کنید. در صورت ادامه، شما از نشست فعلی خود خارج می‌شوید و باید دوباره وارد سیستم شوید. نشست فعال در دستگاه های دیگر ممکن است تا یک ساعت همچنان فعال باقی بمانند." }, "tdeDisabledMasterPasswordRequired": { - "message": "Your organization has disabled trusted device encryption. Please set a master password to access your vault." + "message": "سازمان شما رمزگذاری دستگاه‌های مورد اعتماد را غیرفعال کرده است. لطفاً برای دسترسی به گاوصندوق خود یک کلمه عبور اصلی تنظیم کنید." }, "resetPasswordPolicyAutoEnroll": { "message": "ثبت نام خودکار" @@ -2886,15 +2912,15 @@ "description": "Used as a message within the notification bar when no folders are found" }, "orgPermissionsUpdatedMustSetPassword": { - "message": "Your organization permissions were updated, requiring you to set a master password.", + "message": "مجوزهای سازمان شما به‌روزرسانی شد، باید یک کلمه عبور اصلی تنظیم کنید.", "description": "Used as a card title description on the set password page to explain why the user is there" }, "orgRequiresYouToSetPassword": { - "message": "Your organization requires you to set a master password.", + "message": "سازمانتان از شما می‌خواهد که یک کلمه عبور اصلی تنظیم کنید.", "description": "Used as a card title description on the set password page to explain why the user is there" }, "cardMetrics": { - "message": "out of $TOTAL$", + "message": "از میان $TOTAL$", "placeholders": { "total": { "content": "$1", @@ -2913,7 +2939,7 @@ "message": "دقیقه" }, "vaultTimeoutPolicyAffectingOptions": { - "message": "Enterprise policy requirements have been applied to your timeout options" + "message": "نیازمندی‌های سیاست سازمانی بر گزینه‌های زمان پایان نشست شما اعمال شده است" }, "vaultTimeoutPolicyInEffect": { "message": "سیاست‌های سازمانتان بر مهلت زمانی گاوصندوق شما تأثیر می‌گذارد. حداکثر زمان مجاز گاوصندوق $HOURS$ ساعت و $MINUTES$ دقیقه است", @@ -2929,7 +2955,7 @@ } }, "vaultTimeoutPolicyInEffect1": { - "message": "$HOURS$ hour(s) and $MINUTES$ minute(s) maximum.", + "message": "حداکثر $HOURS$ ساعت و $MINUTES$ دقیقه.", "placeholders": { "hours": { "content": "$1", @@ -2942,7 +2968,7 @@ } }, "vaultTimeoutPolicyMaximumError": { - "message": "Timeout exceeds the restriction set by your organization: $HOURS$ hour(s) and $MINUTES$ minute(s) maximum", + "message": "زمان پایان نشست بیشتر از محدودیتی است که سازمان شما تعیین کرده است: حداکثر $HOURS$ ساعت و $MINUTES$ دقیقه", "placeholders": { "hours": { "content": "$1", @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "شناسه منحصر به فردی یافت نشد." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ در حال استفاده از SSO با یک سرور کلید خود میزبان است. برای ورود اعضای این سازمان دیگر نیازی به کلمه عبور اصلی نیست.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "برای اعضای سازمان زیر، کلمه عبور اصلی دیگر لازم نیست. لطفاً دامنه زیر را با مدیر سازمان خود تأیید کنید." + }, + "organizationName": { + "message": "نام سازمان" + }, + "keyConnectorDomain": { + "message": "دامنه رابط کلید" }, "leaveOrganization": { "message": "ترک سازمان" @@ -3038,7 +3064,7 @@ } }, "exportingIndividualVaultWithAttachmentsDescription": { - "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "message": "فقط موردهای فردی گاوصندوق شامل پیوست‌ها که به $EMAIL$ مرتبط هستند برون ریزی خواهند شد. موردهای گاوصندوق سازمانی شامل نمی‌شوند", "placeholders": { "email": { "content": "$1", @@ -3047,10 +3073,10 @@ } }, "exportingOrganizationVaultTitle": { - "message": "Exporting organization vault" + "message": "در حال برون ریزی گاوصندوق سازمان" }, "exportingOrganizationVaultDesc": { - "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", + "message": "فقط گاوصدوق سازمان مرتبط با $ORGANIZATION$ برون ریزی خواهد شد. موارد موجود در گاوصندوق‌های فردی یا سایر سازمان‌ها شامل نمی‌شوند.", "placeholders": { "organization": { "content": "$1", @@ -3062,27 +3088,27 @@ "message": "خطا" }, "decryptionError": { - "message": "Decryption error" + "message": "خطای رمزگشایی" }, "couldNotDecryptVaultItemsBelow": { - "message": "Bitwarden could not decrypt the vault item(s) listed below." + "message": "Bitwarden نتوانست مورد(های) گاوصندوق فهرست شده زیر را رمزگشایی کند." }, "contactCSToAvoidDataLossPart1": { - "message": "Contact customer success", + "message": "با بخش پشتیبانی مشتریان تماس بگیرید", "description": "This is part of a larger sentence. The full sentence will read 'Contact customer success to avoid additional data loss.'" }, "contactCSToAvoidDataLossPart2": { - "message": "to avoid additional data loss.", + "message": "برای جلوگیری از، از دست دادن داده‌های بیشتر.", "description": "This is part of a larger sentence. The full sentence will read 'Contact customer success to avoid additional data loss.'" }, "generateUsername": { "message": "ایجاد نام کاربری" }, "generateEmail": { - "message": "Generate email" + "message": "تولید ایمیل" }, "spinboxBoundariesHint": { - "message": "Value must be between $MIN$ and $MAX$.", + "message": "مقدار باید بین $MIN$ و $MAX$ باشد.", "description": "Explains spin box minimum and maximum values to the user", "placeholders": { "min": { @@ -3096,7 +3122,7 @@ } }, "passwordLengthRecommendationHint": { - "message": " Use $RECOMMENDED$ characters or more to generate a strong password.", + "message": " برای تولید یک کلمه عبور قوی، از $RECOMMENDED$ کاراکتر یا بیشتر استفاده کنید.", "description": "Appended to `spinboxBoundariesHint` to recommend a length to the user. This must include any language-specific 'sentence' separator characters (e.g. a space in english).", "placeholders": { "recommended": { @@ -3106,7 +3132,7 @@ } }, "passphraseNumWordsRecommendationHint": { - "message": " Use $RECOMMENDED$ words or more to generate a strong passphrase.", + "message": " برای تولید یک عبارت عبور قوی، از $RECOMMENDED$ واژه یا بیشتر استفاده کنید.", "description": "Appended to `spinboxBoundariesHint` to recommend a number of words to the user. This must include any language-specific 'sentence' separator characters (e.g. a space in english).", "placeholders": { "recommended": { @@ -3147,15 +3173,15 @@ "message": "یک نام مستعار ایمیل با یک سرویس ارسال خارجی ایجاد کنید." }, "forwarderDomainName": { - "message": "Email domain", + "message": "دامنه ایمیل", "description": "Labels the domain name email forwarder service option" }, "forwarderDomainNameHint": { - "message": "Choose a domain that is supported by the selected service", + "message": "دامنه‌ای را انتخاب کنید که توسط سرویس انتخاب شده پشتیبانی می‌شود", "description": "Guidance provided for email forwarding services that support multiple email domains." }, "forwarderError": { - "message": "$SERVICENAME$ error: $ERRORMESSAGE$", + "message": "$SERVICENAME$ خطا: $ERRORMESSAGE$", "description": "Reports an error returned by a forwarding service to the user.", "placeholders": { "servicename": { @@ -3169,11 +3195,11 @@ } }, "forwarderGeneratedBy": { - "message": "Generated by Bitwarden.", + "message": "تولید شده توسط Bitwarden.", "description": "Displayed with the address on the forwarding service's configuration screen." }, "forwarderGeneratedByWithWebsite": { - "message": "Website: $WEBSITE$. Generated by Bitwarden.", + "message": "وب‌سایت: $WEBSITE$. تولید شده توسط Bitwarden.", "description": "Displayed with the address on the forwarding service's configuration screen.", "placeholders": { "WEBSITE": { @@ -3183,7 +3209,7 @@ } }, "forwaderInvalidToken": { - "message": "Invalid $SERVICENAME$ API token", + "message": "توکن API نامعتبر برای $SERVICENAME$", "description": "Displayed when the user's API token is empty or rejected by the forwarding service.", "placeholders": { "servicename": { @@ -3193,7 +3219,7 @@ } }, "forwaderInvalidTokenWithMessage": { - "message": "Invalid $SERVICENAME$ API token: $ERRORMESSAGE$", + "message": "توکن API نامعتبر برای $SERVICENAME$: $ERRORMESSAGE$", "description": "Displayed when the user's API token is rejected by the forwarding service with an error message.", "placeholders": { "servicename": { @@ -3207,7 +3233,7 @@ } }, "forwaderInvalidOperation": { - "message": "$SERVICENAME$ refused your request. Please contact your service provider for assistance.", + "message": "$SERVICENAME$ درخواست شما را رد کرد. لطفاً برای دریافت کمک با ارائه‌دهنده سرویس خود تماس بگیرید.", "description": "Displayed when the user is forbidden from using the API by the forwarding service.", "placeholders": { "servicename": { @@ -3217,7 +3243,7 @@ } }, "forwaderInvalidOperationWithMessage": { - "message": "$SERVICENAME$ refused your request: $ERRORMESSAGE$", + "message": "$SERVICENAME$ درخواست شما را رد کرد: $ERRORMESSAGE$", "description": "Displayed when the user is forbidden from using the API by the forwarding service with an error message.", "placeholders": { "servicename": { @@ -3231,7 +3257,7 @@ } }, "forwarderNoAccountId": { - "message": "Unable to obtain $SERVICENAME$ masked email account ID.", + "message": "دریافت شناسه حساب ایمیل ماسک شده از $SERVICENAME$ امکان‌پذیر نیست.", "description": "Displayed when the forwarding service fails to return an account ID.", "placeholders": { "servicename": { @@ -3271,7 +3297,7 @@ } }, "forwarderUnknownForwarder": { - "message": "Unknown forwarder: '$SERVICENAME$'.", + "message": "فرواردکننده ناشناخته: $SERVICENAME$.", "description": "Displayed when the forwarding service is not supported.", "placeholders": { "servicename": { @@ -3360,34 +3386,34 @@ "message": "ارسال مجدد اعلان" }, "viewAllLogInOptions": { - "message": "View all log in options" + "message": "مشاهده همه گزینه‌های ورود به سیستم" }, "notificationSentDevice": { "message": "یک اعلان به دستگاه شما ارسال شده است." }, "notificationSentDevicePart1": { - "message": "Unlock Bitwarden on your device or on the" + "message": "قفل Bitwarden را در دستگاه خود یا در... باز کنید" }, "notificationSentDeviceAnchor": { - "message": "web app" + "message": "برنامه وب" }, "notificationSentDevicePart2": { - "message": "Make sure the Fingerprint phrase matches the one below before approving." + "message": "اطمینان حاصل کنید که عبارت اثر انگشت با عبارت زیر مطابقت دارد قبل از تأیید." }, "aNotificationWasSentToYourDevice": { - "message": "A notification was sent to your device" + "message": "یک اعلان به دستگاه شما ارسال شده است" }, "youWillBeNotifiedOnceTheRequestIsApproved": { - "message": "You will be notified once the request is approved" + "message": "به‌محض تأیید درخواست، به شما اطلاع داده خواهد شد" }, "needAnotherOptionV1": { - "message": "Need another option?" + "message": "به گزینه دیگری نیاز دارید؟" }, "loginInitiated": { "message": "ورود به سیستم آغاز شد" }, "logInRequestSent": { - "message": "Request sent" + "message": "درخواست ارسال شد" }, "exposedMasterPassword": { "message": "کلمه عبور اصلی افشا شده" @@ -3426,7 +3452,7 @@ "message": "نحوه پر کردن خودکار" }, "autofillSelectInfoWithCommand": { - "message": "Select an item from this screen, use the shortcut $COMMAND$, or explore other options in settings.", + "message": "یک مورد را از این صفحه انتخاب کنید، از میان‌بر $COMMAND$ استفاده کنید، یا گزینه‌های دیگر را در تنظیمات بررسی کنید.", "placeholders": { "command": { "content": "$1", @@ -3435,7 +3461,7 @@ } }, "autofillSelectInfoWithoutCommand": { - "message": "Select an item from this screen, or explore other options in settings." + "message": "یک مورد را از این صفحه انتخاب کنید یا گزینه‌های دیگر را در تنظیمات بررسی کنید." }, "gotIt": { "message": "متوجه شدم" @@ -3444,22 +3470,22 @@ "message": "تنظیمات پر کردن خودکار" }, "autofillKeyboardShortcutSectionTitle": { - "message": "Autofill shortcut" + "message": "میان‌بر پرکردن خودکار" }, "autofillKeyboardShortcutUpdateLabel": { - "message": "Change shortcut" + "message": "تغییر میان‌بر" }, "autofillKeyboardManagerShortcutsLabel": { - "message": "Manage shortcuts" + "message": "مدیریت میان‌برها" }, "autofillShortcut": { "message": "میانبر صفحه کلید پر کردن خودکار" }, "autofillLoginShortcutNotSet": { - "message": "The autofill login shortcut is not set. Change this in the browser's settings." + "message": "میان‌بر ورود خودکار تنظیم نشده است. این مورد را در تنظیمات مرورگر تغییر دهید." }, "autofillLoginShortcutText": { - "message": "The autofill login shortcut is $COMMAND$. Manage all shortcuts in the browser's settings.", + "message": "میان‌بر ورود خودکار $COMMAND$ است. همه میان‌برها را می‌توانید در تنظیمات مرورگر مدیریت کنید.", "placeholders": { "command": { "content": "$1", @@ -3480,16 +3506,16 @@ "message": "در پنجره جدید باز می‌شود" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "این دستگاه را به خاطر بسپار تا ورودهای بعدی بدون مشکل انجام شود" }, "deviceApprovalRequired": { "message": "تأیید دستگاه لازم است. یک روش تأیید انتخاب کنید:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "تأیید دستگاه لازم است" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "یکی از گزینه‌های تأیید زیر را انتخاب کنید" }, "rememberThisDevice": { "message": "این دستگاه را به خاطر بسپار" @@ -3519,13 +3545,13 @@ "message": "و به ساختن حساب‌تان ادامه دهید." }, "noEmail": { - "message": "No email?" + "message": "ایمیلی دریافت نکردید؟" }, "goBack": { - "message": "Go back" + "message": "بازگشت به عقب" }, "toEditYourEmailAddress": { - "message": "to edit your email address." + "message": "برای ویرایش آدرس ایمیل خود." }, "eu": { "message": "اروپا", @@ -3559,17 +3585,49 @@ "message": "ایمیل کاربر وجود ندارد" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "ایمیل کاربر فعال پیدا نشد. در حال خارج کردن شما از سیستم هستیم." }, "deviceTrusted": { "message": "دستگاه مورد اعتماد است" }, + "trustOrganization": { + "message": "اعتماد به سازمان" + }, + "trust": { + "message": "اطمینان" + }, + "doNotTrust": { + "message": "اعتماد نکنید" + }, + "organizationNotTrusted": { + "message": "سازمان مورد اعتماد نیست" + }, + "emergencyAccessTrustWarning": { + "message": "برای امنیت حساب کاربری شما، فقط در صورتی تأیید کنید که دسترسی اضطراری به این کاربر داده‌اید و اثر انگشت او با آنچه در حسابش نمایش داده شده، مطابقت دارد" + }, + "orgTrustWarning": { + "message": "برای امنیت حساب کاربری شما، فقط در صورتی ادامه دهید که عضو این سازمان باشید، بازیابی حساب کاربری را فعال کرده باشید و اثر انگشت نمایش داده شده در زیر با اثر انگشت سازمان مطابقت داشته باشد." + }, + "orgTrustWarning1": { + "message": "این سازمان دارای سیاست سازمانی است که شما را در بازیابی حساب کاربری ثبت‌نام می‌کند. ثبت‌نام به مدیران سازمان اجازه می‌دهد کلمه عبور شما را تغییر دهند. فقط در صورتی ادامه دهید که این سازمان را می‌شناسید و عبارت اثر انگشت نمایش داده شده در زیر با اثر انگشت سازمان مطابقت دارد." + }, + "trustUser": { + "message": "به کاربر اعتماد کنید" + }, "sendsNoItemsTitle": { - "message": "No active Sends", + "message": "ارسال‌های فعالی نیست", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendsNoItemsMessage": { - "message": "Use Send to securely share encrypted information with anyone.", + "message": "از ارسال برای اشتراک‌گذاری امن اطلاعات رمزگذاری شده با هر کسی استفاده کنید.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsTitleNoItems": { + "message": "اطلاعات حساس را به‌صورت ایمن ارسال کنید", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "پرونده‌ها و داده‌های خود را به‌صورت امن با هر کسی، در هر پلتفرمی به اشتراک بگذارید. اطلاعات شما در حین اشتراک‌گذاری به‌طور کامل رمزگذاری انتها به انتها باقی خواهد ماند و میزان افشا محدود می‌شود.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "inputRequired": { @@ -3646,10 +3704,10 @@ } }, "singleFieldNeedsAttention": { - "message": "1 field needs your attention." + "message": "۱ فیلد به توجه شما نیاز دارد." }, "multipleFieldsNeedAttention": { - "message": "$COUNT$ fields need your attention.", + "message": "فیلدهای $COUNT$ به توجه شما نیاز دارند.", "placeholders": { "count": { "content": "$1", @@ -3704,53 +3762,53 @@ "description": "Message appearing below the autofill on load message when master password reprompt is set for a vault item." }, "toggleSideNavigation": { - "message": "Toggle side navigation" + "message": "تغییر وضعیت ناوبری کناری" }, "skipToContent": { - "message": "Skip to content" + "message": "پرش به محتوا" }, "bitwardenOverlayButton": { - "message": "Bitwarden autofill menu button", + "message": "دکمه منوی پر کردن خودکار Bitwarden", "description": "Page title for the iframe containing the overlay button" }, "toggleBitwardenVaultOverlay": { - "message": "Toggle Bitwarden autofill menu", + "message": "نمایش یا مخفی کردن منوی پر کردن خودکار Bitwarden", "description": "Screen reader and tool tip label for the overlay button" }, "bitwardenVault": { - "message": "Bitwarden autofill menu", + "message": "منوی پر کردن خودکار Bitwarden", "description": "Page title in overlay" }, "unlockYourAccountToViewMatchingLogins": { - "message": "Unlock your account to view matching logins", + "message": "برای مشاهده ورودهای منطبق، قفل حساب کاربری خود را باز کنید", "description": "Text to display in overlay when the account is locked." }, "unlockYourAccountToViewAutofillSuggestions": { - "message": "Unlock your account to view autofill suggestions", + "message": "برای مشاهده پیشنهادهای پر کردن خودکار، قفل حساب کاربری خود را باز کنید", "description": "Text to display in overlay when the account is locked." }, "unlockAccount": { - "message": "Unlock account", + "message": "قفل حساب کاربری را باز کنید", "description": "Button text to display in overlay when the account is locked." }, "unlockAccountAria": { - "message": "Unlock your account, opens in a new window", + "message": "قفل حساب کاربری خود را باز کنید، در پنجره‌ای جدید باز می‌شود", "description": "Screen reader text (aria-label) for unlock account button in overlay" }, "totpCodeAria": { - "message": "Time-based One-Time Password Verification Code", + "message": "کد تأیید رمز یک‌بار مصرف مبتنی بر زمان", "description": "Aria label for the totp code displayed in the inline menu for autofill" }, "totpSecondsSpanAria": { - "message": "Time remaining before current TOTP expires", + "message": "زمان باقی‌مانده تا انقضای کد TOTP فعلی", "description": "Aria label for the totp seconds displayed in the inline menu for autofill" }, "fillCredentialsFor": { - "message": "Fill credentials for", + "message": "پر کردن اطلاعات ورود برای", "description": "Screen reader text for when overlay item is in focused" }, "partialUsername": { - "message": "Partial username", + "message": "نام کاربری جزئی", "description": "Screen reader text for when a login item is focused where a partial username is displayed. SR will announce this phrase before reading the text of the partial username" }, "noItemsToShow": { @@ -3766,31 +3824,31 @@ "description": "Screen reader text (aria-label) for new item button in overlay" }, "newLogin": { - "message": "New login", + "message": "ورود جدید", "description": "Button text to display within inline menu when there are no matching items on a login field" }, "addNewLoginItemAria": { - "message": "Add new vault login item, opens in a new window", + "message": "افزودن مورد ورود جدید به گاوصندوق، در پنجره‌ای جدید باز می‌شود", "description": "Screen reader text (aria-label) for new login button within inline menu" }, "newCard": { - "message": "New card", + "message": "کارت جدید", "description": "Button text to display within inline menu when there are no matching items on a credit card field" }, "addNewCardItemAria": { - "message": "Add new vault card item, opens in a new window", + "message": "افزودن کارت جدید به گاوصندوق، در پنجره‌ای جدید باز می‌شود", "description": "Screen reader text (aria-label) for new card button within inline menu" }, "newIdentity": { - "message": "New identity", + "message": "هویت جدید", "description": "Button text to display within inline menu when there are no matching items on an identity field" }, "addNewIdentityItemAria": { - "message": "Add new vault identity item, opens in a new window", + "message": "افزودن هویت جدید به گاوصندوق، در پنجره‌ای جدید باز می‌شود", "description": "Screen reader text (aria-label) for new identity button within inline menu" }, "bitwardenOverlayMenuAvailable": { - "message": "Bitwarden autofill menu available. Press the down arrow key to select.", + "message": "منوی پر کردن خودکار Bitwarden در دسترس است. برای انتخاب، کلید فلش پایین را فشار دهید.", "description": "Screen reader text for announcing when the overlay opens on the page" }, "turnOn": { @@ -3804,13 +3862,13 @@ "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" }, "importError": { - "message": "خطای وارد کردن" + "message": "خطای درون ریزی" }, "importErrorDesc": { "message": "مشکلی با داده‌هایی که سعی کردید وارد کنید وجود داشت. لطفاً خطاهای فهرست شده زیر را در فایل منبع خود برطرف کرده و دوباره امتحان کنید." }, "resolveTheErrorsBelowAndTryAgain": { - "message": "Resolve the errors below and try again." + "message": "خطاهای زیر را برطرف کرده و دوباره امتحان کنید." }, "description": { "message": "توضیحات" @@ -3831,10 +3889,10 @@ "message": "دوباره سعی کنید" }, "verificationRequiredForActionSetPinToContinue": { - "message": "Verification required for this action. Set a PIN to continue." + "message": "برای این اقدام تأیید لازم است. یک کد پین تعیین کنید تا ادامه دهید." }, "setPin": { - "message": "تنظیم PIN" + "message": "تنظیم کد پین" }, "verifyWithBiometrics": { "message": "تایید با استفاده از بیومتریک" @@ -3849,25 +3907,25 @@ "message": "نیازمند روش دیگری هستید؟" }, "useMasterPassword": { - "message": "استفاده از رمز عبور اصلی" + "message": "استفاده از کلمه عبور اصلی" }, "usePin": { - "message": "استفاده از PIN" + "message": "استفاده از کد پین" }, "useBiometrics": { "message": "استفاده از بیومتریک" }, "enterVerificationCodeSentToEmail": { - "message": "Enter the verification code that was sent to your email." + "message": "کد تأییدی را که به ایمیل شما ارسال شده است وارد کنید." }, "resendCode": { - "message": "Resend code" + "message": "ارسال دوباره کد" }, "total": { "message": "مجموع" }, "importWarning": { - "message": "You are importing data to $ORGANIZATION$. Your data may be shared with members of this organization. Do you want to proceed?", + "message": "شما در حال درون ریزی داده به $ORGANIZATION$ هستید. داده‌های شما ممکن است با اعضای این سازمان به اشتراک گذاشته شود. آیا می‌خواهید ادامه دهید؟", "placeholders": { "organization": { "content": "$1", @@ -3876,13 +3934,13 @@ } }, "duoHealthCheckResultsInNullAuthUrlError": { - "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." + "message": "خطا در اتصال به سرویس Duo. از روش ورود دو مرحله‌ای دیگری استفاده کنید یا برای دریافت کمک با Duo تماس بگیرید." }, "duoRequiredForAccount": { - "message": "Duo two-step login is required for your account." + "message": "ورود دو مرحله ای Duo برای حساب کاربری شما لازم است." }, "popoutExtension": { - "message": "Popout extension" + "message": "باز کردن پنجره جداگانه افزونه" }, "launchDuo": { "message": "اجرای Duo" @@ -3894,25 +3952,25 @@ "message": "چیزی وارد نشد." }, "importEncKeyError": { - "message": "Error decrypting the exported file. Your encryption key does not match the encryption key used export the data." + "message": "خطا در رمزگشایی پرونده‌ی درون ریزی شده. کلید رمزگذاری شما با کلید رمزگذاری استفاده شده برای درون ریزی داده‌ها مطابقت ندارد." }, "invalidFilePassword": { - "message": "Invalid file password, please use the password you entered when you created the export file." + "message": "کلمه عبور پرونده نامعتبر است، لطفاً از کلمه عبوری که هنگام ایجاد پرونده‌ی برون ریزی وارد کردید استفاده کنید." }, "destination": { - "message": "Destination" + "message": "مقصد" }, "learnAboutImportOptions": { - "message": "Learn about your import options" + "message": "درباره گزینه‌های برون ریزی خود بیاموزید" }, "selectImportFolder": { "message": "یک پوشه انتخاب کنید" }, "selectImportCollection": { - "message": "Select a collection" + "message": "انتخاب یک مجموعه" }, "importTargetHint": { - "message": "Select this option if you want the imported file contents moved to a $DESTINATION$", + "message": "اگر می‌خواهید محتوای فایل وارد شده به $DESTINATION$ منتقل شود، این گزینه را انتخاب کنید", "description": "Located as a hint under the import target. Will be appended by either folder or collection, depending if the user is importing into an individual or an organizational vault.", "placeholders": { "destination": { @@ -3922,25 +3980,25 @@ } }, "importUnassignedItemsError": { - "message": "File contains unassigned items." + "message": "پرونده حاوی موارد اختصاص نیافته است." }, "selectFormat": { - "message": "Select the format of the import file" + "message": "فرمت پرونده‌ی درون ریزی را انتخاب کنید" }, "selectImportFile": { - "message": "Select the import file" + "message": "پرونده‌ی درون ریزی را انتخاب کنید" }, "chooseFile": { - "message": "Choose File" + "message": "انتخاب پرونده" }, "noFileChosen": { - "message": "No file chosen" + "message": "هیچ پرونده‌ای انتخاب نشد" }, "orCopyPasteFileContents": { - "message": "or copy/paste the import file contents" + "message": "یا محتویات پرونده‌ی درون ریزی را کپی/پیست کنید" }, "instructionsFor": { - "message": "$NAME$ Instructions", + "message": "دستورالعمل‌های $NAME$", "description": "The title for the import tool instructions.", "placeholders": { "name": { @@ -3950,25 +4008,25 @@ } }, "confirmVaultImport": { - "message": "Confirm vault import" + "message": "درون ریزی گاوصندوق را تأیید کنید" }, "confirmVaultImportDesc": { - "message": "This file is password-protected. Please enter the file password to import data." + "message": "این پرونده با کلمه عبور محافظت شده است. لطفاً کلمه عبور پرونده را برای درون ریزی داده‌ها وارد کنید." }, "confirmFilePassword": { - "message": "Confirm file password" + "message": "تأیید کلمه عبور پرونده" }, "exportSuccess": { - "message": "Vault data exported" + "message": "داده های گاوصندوق برون ریزی شد" }, "typePasskey": { - "message": "Passkey" + "message": "کلید عبور" }, "accessing": { - "message": "Accessing" + "message": "در حال دسترسی" }, "loggedInExclamation": { - "message": "Logged in!" + "message": "وارد شده!" }, "passkeyNotCopied": { "message": "کلید عبور کپی نمی‌شود" @@ -3980,7 +4038,7 @@ "message": "تأیید توسط سایت آغازگر الزامی است. این ویژگی هنوز برای حساب‌های بدون کلمه عبور اصلی اجرا نشده است." }, "logInWithPasskeyQuestion": { - "message": "Log in with passkey?" + "message": "با کلید عبور وارد می‌شوید؟" }, "passkeyAlreadyExists": { "message": "یک کلید عبور از قبل برای این برنامه وجود دارد." @@ -3992,10 +4050,10 @@ "message": "شما هیچ ورود مشابهی برای این سایت ندارید." }, "noMatchingLoginsForSite": { - "message": "No matching logins for this site" + "message": "ورود منطبق برای این سایت یافت نشد" }, "searchSavePasskeyNewLogin": { - "message": "Search or save passkey as new login" + "message": "جستجو یا ذخیره کلید عبور به عنوان ورود جدید" }, "confirm": { "message": "تأیید" @@ -4007,10 +4065,10 @@ "message": "کلید عبور را به عنوان ورود جدید ذخیره کن" }, "chooseCipherForPasskeySave": { - "message": "Choose a login to save this passkey to" + "message": "یک ورود برای ذخیره این کلید عبور انتخاب کنید" }, "chooseCipherForPasskeyAuth": { - "message": "Choose a passkey to log in with" + "message": "یک کلید عبور برای ورود انتخاب کنید" }, "passkeyItem": { "message": "مورد کلید عبور" @@ -4028,125 +4086,125 @@ "message": "برای استفاده از کلید عبور، احراز هویت لازم است. برای ادامه، هویت خود را تأیید کنید." }, "multifactorAuthenticationCancelled": { - "message": "Multifactor authentication cancelled" + "message": "تأیید هویت چند مرحله‌ای کنسل شد" }, "noLastPassDataFound": { - "message": "No LastPass data found" + "message": "هیچ داده‌ای از LastPass یافت نشد" }, "incorrectUsernameOrPassword": { - "message": "Incorrect username or password" + "message": "نام کاربری یا کلمه عبور اشتباه است" }, "incorrectPassword": { - "message": "Incorrect password" + "message": "کلمه عبور اشتباه است" }, "incorrectCode": { - "message": "Incorrect code" + "message": "کد اشتباه است" }, "incorrectPin": { - "message": "Incorrect PIN" + "message": "کد پین نادرست است" }, "multifactorAuthenticationFailed": { - "message": "Multifactor authentication failed" + "message": "احراز هویت چند مرحله‌ای ناموفق بود" }, "includeSharedFolders": { - "message": "Include shared folders" + "message": "شامل پوشه‌های به‌ اشتراک گذاری‌ شده" }, "lastPassEmail": { - "message": "LastPass Email" + "message": "ایمیل LastPass" }, "importingYourAccount": { - "message": "Importing your account..." + "message": "در حال درون ریزی حساب کاربری شما..." }, "lastPassMFARequired": { - "message": "LastPass multifactor authentication required" + "message": "احراز هویت چند مرحله‌ای LastPass مورد نیاز است" }, "lastPassMFADesc": { - "message": "Enter your one-time passcode from your authentication app" + "message": "کد یک‌بار مصرف خود را از برنامه احراز هویت وارد کنید" }, "lastPassOOBDesc": { - "message": "Approve the login request in your authentication app or enter a one-time passcode." + "message": "درخواست ورود را در برنامه احراز هویت خود تأیید کنید یا یک کد یک‌بار مصرف وارد کنید." }, "passcode": { - "message": "Passcode" + "message": "کد عبور" }, "lastPassMasterPassword": { - "message": "LastPass master password" + "message": "کلمه عبور اصلی LastPass" }, "lastPassAuthRequired": { - "message": "LastPass authentication required" + "message": "احراز هویت LastPass مورد نیاز است" }, "awaitingSSO": { - "message": "Awaiting SSO authentication" + "message": "در انتظار احراز هویت SSO" }, "awaitingSSODesc": { - "message": "Please continue to log in using your company credentials." + "message": "لطفاً برای ورود، از اطلاعات کاربری شرکت خود استفاده کنید." }, "seeDetailedInstructions": { - "message": "See detailed instructions on our help site at", + "message": "دستورالعمل‌های کامل را در سایت راهنمای ما مشاهده کنید در", "description": "This is followed a by a hyperlink to the help website." }, "importDirectlyFromLastPass": { - "message": "Import directly from LastPass" + "message": "درون ریزی مستقیم از LastPass" }, "importFromCSV": { - "message": "Import from CSV" + "message": "درون ریزی از CSV" }, "lastPassTryAgainCheckEmail": { - "message": "Try again or look for an email from LastPass to verify it's you." + "message": "دوباره تلاش کنید یا ایمیلی از LastPass را بررسی کنید تا هویت شما تأیید شود." }, "collection": { - "message": "Collection" + "message": "مجموعه" }, "lastPassYubikeyDesc": { - "message": "Insert the YubiKey associated with your LastPass account into your computer's USB port, then touch its button." + "message": "کلید YubiKey مربوط به حساب کاربری LastPass خود را در درگاه USB کامپیوتر قرار دهید، سپس دکمه آن را لمس کنید." }, "switchAccount": { - "message": "Switch account" + "message": "تعویض حساب کاربری" }, "switchAccounts": { - "message": "Switch accounts" + "message": "تعویض حساب‌ها" }, "switchToAccount": { - "message": "Switch to account" + "message": "تعویض به حساب کاربری" }, "activeAccount": { - "message": "Active account" + "message": "حساب کاربری فعال" }, "bitwardenAccount": { - "message": "Bitwarden account" + "message": "حساب کاربری Bitwarden" }, "availableAccounts": { - "message": "Available accounts" + "message": "حساب کاربری در درسترس" }, "accountLimitReached": { - "message": "Account limit reached. Log out of an account to add another." + "message": "محدودیت حساب کاربری تکمیل شد. برای افزودن حساب کاربری دیگر، از یک حساب خارج شوید." }, "active": { - "message": "active" + "message": "فعال" }, "locked": { - "message": "locked" + "message": "قفل شد" }, "unlocked": { - "message": "unlocked" + "message": "باز شد" }, "server": { - "message": "server" + "message": "سرور" }, "hostedAt": { - "message": "hosted at" + "message": "میزبانی شده در" }, "useDeviceOrHardwareKey": { - "message": "Use your device or hardware key" + "message": "از دستگاه یا کلید سخت‌افزاری خود استفاده کنید" }, "justOnce": { - "message": "Just once" + "message": "فقط یک بار" }, "alwaysForThisSite": { - "message": "Always for this site" + "message": "همیشه برای این سایت" }, "domainAddedToExcludedDomains": { - "message": "$DOMAIN$ added to excluded domains.", + "message": "دامنه $DOMAIN$ به دامنه‌های مستثنی اضافه شد.", "placeholders": { "domain": { "content": "$1", @@ -4155,106 +4213,106 @@ } }, "commonImportFormats": { - "message": "Common formats", + "message": "فرمت‌های رایج", "description": "Label indicating the most common import formats" }, "confirmContinueToBrowserSettingsTitle": { - "message": "Continue to browser settings?", + "message": "ادامه به تنظیمات مرورگر؟", "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" }, "confirmContinueToHelpCenter": { - "message": "Continue to Help Center?", + "message": "به مرکز راهنمایی ادامه می‌دهید؟", "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" }, "confirmContinueToHelpCenterPasswordManagementContent": { - "message": "Change your browser's autofill and password management settings.", + "message": "تنظیمات پر کردن خودکار و مدیریت کلمه عبور مرورگر خود را تغییر دهید.", "description": "Body content for dialog which asks if the user wants to proceed to the Help Center's page about browser password management settings" }, "confirmContinueToHelpCenterKeyboardShortcutsContent": { - "message": "You can view and set extension shortcuts in your browser's settings.", + "message": "می‌توانید میان‌برهای افزونه را در تنظیمات مرورگر خود مشاهده و تنظیم کنید.", "description": "Body content for dialog which asks if the user wants to proceed to the Help Center's page about browser keyboard shortcut settings" }, "confirmContinueToBrowserPasswordManagementSettingsContent": { - "message": "Change your browser's autofill and password management settings.", + "message": "تنظیمات پر کردن خودکار و مدیریت کلمه عبور مرورگر خود را تغییر دهید.", "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" }, "confirmContinueToBrowserKeyboardShortcutSettingsContent": { - "message": "You can view and set extension shortcuts in your browser's settings.", + "message": "می‌توانید میان‌برهای افزونه را در تنظیمات مرورگر خود مشاهده و تنظیم کنید.", "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" }, "overrideDefaultBrowserAutofillTitle": { - "message": "Make Bitwarden your default password manager?", + "message": "می‌خواهید Bitwarden را مدیر کلمه عبور پیش‌فرض خود کنید؟", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", + "message": "نادیده گرفتن این گزینه ممکن است باعث تداخل بین پیشنهادهای پر کردن خودکار Bitwarden و مرورگر شما شود.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { - "message": "Make Bitwarden your default password manager", + "message": "Bitwarden را به عنوان مدیر کلمه عبور پیش‌فرض خود تنظیم کنید", "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": "امکان تنظیم Bitwarden به‌عنوان مدیر کلمه عبور پیش‌فرض وجود ندارد", "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": "برای تنظیم Bitwarden به‌عنوان مدیر کلمه عبور پیش‌فرض، باید دسترسی‌های حفظ حریم خصوصی مرورگر را به آن بدهید.", "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": "تنظیم به‌عنوان پیش‌فرض", "description": "Button text for the setting that allows overriding the default browser autofill settings" }, "saveCipherAttemptSuccess": { - "message": "Credentials saved successfully!", + "message": "اطلاعات ورود با موفقیت ذخیره شد!", "description": "Notification message for when saving credentials has succeeded." }, "passwordSaved": { - "message": "Password saved!", + "message": "کلمه عبور ذخیره شد!", "description": "Notification message for when saving credentials has succeeded." }, "updateCipherAttemptSuccess": { - "message": "Credentials updated successfully!", + "message": "اطلاعات ورود با موفقیت به‌روزرسانی شد!", "description": "Notification message for when updating credentials has succeeded." }, "passwordUpdated": { - "message": "Password updated!", + "message": "کلمه عبور به‌روزرسانی شد!", "description": "Notification message for when updating credentials has succeeded." }, "saveCipherAttemptFailed": { - "message": "Error saving credentials. Check console for details.", + "message": "خطا در ذخیره اطلاعات ورود. جزئیات را در کنسول بررسی کنید.", "description": "Notification message for when saving credentials has failed." }, "success": { - "message": "Success" + "message": "موفقیت آمیز بود" }, "removePasskey": { - "message": "Remove passkey" + "message": "حذف کلید عبور" }, "passkeyRemoved": { - "message": "Passkey removed" + "message": "کلید عبور حذف شد" }, "autofillSuggestions": { - "message": "Autofill suggestions" + "message": "پیشنهادهای پر کردن خودکار" }, "itemSuggestions": { - "message": "Suggested items" + "message": "موارد پیشنهادی" }, "autofillSuggestionsTip": { - "message": "Save a login item for this site to autofill" + "message": "یک مورد ورود برای این سایت ذخیره کنید تا به‌صورت خودکار پر شود" }, "yourVaultIsEmpty": { - "message": "Your vault is empty" + "message": "گاوصندوق‌تان خالی است" }, "noItemsMatchSearch": { - "message": "No items match your search" + "message": "موردی با جستجوی شما مطابقت نداشت" }, "clearFiltersOrTryAnother": { - "message": "Clear filters or try another search term" + "message": "فیلترها را پاک کنید یا عبارت جستجوی دیگری را امتحان کنید" }, "copyInfoTitle": { - "message": "Copy info - $ITEMNAME$", + "message": "کپی اطلاعات - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", "placeholders": { "itemname": { @@ -4264,7 +4322,7 @@ } }, "copyNoteTitle": { - "message": "Copy Note - $ITEMNAME$", + "message": "کپی یادداشت - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", "placeholders": { "itemname": { @@ -4274,7 +4332,7 @@ } }, "moreOptionsLabel": { - "message": "More options, $ITEMNAME$", + "message": "گزینه‌های بیشتر، $ITEMNAME$", "description": "Aria label for a button that opens a menu with more options for an item.", "placeholders": { "itemname": { @@ -4284,7 +4342,7 @@ } }, "moreOptionsTitle": { - "message": "More options - $ITEMNAME$", + "message": "گزینه‌های بیشتر - $ITEMNAME$", "description": "Title for a button that opens a menu with more options for an item.", "placeholders": { "itemname": { @@ -4294,7 +4352,7 @@ } }, "viewItemTitle": { - "message": "View item - $ITEMNAME$", + "message": "مشاهده آیتم - $ITEMNAME$", "description": "Title for a link that opens a view for an item.", "placeholders": { "itemname": { @@ -4304,7 +4362,7 @@ } }, "viewItemTitleWithField": { - "message": "View item - $ITEMNAME$ - $FIELD$", + "message": "مشاهده مورد - $ITEMNAME$ - $FIELD$", "description": "Title for a link that opens a view for an item.", "placeholders": { "itemname": { @@ -4318,7 +4376,7 @@ } }, "autofillTitle": { - "message": "Autofill - $ITEMNAME$", + "message": "پر کردن خودکار - $ITEMNAME$", "description": "Title for a button that autofills a login item.", "placeholders": { "itemname": { @@ -4328,7 +4386,7 @@ } }, "autofillTitleWithField": { - "message": "Autofill - $ITEMNAME$ - $FIELD$", + "message": "پر کردن خودکار - $ITEMNAME$ - $FIELD$", "description": "Title for a button that autofills a login item.", "placeholders": { "itemname": { @@ -4342,7 +4400,7 @@ } }, "copyFieldValue": { - "message": "Copy $FIELD$, $VALUE$", + "message": "کپی $FIELD$، $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", "placeholders": { "field": { @@ -4356,40 +4414,40 @@ } }, "noValuesToCopy": { - "message": "No values to copy" + "message": "هیچ مقداری برای کپی وجود ندارد" }, "assignToCollections": { - "message": "Assign to collections" + "message": "اختصاص به مجموعه‌ها" }, "copyEmail": { - "message": "Copy email" + "message": "کپی ایمیل" }, "copyPhone": { - "message": "Copy phone" + "message": "کپی تلفن" }, "copyAddress": { - "message": "Copy address" + "message": "کپی آدرس" }, "adminConsole": { - "message": "Admin Console" + "message": "کنسول مدیر" }, "accountSecurity": { - "message": "Account security" + "message": "امنیت حساب کاربری" }, "notifications": { - "message": "Notifications" + "message": "اعلان‌ها" }, "appearance": { - "message": "Appearance" + "message": "ظاهر" }, "errorAssigningTargetCollection": { - "message": "Error assigning target collection." + "message": "خطا در اختصاص مجموعه هدف." }, "errorAssigningTargetFolder": { - "message": "Error assigning target folder." + "message": "خطا در اختصاص پوشه هدف." }, "viewItemsIn": { - "message": "View items in $NAME$", + "message": "مشاهده موارد در $NAME$", "description": "Button to view the contents of a folder or collection", "placeholders": { "name": { @@ -4399,7 +4457,7 @@ } }, "backTo": { - "message": "Back to $NAME$", + "message": "بازگشت به $NAME$", "description": "Navigate back to a previous folder or collection", "placeholders": { "name": { @@ -4409,10 +4467,10 @@ } }, "new": { - "message": "New" + "message": "جدید" }, "removeItem": { - "message": "Remove $NAME$", + "message": "حذف $NAME$", "description": "Remove a selected option, such as a folder or collection", "placeholders": { "name": { @@ -4422,56 +4480,56 @@ } }, "itemsWithNoFolder": { - "message": "Items with no folder" + "message": "موارد بدون پوشه" }, "itemDetails": { - "message": "Item details" + "message": "جزئیات مورد" }, "itemName": { - "message": "Item name" + "message": "نام مورد" }, "organizationIsDeactivated": { - "message": "Organization is deactivated" + "message": "سازمان غیرفعال شده است" }, "owner": { - "message": "Owner" + "message": "مالک" }, "selfOwnershipLabel": { - "message": "You", + "message": "شما", "description": "Used as a label to indicate that the user is the owner of an item." }, "contactYourOrgAdmin": { - "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." + "message": "به موردهای موجود در سازمان‌های غیرفعال نمی‌توان دسترسی داشت. برای دریافت کمک با مالک سازمان تماس بگیرید." }, "additionalInformation": { - "message": "Additional information" + "message": "اطلاعات بیشتر" }, "itemHistory": { - "message": "Item history" + "message": "تاریخچه مورد" }, "lastEdited": { - "message": "Last edited" + "message": "آخرین ویرایش" }, "ownerYou": { - "message": "Owner: You" + "message": "مالک: شما" }, "linked": { - "message": "Linked" + "message": "پیوند شده" }, "copySuccessful": { - "message": "Copy Successful" + "message": "کپی موفق بود" }, "upload": { - "message": "Upload" + "message": "بارگذاری" }, "addAttachment": { - "message": "Add attachment" + "message": "افزودن پیوست" }, "maxFileSizeSansPunctuation": { - "message": "Maximum file size is 500 MB" + "message": "بیشترین حجم پرونده ۵۰۰ مگابایت است" }, "deleteAttachmentName": { - "message": "Delete attachment $NAME$", + "message": "حذف پیوست $NAME$", "placeholders": { "name": { "content": "$1", @@ -4480,7 +4538,7 @@ } }, "downloadAttachmentName": { - "message": "Download $NAME$", + "message": "بارگیری $NAME$", "placeholders": { "name": { "content": "$1", @@ -4488,26 +4546,53 @@ } } }, + "downloadBitwarden": { + "message": "بارگیری Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Bitwarden را روی همه دستگاه‌ها بارگیری کنید" + }, + "getTheMobileApp": { + "message": "دریافت برنامه‌ی تلفن همراه" + }, + "getTheMobileAppDesc": { + "message": "با برنامه موبایل Bitwarden، به کلمات عبور خود در هر زمان و مکان دسترسی داشته باشید." + }, + "getTheDesktopApp": { + "message": "برنامه دسکتاپ را دریافت کنید" + }, + "getTheDesktopAppDesc": { + "message": "بدون استفاده از مرورگر به گاوصندوق خود دسترسی پیدا کنید و سپس باز کردن قفل با بیومتریک را تنظیم کنید تا باز کردن سریع‌تر قفل در اپ دسکتاپ و افزونه مرورگر انجام شود." + }, + "downloadFromBitwardenNow": { + "message": "هم‌اکنون از bitwarden.com بارگیری کنید" + }, + "getItOnGooglePlay": { + "message": "از Google Play دریافت کنید" + }, + "downloadOnTheAppStore": { + "message": "از AppStore بارگیری کنید" + }, "permanentlyDeleteAttachmentConfirmation": { - "message": "Are you sure you want to permanently delete this attachment?" + "message": "آیا مطمئن هستید که می‌خواهید این پرونده پیوست را به‌طور دائمی حذف کنید؟" }, "premium": { - "message": "Premium" + "message": "پرمیوم" }, "freeOrgsCannotUseAttachments": { - "message": "Free organizations cannot use attachments" + "message": "سازمان‌های رایگان نمی‌توانند از پرونده‌های پیوست استفاده کنند" }, "filters": { - "message": "Filters" + "message": "فیلترها" }, "filterVault": { - "message": "Filter vault" + "message": "فیلتر گاوصندوق" }, "filterApplied": { - "message": "One filter applied" + "message": "یک فیلتر اعمال شده است" }, "filterAppliedPlural": { - "message": "$COUNT$ filters applied", + "message": "$COUNT$ فیلتر اعمال شده است", "placeholders": { "count": { "content": "$1", @@ -4516,16 +4601,16 @@ } }, "personalDetails": { - "message": "Personal details" + "message": "جزئیات شخصی" }, "identification": { - "message": "Identification" + "message": "شناسایی" }, "contactInfo": { - "message": "Contact info" + "message": "اطلاعات مخاطب" }, "downloadAttachment": { - "message": "Download - $ITEMNAME$", + "message": "بارگیری - $ITEMNAME$", "placeholders": { "itemname": { "content": "$1", @@ -4534,23 +4619,23 @@ } }, "cardNumberEndsWith": { - "message": "card number ends with", + "message": "شماره کارت پایان می‌یابد با", "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." }, "loginCredentials": { - "message": "Login credentials" + "message": "اطلاعات ورود" }, "authenticatorKey": { - "message": "Authenticator key" + "message": "کلید احراز هویت" }, "autofillOptions": { - "message": "Autofill options" + "message": "گزینه‌های پر کردن خودکار" }, "websiteUri": { - "message": "Website (URI)" + "message": "وب‌سایت (نشانی اینترنتی)" }, "websiteUriCount": { - "message": "Website (URI) $COUNT$", + "message": "وب‌سایت (نشانی اینترنتی) $COUNT$", "description": "Label for an input field that contains a website URI. The input field is part of a list of fields, and the count indicates the position of the field in the list.", "placeholders": { "count": { @@ -4560,16 +4645,16 @@ } }, "websiteAdded": { - "message": "Website added" + "message": "وب‌سایت اضافه شد" }, "addWebsite": { - "message": "Add website" + "message": "افزودن وب‌سایت" }, "deleteWebsite": { - "message": "Delete website" + "message": "حذف وبسایت" }, "defaultLabel": { - "message": "Default ($VALUE$)", + "message": "پیش‌فرض ($VALUE$)", "description": "A label that indicates the default value for a field with the current default value in parentheses.", "placeholders": { "value": { @@ -4579,7 +4664,7 @@ } }, "showMatchDetection": { - "message": "Show match detection $WEBSITE$", + "message": "نمایش تطبیق سایت $WEBSITE$", "placeholders": { "website": { "content": "$1", @@ -4588,7 +4673,7 @@ } }, "hideMatchDetection": { - "message": "Hide match detection $WEBSITE$", + "message": "مخفی کردن تطبیق سایت $WEBSITE$", "placeholders": { "website": { "content": "$1", @@ -4597,19 +4682,19 @@ } }, "autoFillOnPageLoad": { - "message": "Autofill on page load?" + "message": "پر کردن خودکار هنگام بارگذاری صفحه؟" }, "cardExpiredTitle": { - "message": "Expired card" + "message": "تاریخ کارت منقضی شده است" }, "cardExpiredMessage": { - "message": "If you've renewed it, update the card's information" + "message": "اگر تمدید کرده‌اید، اطلاعات کارت را به‌روزرسانی کنید" }, "cardDetails": { - "message": "Card details" + "message": "جزئیات کارت" }, "cardBrandDetails": { - "message": "$BRAND$ details", + "message": "$BRAND$ جزئیات", "placeholders": { "brand": { "content": "$1", @@ -4618,43 +4703,43 @@ } }, "enableAnimations": { - "message": "Enable animations" + "message": "فعال‌سازی انیمیشن‌ها" }, "showAnimations": { - "message": "Show animations" + "message": "نمایش انیمیشن‌ها" }, "addAccount": { - "message": "Add account" + "message": "افزودن حساب کاربری" }, "loading": { - "message": "Loading" + "message": "در حال بارگذاری" }, "data": { - "message": "Data" + "message": "داده‌" }, "passkeys": { - "message": "Passkeys", + "message": "کلیدهای عبور", "description": "A section header for a list of passkeys." }, "passwords": { - "message": "Passwords", + "message": "کلمات عبور", "description": "A section header for a list of passwords." }, "logInWithPasskeyAriaLabel": { - "message": "Log in with passkey", + "message": "با کلید عبور وارد شوید", "description": "ARIA label for the inline menu button that logs in with a passkey." }, "assign": { - "message": "Assign" + "message": "اختصاص بدهید" }, "bulkCollectionAssignmentDialogDescriptionSingular": { - "message": "Only organization members with access to these collections will be able to see the item." + "message": "فقط اعضای سازمانی که به این مجموعه‌ها دسترسی دارند قادر به مشاهده این مورد خواهند بود." }, "bulkCollectionAssignmentDialogDescriptionPlural": { - "message": "Only organization members with access to these collections will be able to see the items." + "message": "فقط اعضای سازمانی که به این مجموعه‌ها دسترسی دارند قادر به مشاهده این موارد خواهند بود." }, "bulkCollectionAssignmentWarning": { - "message": "You have selected $TOTAL_COUNT$ items. You cannot update $READONLY_COUNT$ of the items because you do not have edit permissions.", + "message": "شما $TOTAL_COUNT$ مورد را انتخاب کرده‌اید. نمی‌توانید $READONLY_COUNT$ مورد را به‌روزرسانی کنید زیرا دسترسی ویرایش ندارید.", "placeholders": { "total_count": { "content": "$1", @@ -4666,37 +4751,37 @@ } }, "addField": { - "message": "Add field" + "message": "افزودن فیلد" }, "add": { - "message": "Add" + "message": "افزودن" }, "fieldType": { - "message": "Field type" + "message": "نوع فیلد" }, "fieldLabel": { - "message": "Field label" + "message": "برچسب فیلد" }, "textHelpText": { - "message": "Use text fields for data like security questions" + "message": "برای داده‌هایی مانند سوالات امنیتی از فیلدهای متنی استفاده کنید" }, "hiddenHelpText": { - "message": "Use hidden fields for sensitive data like a password" + "message": "برای داده‌های حساس مانند کلمه عبور از فیلدهای مخفی استفاده کنید" }, "checkBoxHelpText": { - "message": "Use checkboxes if you'd like to autofill a form's checkbox, like a remember email" + "message": "اگر می‌خواهید فیلدهای تیک‌دار فرم را به‌صورت خودکار پر کنید، مانند گزینه به یاد سپردن ایمیل، از کادرهای انتخاب استفاده کنید" }, "linkedHelpText": { - "message": "Use a linked field when you are experiencing autofill issues for a specific website." + "message": "وقتی در پر کردن خودکار برای یک وب‌سایت خاص به مشکل برخوردید، از فیلد مرتبط استفاده کنید." }, "linkedLabelHelpText": { - "message": "Enter the the field's html id, name, aria-label, or placeholder." + "message": "شناسه Html، نام، aria-label یا محل نگهدار فیلد را وارد کنید." }, "editField": { - "message": "Edit field" + "message": "ویرایش فیلد" }, "editFieldLabel": { - "message": "Edit $LABEL$", + "message": "ویرایش $LABEL$", "placeholders": { "label": { "content": "$1", @@ -4705,7 +4790,7 @@ } }, "deleteCustomField": { - "message": "Delete $LABEL$", + "message": "حذف $LABEL$", "placeholders": { "label": { "content": "$1", @@ -4714,7 +4799,7 @@ } }, "fieldAdded": { - "message": "$LABEL$ added", + "message": "$LABEL$ افزوده شد", "placeholders": { "label": { "content": "$1", @@ -4723,7 +4808,7 @@ } }, "reorderToggleButton": { - "message": "Reorder $LABEL$. Use arrow key to move item up or down.", + "message": "مرتب‌سازی مجدد $LABEL$. برای جابجایی مورد به بالا یا پایین از کلیدهای جهت‌نما استفاده کنید.", "placeholders": { "label": { "content": "$1", @@ -4732,10 +4817,10 @@ } }, "reorderWebsiteUriButton": { - "message": "Reorder website URI. Use arrow key to move item up or down." + "message": "مرتب‌سازی مجدد نشانی اینترنتی وب‌سایت. برای جابجایی مورد به بالا یا پایین از کلیدهای جهت‌نما استفاده کنید." }, "reorderFieldUp": { - "message": "$LABEL$ moved up, position $INDEX$ of $LENGTH$", + "message": "$LABEL$ به بالا منتقل شد، موقعیت $INDEX$ از $LENGTH$", "placeholders": { "label": { "content": "$1", @@ -4752,13 +4837,13 @@ } }, "selectCollectionsToAssign": { - "message": "Select collections to assign" + "message": "مجموعه‌ها را برای اختصاص انتخاب کنید" }, "personalItemTransferWarningSingular": { - "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + "message": "۱ مورد به طور دائمی به سازمان انتخاب شده منتقل خواهد شد. شما دیگر مالک این مورد نخواهید بود." }, "personalItemsTransferWarningPlural": { - "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", + "message": "$PERSONAL_ITEMS_COUNT$ مورد به طور دائمی به سازمان انتخاب شده منتقل خواهند شد. شما دیگر مالک این موارد نخواهید بود.", "placeholders": { "personal_items_count": { "content": "$1", @@ -4767,7 +4852,7 @@ } }, "personalItemWithOrgTransferWarningSingular": { - "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "message": "۱ مورد به طور دائمی به $ORG$ منتقل خواهد شد. شما دیگر مالک این مورد نخواهید بود.", "placeholders": { "org": { "content": "$1", @@ -4776,7 +4861,7 @@ } }, "personalItemsWithOrgTransferWarningPlural": { - "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", + "message": "$PERSONAL_ITEMS_COUNT$ مورد به طور دائمی به $ORG$ منتقل خواهند شد. شما دیگر مالک این موارد نخواهید بود.", "placeholders": { "personal_items_count": { "content": "$1", @@ -4789,13 +4874,13 @@ } }, "successfullyAssignedCollections": { - "message": "Successfully assigned collections" + "message": "مجموعه‌ها با موفقیت اختصاص داده شدند" }, "nothingSelected": { - "message": "You have not selected anything." + "message": "شما چیزی را انتخاب نکرده اید." }, "itemsMovedToOrg": { - "message": "Items moved to $ORGNAME$", + "message": "موارد به $ORGNAME$ منتقل شدند", "placeholders": { "orgname": { "content": "$1", @@ -4804,7 +4889,7 @@ } }, "itemMovedToOrg": { - "message": "Item moved to $ORGNAME$", + "message": "مورد به $ORGNAME$ منتقل شد", "placeholders": { "orgname": { "content": "$1", @@ -4813,7 +4898,7 @@ } }, "reorderFieldDown": { - "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", + "message": "$LABEL$ به پایین منتقل شد، موقعیت $INDEX$ از $LENGTH$", "placeholders": { "label": { "content": "$1", @@ -4830,46 +4915,46 @@ } }, "itemLocation": { - "message": "Item Location" + "message": "مکان مورد" }, "fileSend": { - "message": "File Send" + "message": "پرونده ارسال" }, "fileSends": { - "message": "File Sends" + "message": "پرونده ارسال‌ها" }, "textSend": { - "message": "Text Send" + "message": "ارسال متن" }, "textSends": { - "message": "Text Sends" + "message": "ارسال‌های متن" }, "accountActions": { - "message": "Account actions" + "message": "فعالیت‌های حساب کاربری" }, "showNumberOfAutofillSuggestions": { - "message": "Show number of login autofill suggestions on extension icon" + "message": "نمایش تعداد پیشنهادهای پر کردن خودکار ورود در آیکون افزونه" }, "showQuickCopyActions": { - "message": "Show quick copy actions on Vault" + "message": "نمایش عملیات کپی سریع در گاوصندوق" }, "systemDefault": { - "message": "System default" + "message": "پیش‌فرض سیستم" }, "enterprisePolicyRequirementsApplied": { - "message": "Enterprise policy requirements have been applied to this setting" + "message": "الزامات سیاست سازمانی روی این تنظیم اعمال شده است" }, "sshPrivateKey": { - "message": "Private key" + "message": "کلید خصوصی" }, "sshPublicKey": { - "message": "Public key" + "message": "کلید عمومی" }, "sshFingerprint": { - "message": "Fingerprint" + "message": "اثر انگشت" }, "sshKeyAlgorithm": { - "message": "Key type" + "message": "نوع کلید" }, "sshKeyAlgorithmED25519": { "message": "ED25519" @@ -4884,61 +4969,61 @@ "message": "RSA 4096-Bit" }, "retry": { - "message": "Retry" + "message": "تلاش مجدد" }, "vaultCustomTimeoutMinimum": { - "message": "Minimum custom timeout is 1 minute." + "message": "حداقل مهلت زمانی سفارشی ۱ دقیقه است." }, "additionalContentAvailable": { - "message": "Additional content is available" + "message": "محتوای اضافی در دسترس است" }, "fileSavedToDevice": { - "message": "File saved to device. Manage from your device downloads." + "message": "پرونده در دستگاه ذخیره شد. از بخش بارگیری‌های دستگاه خود مدیریت کنید." }, "showCharacterCount": { - "message": "Show character count" + "message": "نمایش تعداد کاراکترها" }, "hideCharacterCount": { - "message": "Hide character count" + "message": "مخفی کردن تعداد کاراکترها" }, "itemsInTrash": { - "message": "Items in trash" + "message": "موراد در سطل زباله" }, "noItemsInTrash": { - "message": "No items in trash" + "message": "موردی در سطل زباله نیست" }, "noItemsInTrashDesc": { - "message": "Items you delete will appear here and be permanently deleted after 30 days" + "message": "مواردی که حذف می‌کنید اینجا نمایش داده می‌شوند و پس از ۳۰ روز به طور دائمی حذف خواهند شد" }, "trashWarning": { - "message": "Items that have been in trash more than 30 days will automatically be deleted" + "message": "مواردی که بیش از ۳۰ روز در سطل زباله بوده‌اند به‌طور خودکار حذف خواهند شد" }, "restore": { - "message": "Restore" + "message": "بازیابی" }, "deleteForever": { - "message": "Delete forever" + "message": "حذف برای همیشه" }, "noEditPermissions": { - "message": "You don't have permission to edit this item" + "message": "شما مجوز ویرایش این مورد را ندارید" }, "biometricsStatusHelptextUnlockNeeded": { - "message": "Biometric unlock is unavailable because PIN or password unlock is required first." + "message": "بازکردن با بیومتریک در دسترس نیست زیرا ابتدا باید بازکردن قفل با کد پین یا کلمه عبور انجام شود." }, "biometricsStatusHelptextHardwareUnavailable": { - "message": "Biometric unlock is currently unavailable." + "message": "باز کردن قفل با بیومتریک در حال حاضر در دسترس نیست." }, "biometricsStatusHelptextAutoSetupNeeded": { - "message": "Biometric unlock is unavailable due to misconfigured system files." + "message": "باز کردن قفل با بیومتریک به دلیل پیکربندی نادرست پرونده‌های سیستم در دسترس نیست." }, "biometricsStatusHelptextManualSetupNeeded": { - "message": "Biometric unlock is unavailable due to misconfigured system files." + "message": "باز کردن قفل با بیومتریک به دلیل پیکربندی نادرست پرونده‌های سیستم در دسترس نیست." }, "biometricsStatusHelptextDesktopDisconnected": { - "message": "Biometric unlock is unavailable because the Bitwarden desktop app is closed." + "message": "باز کردن قفل با بیومتریک در دسترس نیست زیرا برنامه دسکتاپ Bitwarden بسته است." }, "biometricsStatusHelptextNotEnabledInDesktop": { - "message": "Biometric unlock is unavailable because it is not enabled for $EMAIL$ in the Bitwarden desktop app.", + "message": "باز کردن قفل با بیومتریک در دسترس نیست زیرا برای $EMAIL$ در برنامه دسکتاپ Bitwarden فعال نشده است.", "placeholders": { "email": { "content": "$1", @@ -4947,244 +5032,217 @@ } }, "biometricsStatusHelptextUnavailableReasonUnknown": { - "message": "Biometric unlock is currently unavailable for an unknown reason." + "message": "باز کردن قفل با بیومتریک در حال حاضر به دلیل نامعلومی در دسترس نیست." + }, + "unlockVault": { + "message": "قفل گاوصندوق خود را در چند ثانیه باز کنید" + }, + "unlockVaultDesc": { + "message": "می‌توانید تنظیمات باز کردن قفل و زمان‌بندی خودکار بسته شدن گاوصندوق را سفارشی کنید تا سریع‌تر به گاوصندوق خود دسترسی پیدا کنید." + }, + "unlockPinSet": { + "message": "بازکردن قفل کد پین تنظیم شد" }, "authenticating": { - "message": "Authenticating" + "message": "در حال احراز هویت" }, "fillGeneratedPassword": { - "message": "Fill generated password", + "message": "پر کردن کلمه عبور تولید شده", "description": "Heading for the password generator within the inline menu" }, "passwordRegenerated": { - "message": "Password regenerated", + "message": "کلمه عبور تولید شد", "description": "Notification message for when a password has been regenerated" }, "saveToBitwarden": { - "message": "Save to Bitwarden", + "message": "ذخیره در Bitwarden", "description": "Confirmation message for saving a login to Bitwarden" }, "spaceCharacterDescriptor": { - "message": "Space", + "message": "فاصله", "description": "Represents the space key in screen reader content as a readable word" }, "tildeCharacterDescriptor": { - "message": "Tilde", + "message": "تیلد", "description": "Represents the ~ key in screen reader content as a readable word" }, "backtickCharacterDescriptor": { - "message": "Backtick", + "message": "بک‌تیک", "description": "Represents the ` key in screen reader content as a readable word" }, "exclamationCharacterDescriptor": { - "message": "Exclamation mark", + "message": "علامت تعجب", "description": "Represents the ! key in screen reader content as a readable word" }, "atSignCharacterDescriptor": { - "message": "At sign", + "message": "علامت @", "description": "Represents the @ key in screen reader content as a readable word" }, "hashSignCharacterDescriptor": { - "message": "Hash sign", + "message": "علامت #", "description": "Represents the # key in screen reader content as a readable word" }, "dollarSignCharacterDescriptor": { - "message": "Dollar sign", + "message": "علامت دلار", "description": "Represents the $ key in screen reader content as a readable word" }, "percentSignCharacterDescriptor": { - "message": "Percent sign", + "message": "علامت ٪", "description": "Represents the % key in screen reader content as a readable word" }, "caretCharacterDescriptor": { - "message": "Caret", + "message": "علامت ^", "description": "Represents the ^ key in screen reader content as a readable word" }, "ampersandCharacterDescriptor": { - "message": "Ampersand", + "message": "علامت &", "description": "Represents the & key in screen reader content as a readable word" }, "asteriskCharacterDescriptor": { - "message": "Asterisk", + "message": "علامت *", "description": "Represents the * key in screen reader content as a readable word" }, "parenLeftCharacterDescriptor": { - "message": "Left parenthesis", + "message": "پرانتز چپ", "description": "Represents the ( key in screen reader content as a readable word" }, "parenRightCharacterDescriptor": { - "message": "Right parenthesis", + "message": "پرانتز راست", "description": "Represents the ) key in screen reader content as a readable word" }, "hyphenCharacterDescriptor": { - "message": "Underscore", + "message": "خط زیر", "description": "Represents the _ key in screen reader content as a readable word" }, "underscoreCharacterDescriptor": { - "message": "Hyphen", + "message": "خط تیره", "description": "Represents the - key in screen reader content as a readable word" }, "plusCharacterDescriptor": { - "message": "Plus", + "message": "به علاوه", "description": "Represents the + key in screen reader content as a readable word" }, "equalsCharacterDescriptor": { - "message": "Equals", + "message": "مساوی", "description": "Represents the = key in screen reader content as a readable word" }, "braceLeftCharacterDescriptor": { - "message": "Left brace", + "message": "آکولادِ چپ", "description": "Represents the { key in screen reader content as a readable word" }, "braceRightCharacterDescriptor": { - "message": "Right brace", + "message": "آکولادِ راست", "description": "Represents the } key in screen reader content as a readable word" }, "bracketLeftCharacterDescriptor": { - "message": "Left bracket", + "message": "کروشه‌ی چپ", "description": "Represents the [ key in screen reader content as a readable word" }, "bracketRightCharacterDescriptor": { - "message": "Right bracket", + "message": "کروشه‌ی راست", "description": "Represents the ] key in screen reader content as a readable word" }, "pipeCharacterDescriptor": { - "message": "Pipe", + "message": "علامت |", "description": "Represents the | key in screen reader content as a readable word" }, "backSlashCharacterDescriptor": { - "message": "Back slash", + "message": "بک اسلش", "description": "Represents the back slash key in screen reader content as a readable word" }, "colonCharacterDescriptor": { - "message": "Colon", + "message": "دو نقطه", "description": "Represents the : key in screen reader content as a readable word" }, "semicolonCharacterDescriptor": { - "message": "Semicolon", + "message": "نقطه ویرگول", "description": "Represents the ; key in screen reader content as a readable word" }, "doubleQuoteCharacterDescriptor": { - "message": "Double quote", + "message": "دابل کوت", "description": "Represents the double quote key in screen reader content as a readable word" }, "singleQuoteCharacterDescriptor": { - "message": "Single quote", + "message": "سینگل کوت", "description": "Represents the ' key in screen reader content as a readable word" }, "lessThanCharacterDescriptor": { - "message": "Less than", + "message": "کمتر از", "description": "Represents the < key in screen reader content as a readable word" }, "greaterThanCharacterDescriptor": { - "message": "Greater than", + "message": "بیش‌تر از", "description": "Represents the > key in screen reader content as a readable word" }, "commaCharacterDescriptor": { - "message": "Comma", + "message": "کاما", "description": "Represents the , key in screen reader content as a readable word" }, "periodCharacterDescriptor": { - "message": "Period", + "message": "دوره", "description": "Represents the . key in screen reader content as a readable word" }, "questionCharacterDescriptor": { - "message": "Question mark", + "message": "علامت سوال", "description": "Represents the ? key in screen reader content as a readable word" }, "forwardSlashCharacterDescriptor": { - "message": "Forward slash", + "message": "ممیز", "description": "Represents the / key in screen reader content as a readable word" }, "lowercaseAriaLabel": { - "message": "Lowercase" + "message": "حروف کوچک" }, "uppercaseAriaLabel": { - "message": "Uppercase" + "message": "حروف بزرگ" }, "generatedPassword": { - "message": "Generated password" + "message": "کلمه عبور تولید شد" }, "compactMode": { - "message": "Compact mode" + "message": "حالت فشرده" }, "beta": { - "message": "Beta" - }, - "importantNotice": { - "message": "Important notice" - }, - "setupTwoStepLogin": { - "message": "Set up two-step login" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Remind me later" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" - }, - "turnOnTwoStepLogin": { - "message": "Turn on two-step login" - }, - "changeAcctEmail": { - "message": "Change account email" + "message": "آزمایشی" }, "extensionWidth": { - "message": "Extension width" + "message": "عرض افزونه" }, "wide": { - "message": "Wide" + "message": "عریض" }, "extraWide": { - "message": "Extra wide" + "message": "خیلی عریض" }, "sshKeyWrongPassword": { - "message": "The password you entered is incorrect." + "message": "کلمه عبور وارد شده اشتباه است." }, "importSshKey": { - "message": "Import" + "message": "درون ریزی" }, "confirmSshKeyPassword": { - "message": "Confirm password" + "message": "تأیید کلمه عبور" }, "enterSshKeyPasswordDesc": { - "message": "Enter the password for the SSH key." + "message": "کلمه عبور کلید SSH را وارد کنید." }, "enterSshKeyPassword": { - "message": "Enter password" + "message": "کلمه عبور را وارد کنید" }, "invalidSshKey": { - "message": "The SSH key is invalid" + "message": "کلید SSH نامعتبر است" }, "sshKeyTypeUnsupported": { - "message": "The SSH key type is not supported" + "message": "نوع کلید SSH پشتیبانی نمی‌شود" }, "importSshKeyFromClipboard": { - "message": "Import key from clipboard" + "message": "وارد کردن کلید از حافظه موقت" }, "sshKeyImported": { - "message": "SSH key imported successfully" + "message": "کلید SSH با موفقیت وارد شد" }, "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "message": "نمی‌توانید مجموعه‌هایی را که فقط دسترسی مشاهده دارند حذف کنید: $COLLECTIONS$", "placeholders": { "collections": { "content": "$1", @@ -5193,90 +5251,138 @@ } }, "updateDesktopAppOrDisableFingerprintDialogTitle": { - "message": "Please update your desktop application" + "message": "لطفاً برنامه دسکتاپ خود را به‌روزرسانی کنید" }, "updateDesktopAppOrDisableFingerprintDialogMessage": { - "message": "To use biometric unlock, please update your desktop application, or disable fingerprint unlock in the desktop settings." + "message": "برای استفاده از باز کردن قفل با بیومتریک، لطفاً برنامه دسکتاپ خود را به‌روزرسانی کنید یا باز کردن قفل با اثر انگشت را در تنظیمات دسکتاپ غیرفعال کنید." }, "changeAtRiskPassword": { - "message": "Change at-risk password" + "message": "تغییر کلمه عبور در معرض خطر" }, "settingsVaultOptions": { - "message": "Vault options" + "message": "گزینه‌های گاوصندوق" }, "emptyVaultDescription": { - "message": "The vault protects more than just your passwords. Store secure logins, IDs, cards and notes securely here." + "message": "گاوصندوق تنها کلمات عبور را محافظت نمی‌کند. ورودهای امن، شناسه‌ها، کارت‌ها و یادداشت‌ها را نیز به صورت امن در اینجا ذخیره کنید." }, "introCarouselLabel": { - "message": "Welcome to Bitwarden" + "message": "به Bitwarden خوش آمدید" }, "securityPrioritized": { - "message": "Security, prioritized" + "message": "امنیت، در اولویت" }, "securityPrioritizedBody": { - "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + "message": "ورودها، کارت‌ها و هویت‌ها را در گاوصندوق امن خود ذخیره کنید. Bitwarden از رمزگذاری انتها به انتهای دانش صفر برای محافظت از آنچه برای شما مهم است استفاده می‌کند." }, "quickLogin": { - "message": "Quick and easy login" + "message": "ورود سریع و آسان" }, "quickLoginBody": { - "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + "message": "قفل بیومتریک و پر کردن خودکار را تنظیم کنید تا بدون وارد کردن حتی یک حرف وارد حساب‌های خود شوید." }, "secureUser": { - "message": "Level up your logins" + "message": "ورودهای خود را ارتقا دهید" }, "secureUserBody": { - "message": "Use the generator to create and save strong, unique passwords for all your accounts." + "message": "از تولید کننده برای ایجاد و ذخیره کلمه‌های عبور قوی و منحصر به فرد برای تمام حساب‌های کاربری خود استفاده کنید." }, "secureDevices": { - "message": "Your data, when and where you need it" + "message": "داده‌های شما، زمانی که نیاز دارید و در جایی که نیاز دارید" }, "secureDevicesBody": { - "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." + "message": "کلمه‌های عبور نامحدود را در دستگاه‌های نامحدود با اپلیکیشن‌های موبایل، مرورگر و دسکتاپ Bitwarden ذخیره کنید." + }, + "nudgeBadgeAria": { + "message": "۱ اعلان" }, "emptyVaultNudgeTitle": { - "message": "Import existing passwords" + "message": "درون ریزی کلمات عبور موجود" }, "emptyVaultNudgeBody": { - "message": "Use the importer to quickly transfer logins to Bitwarden without manually adding them." + "message": "از ابزار درون ریزی استفاده کنید تا ورودها را سریعاً به Bitwarden منتقل کنید بدون نیاز به افزودن دستی آن‌ها." }, "emptyVaultNudgeButton": { - "message": "Import now" + "message": "الان درودن ریزی کن" }, "hasItemsVaultNudgeTitle": { - "message": "Welcome to your vault!" + "message": "به گاوصندوق خود خوش آمدید!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "پر کردن خودکار موارد برای صفحه فعلی" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "موارد مورد علاقه برای دسترسی آسان" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "در گاوصندوق خود به دنبال چیز دیگری بگردید" }, "newLoginNudgeTitle": { - "message": "Save time with autofill" + "message": "با پر کردن خودکار در وقت خود صرفه جویی کنید" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "شامل یک", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "وب‌سایت", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "تا این ورود به عنوان پیشنهاد پر کردن خودکار ظاهر شود.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { - "message": "Seamless online checkout" + "message": "پرداخت آنلاین بدون وقفه" }, "newCardNudgeBody": { - "message": "With cards, easily autofill payment forms securely and accurately." + "message": "با کارت‌ها، فرم‌های پرداخت را به‌راحتی و با امنیت و دقت پر کنید." }, "newIdentityNudgeTitle": { - "message": "Simplify creating accounts" + "message": "ساخت حساب‌های کاربری را ساده کنید" }, "newIdentityNudgeBody": { - "message": "With identities, quickly autofill long registration or contact forms." + "message": "با هویت‌ها، به سرعت فرم‌های طولانی ثبت‌نام یا تماس را پر کنید." }, "newNoteNudgeTitle": { - "message": "Keep your sensitive data safe" + "message": "اطلاعات حساس خود را ایمن نگه دارید" }, "newNoteNudgeBody": { - "message": "With notes, securely store sensitive data like banking or insurance details." + "message": "با یادداشت‌ها، اطلاعات حساسی مانند جزئیات بانکی یا بیمه را به‌صورت ایمن ذخیره کنید." }, "newSshNudgeTitle": { - "message": "Developer-friendly SSH access" + "message": "دسترسی SSH مناسب برای توسعه‌دهندگان" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "کلیدهای خود را ذخیره کنید و با عامل SSH برای احراز هویت سریع و رمزگذاری‌شده متصل شوید.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "اطلاعات بیشتر درباره عامل SSH را بیاموزید", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "ساخت سریع کلمات عبور" + }, + "generatorNudgeBodyOne": { + "message": "به‌راحتی کلمات عبور قوی و منحصر به فرد ایجاد کنید با کلیک روی", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "برای کمک به حفظ امنیت ورودهای شما.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "با کلیک روی دکمه تولید رمز عبور، به‌راحتی کلمات عبور قوی و منحصر به‌ فرد ایجاد کنید تا ورودهای شما ایمن باقی بمانند.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "شما اجازه دسترسی به این صفحه را ندارید. لطفاً با حساب کاربری دیگری وارد شوید." } } diff --git a/apps/browser/src/_locales/fi/messages.json b/apps/browser/src/_locales/fi/messages.json index c3f48b1df3b..c93e64a0443 100644 --- a/apps/browser/src/_locales/fi/messages.json +++ b/apps/browser/src/_locales/fi/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "Uusi kohde, avautuu uudessa ikkunassa", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Muokkaa ennen tallentamista", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ tallennettiin Bitwardeniin.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ päivitettiin Bitwardeniin.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Tallenna uutena kirjautumistietona", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Päivitä kirjautumistieto", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Tallenna kirjautumistieto", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Automaattitäytön ehdotukset" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Poista automaattitäyttö käytöstä selaimessa $BROWSER$", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Poista automaattitäyttö käytöstä" + }, "showInlineMenuLabel": { "message": "Näytä automaattitäytön ehdotukset lomakekentissä" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Käytä tätä salasanaa" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Käytä tätä käyttäjätunnusta" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Aikakatkaisutoiminto" }, - "newCustomizationOptionsCalloutTitle": { - "message": "Uusia mukautusvaihtoehtoja" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Mukauta holvikokemustasi pikakopiointitoiminnoilla, kompaktilla tilalla ja muulla!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "Näytä kaikki ulkoasuasetukset" - }, "lock": { "message": "Lukitse", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "Kaikki Sendit", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Piilota teksti oletuksena" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Yksilöllistä tunnistetta ei löytynyt." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ käyttää kertakirjautumista (SSO) itse ylläpidetyllä avainpalvelimella. Organisaation jäsenet eivät enää tarvitse pääsalasanaa kirjautumiseen.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organisaation nimi" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Poistu organisaatiosta" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Laitteeseen luotettu" }, + "trustOrganization": { + "message": "Luota organisaatioon" + }, + "trust": { + "message": "Luota" + }, + "doNotTrust": { + "message": "Älä luota" + }, + "organizationNotTrusted": { + "message": "Organisaatio ei ole luotettu" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Luota käyttäjään" + }, "sendsNoItemsTitle": { "message": "Aktiivisia Sendejä ei ole", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Sendillä voit jakaa salattuja tietoja turvallisesti kenelle tahansa.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Syöte vaaditaan." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Lataa Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Lataa Bitwarden kaikille laitteille" + }, + "getTheMobileApp": { + "message": "Hanki mobiilisovellus" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Hanki työpöytäsovellus" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Hanki se Google Playstä" + }, + "downloadOnTheAppStore": { + "message": "Lataa App Storesta" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Haluatko varmasti poistaa liitteen pysyvästi?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometrinen avaus ei ole tällä hetkellä käytettävissä tuntemattomasta syystä." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Todennetaan" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Tärkeä ilmoitus" - }, - "setupTwoStepLogin": { - "message": "Määritä kaksivaiheinen kirjautuminen" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden lähettää tilisi sähköpostiosoitteeseen koodin, jolla voit vahvistaa kirjautumiset uusista laitteista helmikuusta 2025 alkaen." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "Voit määrittää kaksivaiheisen kirjautumisen tilisi vaihtoehtoiseksi suojaustavaksi tai vaihtaa sähköpostiosoitteesi sellaiseen, johon sinulla on pääsy." - }, - "remindMeLater": { - "message": "Muistuta myöhemmin" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Onko sinulla luotettava pääsy sähköpostiisi, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "Ei ole" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Kyllä on" - }, - "turnOnTwoStepLogin": { - "message": "Ota kaksivaiheinen kirjautuminen käyttöön" - }, - "changeAcctEmail": { - "message": "Muuta tilin sähköpostiosoitetta" - }, "extensionWidth": { "message": "Laajennuksen leveys" }, @@ -5202,7 +5260,7 @@ "message": "Vaihda vaarantunut salasana" }, "settingsVaultOptions": { - "message": "Vault options" + "message": "Holvin asetukset" }, "emptyVaultDescription": { "message": "The vault protects more than just your passwords. Store secure logins, IDs, cards and notes securely here." @@ -5234,26 +5292,47 @@ "secureDevicesBody": { "message": "Tallenna rajattomasti salasanoja, rajattomalla määrällä laitteita, Bitwardenin mobiili-, selain- ja työpöytäsovelluksilla." }, + "nudgeBadgeAria": { + "message": "1 ilmoitus" + }, "emptyVaultNudgeTitle": { - "message": "Import existing passwords" + "message": "Tuo olemassa olevat salasanat" }, "emptyVaultNudgeBody": { "message": "Use the importer to quickly transfer logins to Bitwarden without manually adding them." }, "emptyVaultNudgeButton": { - "message": "Import now" + "message": "Tuo nyt" }, "hasItemsVaultNudgeTitle": { - "message": "Welcome to your vault!" + "message": "Tervetuloa holviisi!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { - "message": "Save time with autofill" + "message": "Säästä aikaa automaattitäytöllä" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Verkkosivusto", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/fil/messages.json b/apps/browser/src/_locales/fil/messages.json index d01670a2353..6106ca7ed62 100644 --- a/apps/browser/src/_locales/fil/messages.json +++ b/apps/browser/src/_locales/fil/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Autofill suggestions" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Show autofill suggestions on form fields" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Use this password" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Use this username" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Timeout action" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "I-lock", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "Lahat ng Mga Padala", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Hide text by default" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Walang natagpuang natatanging nag-identipikar." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ ay gumagamit ng SSO na may sariling-hosted na key server. Walang kinakailangang master password para mag-log in para sa mga miyembro ng organisasyon na ito.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Umalis sa organisasyon" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Device trusted" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "No active Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Use Send to securely share encrypted information with anyone.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Input is required." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Are you sure you want to permanently delete this attachment?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Authenticating" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Important notice" - }, - "setupTwoStepLogin": { - "message": "Set up two-step login" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Remind me later" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" - }, - "turnOnTwoStepLogin": { - "message": "Turn on two-step login" - }, - "changeAcctEmail": { - "message": "Change account email" - }, "extensionWidth": { "message": "Extension width" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/fr/messages.json b/apps/browser/src/_locales/fr/messages.json index b8c4fa9d011..c9dae571046 100644 --- a/apps/browser/src/_locales/fr/messages.json +++ b/apps/browser/src/_locales/fr/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Enregistrer en tant que nouvel identifiant", "description": "Button text for saving login details as a new entry." @@ -1114,8 +1120,12 @@ "message": "Mettre à jour l'identifiant", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Déverrouiller pour enregistrer l'identifiant", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { - "message": "Save login", + "message": "Enregistrer l'identifiant", "description": "Prompt asking the user if they want to save their login details." }, "updateLogin": { @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Suggestions de saisie automatique" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Désactiver la saisie automatique" + }, "showInlineMenuLabel": { "message": "Afficher les suggestions de saisie automatique dans les champs d'un formulaire" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Utiliser ce mot de passe" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Utiliser ce nom d'utilisateur" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Expiration de l'action" }, - "newCustomizationOptionsCalloutTitle": { - "message": "Nouvelles options de personnalisation" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Personnalisez votre expérience utilisateur du coffre avec des actions de copie rapide, un mode compact et bien plus encore !" - }, - "newCustomizationOptionsCalloutLink": { - "message": "Afficher tous les paramètres d'apparence" - }, "lock": { "message": "Verrouiller", "description": "Verb form: to make secure or inaccessible by" @@ -2355,7 +2377,7 @@ "message": "Politique de confidentialité" }, "yourNewPasswordCannotBeTheSameAsYourCurrentPassword": { - "message": "Your new password cannot be the same as your current password." + "message": "Votre nouveau mot de passe ne peut être le même que votre mot de passe actuel." }, "hintEqualsPassword": { "message": "Votre indice de mot de passe ne peut pas être identique à votre mot de passe." @@ -2655,6 +2677,10 @@ "message": "Tous les Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Masquer le texte par défaut" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Aucun identifiant unique trouvé." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ utilise le SSO avec un serveur de clés auto-hébergé. Un mot de passe principal n'est plus nécessaire aux membres de cette organisation pour se connecter.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Nom de l'organisation" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Quitter l'organisation" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Appareil de confiance" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Faire confiance" + }, + "doNotTrust": { + "message": "Ne pas faire confiance" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "Pas de Send actif", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Utilisez Send pour partager en toute sécurité des informations chiffrées avec tout le monde.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Saisie requise." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Télécharger Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Télécharger Bitwarden sur tous les appareils" + }, + "getTheMobileApp": { + "message": "Télécharger l'application mobile" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Télécharger l'application de bureau" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Êtes-vous sûr de vouloir supprimer définitivement cette pièce jointe ?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Le déverrouillage par biométrie n'est pas disponible actuellement pour une raison inconnue." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Authentification" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Avis important" - }, - "setupTwoStepLogin": { - "message": "Configurer l'identification à deux facteurs" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden enverra un code au courriel de votre compte pour vérifier les connexions depuis de nouveaux appareils à partir de février 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "Vous pouvez configurer l'identification à deux facteurs comme un moyen alternatif de protéger votre compte ou de changer votre adresse courriel à une autre à laquelle vous pouvez accéder." - }, - "remindMeLater": { - "message": "Me le rappeler plus tard" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Avez-vous un accès fiable à votre courriel $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "Non, je ne l'ai pas" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Oui, je peux accéder à mon courriel de manière fiable" - }, - "turnOnTwoStepLogin": { - "message": "Activer l'identification à deux facteurs" - }, - "changeAcctEmail": { - "message": "Changer le courriel du compte" - }, "extensionWidth": { "message": "Largeur de l'extension" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/gl/messages.json b/apps/browser/src/_locales/gl/messages.json index 40823d54799..ef99d2cb211 100644 --- a/apps/browser/src/_locales/gl/messages.json +++ b/apps/browser/src/_locales/gl/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Suxestións de autoenchido" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Amosar suxestións de autoenchido en formularios" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Usar este contrasinal" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Usar este nome de usuario" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Acción do temporizador" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "Bloquear", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "Todos os Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Ocultar texto por defecto" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Non se atopou ningún identificador único." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ emprega SSO con un servidor de claves propio. Os membros da organización xa non precisan dun contrasinal mestre para iniciar sesión.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Deixar a organización" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Dispositivo de confianza" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "Sen Sends activos", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Usar send para compartir información cifrada con quen queiras.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Requírese algunha entrada." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Estás seguro de que queres eliminar permanentemente este anexo?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "O desbloqueo biométrico non está dispoñible por algunha razón non prevista." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Autenticando" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Aviso importante" - }, - "setupTwoStepLogin": { - "message": "Configurar verificación en dous pasos" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "A partir de febreiro de 2025 Bitwarden comezará a enviar correos con códigos de verificación para confirmar novos inicios de sesión á túa conta." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "Podes configurar a verificación en 2 pasos como alternativa para protexer a túa conta ou cambiar o enderezo electrónico a un ó que teñas acceso." - }, - "remindMeLater": { - "message": "Lembrarmo máis tarde" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Tes acceso fiable ó teu correo? ($EMAIL$)", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "Non, non o teño" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Si, teño acceso fiable ó meu correo" - }, - "turnOnTwoStepLogin": { - "message": "Activar verificación en dous pasos" - }, - "changeAcctEmail": { - "message": "Mudar de correo electrónico" - }, "extensionWidth": { "message": "Ancho da extensión" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/he/messages.json b/apps/browser/src/_locales/he/messages.json index a41386d9494..72dcdb70376 100644 --- a/apps/browser/src/_locales/he/messages.json +++ b/apps/browser/src/_locales/he/messages.json @@ -3,7 +3,7 @@ "message": "Bitwarden" }, "appLogoLabel": { - "message": "Bitwarden logo" + "message": "הלוגו של Bitwarden" }, "extName": { "message": "מנהל הסיסמאות Bitwarden", @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "שמור ככניסה חדשה", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "עדכן כניסה", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "הצעות למילוי אוטומטי" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "הצג הצעות למילוי אוטומטי על שדות טופס" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "השתמש בסיסמה זו" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "השתמש בשם משתמש זה" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "פעולת פסק זמן" }, - "newCustomizationOptionsCalloutTitle": { - "message": "אפשרויות התאמה אישית חדשות" - }, - "newCustomizationOptionsCalloutContent": { - "message": "התאם אישית את חווית הכספת שלך עם פעולות העתקה מהירות, מצב קומפקטי, ועוד!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "הצג את כל הגדרות המראה" - }, "lock": { "message": "נעילה", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "כל הסֵנְדים", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "מספר הגישות המרבי הושג", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "הסתר טקסט כברירת מחדל" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "לא נמצא מזהה ייחודי." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ משתמש/ת ב־SSO עם שרת מפתחות באירוח עצמי. סיסמה ראשית כבר לא נדרשת כדי להיכנס עבור חברים של ארגון זה.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "עזוב ארגון" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "מכשיר מהימן" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "אין סֵנְדים פעילים", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "השתמש בסֵנְד כדי לשתף באופן מאובטח מידע מוצפן עם כל אחד.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "נדרש קלט." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "האם אתה בטוח שברצונך למחוק לצמיתות צרופה זו?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "ביטול נעילה ביומטרי אינו זמין כעת מסיבה לא ידועה." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "מאמת" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "בטא" }, - "importantNotice": { - "message": "הודעה חשובה" - }, - "setupTwoStepLogin": { - "message": "הגדר כניסה דו־שלבית" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden ישלח קוד לדוא\"ל החשבון שלך כדי לאמת כניסות ממכשירים חדשים החל מפברואר 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "אתה יכול להגדיר כניסה דו־שלבית כדרך חלופית להגן על החשבון שלך או לשנות את הדוא\"ל שלך לאחד שאתה יכול לגשת אליו." - }, - "remindMeLater": { - "message": "הזכר לי מאוחר יותר" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "יש לך גישה מהימנה לדוא\"ל שלך, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "לא, אין לי" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "כן, אני יכול לגשת לדוא\"ל שלי באופן מהימן" - }, - "turnOnTwoStepLogin": { - "message": "הפעל כניסה דו־שלבית" - }, - "changeAcctEmail": { - "message": "שנה את דוא\"ל החשבון" - }, "extensionWidth": { "message": "רוחב הרחבה" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/hi/messages.json b/apps/browser/src/_locales/hi/messages.json index d4fff520b87..06dd2c49390 100644 --- a/apps/browser/src/_locales/hi/messages.json +++ b/apps/browser/src/_locales/hi/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Autofill suggestions" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Show autofill suggestions on form fields" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Use this password" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Use this username" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "टाइमआउट कार्रवाई" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "लॉक", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "सभी Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Hide text by default" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ is using SSO with a self-hosted key server. A master password is no longer required to log in for members of this organization.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Leave organization" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Device trusted" }, + "trustOrganization": { + "message": "विश्वसनीय संगठन" + }, + "trust": { + "message": "भरोसा करें" + }, + "doNotTrust": { + "message": "भरोसा न करें" + }, + "organizationNotTrusted": { + "message": "संगठन पर भरोसा नहीं है" + }, + "emergencyAccessTrustWarning": { + "message": "अपने खाते की सुरक्षा के लिए, केवल तभी पुष्टि करें जब आपने इस उपयोगकर्ता को आपातकालीन पहुँच प्रदान की हो और उनका फिंगरप्रिंट उनके खाते में प्रदर्शित फिंगरप्रिंट से मेल खाता हो" + }, + "orgTrustWarning": { + "message": "अपने खाते की सुरक्षा के लिए, केवल तभी आगे बढ़ें जब आप इस संगठन के सदस्य हों, खाता पुनर्प्राप्ति सक्षम हो, तथा नीचे प्रदर्शित फिंगरप्रिंट संगठन के फिंगरप्रिंट से मेल खाता हो।" + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "उपयोगकर्ता पर भरोसा रखें" + }, "sendsNoItemsTitle": { "message": "No active Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Use Send to securely share encrypted information with anyone.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Input is required." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Are you sure you want to permanently delete this attachment?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Authenticating" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "महत्वपूर्ण सूचना" - }, - "setupTwoStepLogin": { - "message": "टू-स्टेप लॉगइन" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "बाद में मुझे याद कराएं" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "नहीं, मैं नहीं" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "हाँ, मैं आराम से अपना ईमेल देख सकता हूँ" - }, - "turnOnTwoStepLogin": { - "message": "टू-स्टेप लॉगइन सक्षम करें" - }, - "changeAcctEmail": { - "message": "अकाउंट का ईमेल बदलें" - }, "extensionWidth": { "message": "Extension width" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { - "message": "Save time with autofill" + "message": "स्वतः भरण से समय बचाएँ" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/hr/messages.json b/apps/browser/src/_locales/hr/messages.json index f3e4bd840c7..f94a2e60b79 100644 --- a/apps/browser/src/_locales/hr/messages.json +++ b/apps/browser/src/_locales/hr/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Spremi novu prijavu", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Ažuriraj prijavu", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Prijedlozi auto-ispune" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Prikaži prijedloge auto-ispune na poljima obrazaca" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Koristi ovu lozinku" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Koristi ovo korisničko ime" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Radnja nakon isteka " }, - "newCustomizationOptionsCalloutTitle": { - "message": "Nove mogućnosti prilagodbe" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Prilagodi svoje iskustvo trezora brzim kopiranjem, kompaktnim načinom rada i više!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "Pogledaj sve postavke izgleda" - }, "lock": { "message": "Zaključaj", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "Svi Sendovi", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Zadano sakrij tekst" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Nije nađen jedinstveni identifikator." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ koristi jedinstvenu prijavu SSO s vlastitim poslužiteljem. Članovima organizacije glavna lozinka više nije potrebna.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Napusti organizaciju" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Uređaj pouzdan" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "Nema aktivnih Sendova", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Koristi Send za sigurno slanje šifriranih podataka bilo kome.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Potreban je unos." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Sigurno želiš trajno izbrisati ovaj privitak?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometrijsko otključavanje trenutno nije dostupno iz nepoznatog razloga." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Autentifikacija" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Važna napomena" - }, - "setupTwoStepLogin": { - "message": "Postavi dvostruku autentifikaciju" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden će, počevši od veljače 2025., za provjeru prijava s novih uređaja poslati kôd na e-poštu tvog računa." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "Prijavu dvostrukom autentifikacijom možeš postaviti kao alternativni način zaštite svog računa ili promijeni svoju e-poštu u onu kojoj možeš pristupiti." - }, - "remindMeLater": { - "message": "Podsjeti me kasnije" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Imaš li pouzdan pristup svojoj e-pošti: $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "Ne, nemam" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Da, pouzdano mogu pristupiti svojoj e-pošti" - }, - "turnOnTwoStepLogin": { - "message": "Uključi prijavu dvostrukom autentifikacijom" - }, - "changeAcctEmail": { - "message": "Promjeni e-poštu računa" - }, "extensionWidth": { "message": "Širina proširenja" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/hu/messages.json b/apps/browser/src/_locales/hu/messages.json index 07161af5727..55c2ec433c8 100644 --- a/apps/browser/src/_locales/hu/messages.json +++ b/apps/browser/src/_locales/hu/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "Új elem, megnyitás új ablakban", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Szerkesztés mentés előtt", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ mentésre került a Bitwardenben.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "mentésre került a Bitwardenbe.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ frissítésre került a Bitwardenben.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "frissítésre került a Bitwardenben.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "$ITEMTYPE$, $ITEMNAME$ választás", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Mentés új bejelentkezésként", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Bejelentkezés frissítése", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Feloldás a bejelentkezés mentéséhez", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Bejelentkezés mentése", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Autofill suggestions" }, + "autofillSpotlightTitle": { + "message": "Az automatikus kitöltési javaslatok könnyű megtalálása" + }, + "autofillSpotlightDesc": { + "message": "Kapcsoljuk ki a böngésző automatikus kitöltési beállításait, így azok nem ütköznek a Bitwardennel." + }, + "turnOffBrowserAutofill": { + "message": "$BROWSER$ automatikus kitöltés kikapcsolása", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Automat kitöltés bekapcsolása" + }, "showInlineMenuLabel": { "message": "Show autofill suggestions on form fields" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Jelszó használata" }, + "useThisPassphrase": { + "message": "Jelmondat használata" + }, "useThisUsername": { "message": "Felhasználónév használata" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Időkifutási művelet" }, - "newCustomizationOptionsCalloutTitle": { - "message": "Új testreszabási opciók" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Szabjuk testre tárhely élményét gyors másolási műveletekkel, kompakt móddal és még sok mással!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "Az összes megjelenési beállítás megtekintése" - }, "lock": { "message": "Lezárás", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "Összes Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "A maximális hozzáférések száma elérésre került.", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Szöveg elrejtése alapértelmezetten" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Nincs egyedi azonosító." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ jelenleg saját tárolású aláíráskulcsú SSO szervert használ. A mesterjelszó a továbbiakban nem szükséges a szervezeti tagsági bejelentkezéshez.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A következő szervezet tagjai számára már nincs szükség mesterjelszóra. Erősítsük meg az alábbi tartományt a szervezet adminisztrátorával." + }, + "organizationName": { + "message": "Szervezet neve" + }, + "keyConnectorDomain": { + "message": "Key Connector tartomány" }, "leaveOrganization": { "message": "Szervezet elhagyása" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Az eszköz megbízható." }, + "trustOrganization": { + "message": "Bizalmi szervezet" + }, + "trust": { + "message": "Bizalom" + }, + "doNotTrust": { + "message": "Nincs bizalom" + }, + "organizationNotTrusted": { + "message": "A szervezet nem megbízható." + }, + "emergencyAccessTrustWarning": { + "message": "A fiók biztonság érdekében csak akkor erősítsük meg, ha vészhelyzeti hozzáférést biztosítottunk ehhez a felhasználóhoz és az ujjlenyomata megegyezik a fiókjukban megjelenítettekkel." + }, + "orgTrustWarning": { + "message": "A fiók biztonsága érdekében csak akkor folytassuk, ha tagja vagyunk ennek a szervezetnek, engedélyezve van a fiók helyreállítása és az alább megjelenített ujjlenyomat megegyezik a szervezet ujjlenyomatával." + }, + "orgTrustWarning1": { + "message": "Ennek a szervezetnek van egy vállalati szabályzata, amely regisztrál bennünket a fiók helyreállítási szolgáltatásba. A regisztráció lehetővé teszi a szervezet rendszergazdái számára, hogy megváltoztassák a jelszavunkat. Csak akkor folytassuk, ha felismerjük ezt a szervezetet és az alább megjelenített ujjlenyomat-kifejezés megegyezik a szervezet ujjlenyomatával." + }, + "trustUser": { + "message": "Megbízható felhasználó" + }, "sendsNoItemsTitle": { "message": "Nincsenek natív Send elemek.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "A Send használatával biztonságosan megoszthatjuk a titkosított információkat bárkivel.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Érzékeny információt küldése biztonságosan", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Fájlok vagy adatok megosztása biztonságosan bárkivel, bármilyen platformon. Az információk titkosítva maradnak a végpontokon, korlátozva a kitettséget.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Az adatbevitel kötelező." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Bitwarden letöltése" + }, + "downloadBitwardenOnAllDevices": { + "message": "Bitwarden letöltése minden eszközön" + }, + "getTheMobileApp": { + "message": "Mobilalkalmazás beszerzése" + }, + "getTheMobileAppDesc": { + "message": "Útközben is hozzáférhetünk a jelszabkhoz a Bitwarden mobilalkalmazással." + }, + "getTheDesktopApp": { + "message": "Asztali alkalmazás beszerzése" + }, + "getTheDesktopAppDesc": { + "message": "Hozzáférhetünk a széfhez böngésző nélkül, majd állítsuk be a feloldást biometrikus adatokkal, hogy felgyorsítsuk a feloldást mind az asztali alkalmazásban, mind a böngésző bővítményben." + }, + "downloadFromBitwardenNow": { + "message": "Letöltés most a bitwarden.com webhelyről" + }, + "getItOnGooglePlay": { + "message": "Beszerzés a Google Playen" + }, + "downloadOnTheAppStore": { + "message": "Letöltés az App Store-ból" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Biztosan véglegesen törlésre kerüljön ez a melléklet?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "A biometrikus feloldás jelenleg ismeretlen okból nem érhető el." }, + "unlockVault": { + "message": "A széf feloldása másodpercek alatt" + }, + "unlockVaultDesc": { + "message": "Testreszabhatjuk a feloldási és időtúllépési beállításokat a széf gyorsabb elérése érdekében." + }, + "unlockPinSet": { + "message": "PIN beállítás feloldása" + }, "authenticating": { "message": "Authenticating" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Béta" }, - "importantNotice": { - "message": "Fontos megjegyzés" - }, - "setupTwoStepLogin": { - "message": "Kétlépéses bejelentkezés beüzemelése" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "A Bitwarden 2025 februárjától kódot küld a fiókhoz tartozó email-címre, amellyel ellenőrizhetők az új eszközökről történő bejelentkezések." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "A fiók védelmének alternatív módjaként beállíthatunk kétlépcsős bejelentkezést vagy módosíthatjuk az email címet egy elérhetőre." - }, - "remindMeLater": { - "message": "Emlékeztetés később" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Megbízható a hozzáférés $EMAIL$ email címhez?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "Nem, nem érem el" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Igen, megbízhatóan hozzáférek az emailjeimhez" - }, - "turnOnTwoStepLogin": { - "message": "Kétlépéses bejelentkezés bekapcsolása" - }, - "changeAcctEmail": { - "message": "Fiók email cím megváltoztatása" - }, "extensionWidth": { "message": "Kiterjesztés szélesség" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Mentsünk el a korlátlan jelszót korlátlan számú eszközön a Bitwarden mobil, böngésző és asztali alkalmazásokkal." }, + "nudgeBadgeAria": { + "message": "1 értesítés" + }, "emptyVaultNudgeTitle": { "message": "Létező jelszavak importálása" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Üdvözlet a széfben!" }, - "hasItemsVaultNudgeBody": { - "message": "Az aktuális oldal elemeinek automatikus kitöltése\nKedvenc elemek a könnyű hozzáférés érdekében\nValami más keresése a széfben" + "hasItemsVaultNudgeBodyOne": { + "message": "Az aktuális oldal elemeinek automatikus kitöltése" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Kedvenc elemek a könnyű hozzáférés érdekében" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Valami más keresése a széfben" }, "newLoginNudgeTitle": { "message": "Idő megtakarítás automatikus kitöltéssel" }, - "newLoginNudgeBody": { - "message": "Adjunk meg egy webhelyet, hogy ez a bejelentkezési név automatikusan kitöltendő javaslatként jelenjen meg." + "newLoginNudgeBodyOne": { + "message": "Bevonás:", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Webhely", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "így ez a bejelentkezés automatikus kitöltési javaslatként jelenik meg.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Zökkenőmentes online fizetés" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Fejlesztőbarát SSH hozzáférés" }, - "newSshNudgeBody": { - "message": "Tároljuk a kulcsokat és csatlakozzunk az SSH-ügynökhöz a gyors, titkosított hitelesítéshez." + "newSshNudgeBodyOne": { + "message": "Tároljuk el a kulcsokat és csatlakozzunk az SSH ügynökhöz a gyors, titkosított hitelesítéshez.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "További információ az SSH ügynökről", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Jelszavak gyors létrehozása" + }, + "generatorNudgeBodyOne": { + "message": "Könnyen létrehozhatunk erős és egyedi jelszavakat a gombra kattintva.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "a bejelentkezések biztonságának megőrzéséhez.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Könnyedén hozhatunk létre erős és egyedi jelszavakat a Jelszó generálása gombra kattintva, amely segít megőrizni a bejelentkezések biztonságát.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "Nincs jogosultság az oldal megtekintéséhez. Próbáljunk meg másik fiókkal bejelentkezni." } } diff --git a/apps/browser/src/_locales/id/messages.json b/apps/browser/src/_locales/id/messages.json index 5c77c54ecf4..ec27c6b6328 100644 --- a/apps/browser/src/_locales/id/messages.json +++ b/apps/browser/src/_locales/id/messages.json @@ -3,7 +3,7 @@ "message": "Bitwarden" }, "appLogoLabel": { - "message": "Bitwarden logo" + "message": "Logo Bitwarden" }, "extName": { "message": "Pengelola Sandi Bitwarden", @@ -887,7 +887,7 @@ "message": "Ikuti langkah-langkah di bawah untuk menyelesaikan log masuk." }, "followTheStepsBelowToFinishLoggingInWithSecurityKey": { - "message": "Follow the steps below to finish logging in with your security key." + "message": "Ikuti langkah-langkah berikut untuk menyelesaikan kegiatan masuk dengan kunci keamanan Anda." }, "restartRegistration": { "message": "Mulai ulang pendaftaran" @@ -1063,7 +1063,7 @@ "message": "Iya, Simpan Sekarang" }, "notificationViewAria": { - "message": "View $ITEMNAME$, opens in new window", + "message": "Lihat $ITEMNAME$, buka di jendela baru", "placeholders": { "itemName": { "content": "$1" @@ -1071,15 +1071,19 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { - "message": "Edit before saving", + "message": "Sunting sebelum menyimpan", "description": "Tooltip and Aria label for edit button on cipher item" }, "newNotification": { - "message": "New notification" + "message": "Pemberitahuan baru" }, "labelWithNotification": { - "message": "$LABEL$: New notification", + "message": "$LABEL$: Pemberitahuan baru", "description": "Label for the notification with a new login suggestion.", "placeholders": { "label": { @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Simpan sebagai log masuk baru", "description": "Button text for saving login details as a new entry." @@ -1114,12 +1120,16 @@ "message": "Perbarui log masuk", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { - "message": "Save login", + "message": "Simpan log masuk", "description": "Prompt asking the user if they want to save their login details." }, "updateLogin": { - "message": "Update existing login", + "message": "Perbarui log masuk yang sudah ada", "description": "Prompt asking the user if they want to update an existing login entry." }, "loginSaveSuccess": { @@ -1131,7 +1141,7 @@ "description": "Message displayed when login details are successfully updated." }, "loginUpdateTaskSuccess": { - "message": "Great job! You took the steps to make you and $ORGANIZATION$ more secure.", + "message": "Bagus! Anda telah mengambil langkah-langkah untuk membuat Anda dan $ORGANIZATION$ lebih aman.", "placeholders": { "organization": { "content": "$1" @@ -1140,7 +1150,7 @@ "description": "Shown to user after login is updated." }, "loginUpdateTaskSuccessAdditional": { - "message": "Thank you for making $ORGANIZATION$ more secure. You have $TASK_COUNT$ more passwords to update.", + "message": "Terima kasih telah membuat $ORGANIZATION$ menjadi lebih aman. Anda memiliki $TASK_COUNT$ kata sandi lagi untuk diperbarui.", "placeholders": { "organization": { "content": "$1" @@ -1152,7 +1162,7 @@ "description": "Shown to user after login is updated." }, "nextSecurityTaskAction": { - "message": "Change next password", + "message": "Ubah kata sandi selanjutnya", "description": "Message prompting user to undertake completion of another security task." }, "saveFailure": { @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Saran isi otomatis" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Tampilkan saran isi otomatis pada kolom formulir" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Gunakan kata sandi ini" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Gunakan nama pengguna ini" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Batas waktu tindakan" }, - "newCustomizationOptionsCalloutTitle": { - "message": "Opsi penyesuaian baru" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Sesuaikan pengalaman brankas Anda dengan aksi salin cepat, mode kompak, dan lainnya!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "Lihat semua pengaturan Penampilan" - }, "lock": { "message": "Kunci", "description": "Verb form: to make secure or inaccessible by" @@ -2355,7 +2377,7 @@ "message": "Kebijakan Privasi" }, "yourNewPasswordCannotBeTheSameAsYourCurrentPassword": { - "message": "Your new password cannot be the same as your current password." + "message": "Kata sandi baru Anda tidak boleh sama dengan kata sandi Anda yang sekarang." }, "hintEqualsPassword": { "message": "Petunjuk kata sandi Anda tidak boleh sama dengan kata sandi Anda." @@ -2552,10 +2574,10 @@ "message": "Ubah lebih cepat kata sandi yang berrisiko" }, "changeAtRiskPasswordsFasterDesc": { - "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + "message": "Perbarui pengaturan Anda sehingga Anda dapat dengan cepat mengisi otomatis kata sandi Anda dan menghasilkan kata sandi baru" }, "reviewAtRiskLogins": { - "message": "Review at-risk logins" + "message": "Tinjau ulang info masuk yang berpotensi bahaya" }, "reviewAtRiskPasswords": { "message": "Tinjau kata sandi yang berrisiko" @@ -2565,30 +2587,30 @@ "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, "reviewAtRiskLoginSlideImgAltPeriod": { - "message": "Illustration of a list of logins that are at-risk." + "message": "Gambaran daftar info masuk yang berpotensi bahaya." }, "generatePasswordSlideDesc": { - "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", + "message": "Hasilkan kata sandi yang kuat dan unik dengan cepat dengan menu isi otomatis Bitwarden pada situs yang berpotensi bahaya.", "description": "Description of the generate password slide on the at-risk password page carousel" }, "generatePasswordSlideImgAltPeriod": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password." + "message": "Gambaran dari menu isi otomatis Bitwarden yang menampilkan kata sandi yang dihasilkan." }, "updateInBitwarden": { - "message": "Update in Bitwarden" + "message": "Perbarui di Bitwarden" }, "updateInBitwardenSlideDesc": { - "message": "Bitwarden will then prompt you to update the password in the password manager.", + "message": "Bitwarden akan meminta Anda untuk memperbarui kata sandi di pengelola sandi.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, "updateInBitwardenSlideImgAltPeriod": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." + "message": "Gambaran dari pemberitahuan Bitwarden yang meminta pengguna untuk memperbarui info masuk." }, "turnOnAutofill": { - "message": "Turn on autofill" + "message": "Nyalakan isi otomatis" }, "turnedOnAutofill": { - "message": "Turned on autofill" + "message": "Telah menyalakan isi otomatis" }, "dismiss": { "message": "Tutup" @@ -2655,6 +2677,10 @@ "message": "Semua Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Sembunyikan teks secara bawaan" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Tidak ada pengidentifikasi unik yang ditemukan." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ menggunakan SSO dengan server kunci yang dihosting sendiri. Kata sandi utama tidak lagi diperlukan untuk masuk untuk anggota organisasi ini.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Tinggalkan Organisasi" @@ -3038,7 +3064,7 @@ } }, "exportingIndividualVaultWithAttachmentsDescription": { - "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "message": "Hanya benda-benda brankas satuan termasuk lampiran yang terhubung dengan $EMAIL$ yang akan diekspor. Benda brankas organisasi tidak akan disertakan", "placeholders": { "email": { "content": "$1", @@ -3068,7 +3094,7 @@ "message": "Bitwarden tidak bisa mendekripsi butir brankas yang tercantum di bawah." }, "contactCSToAvoidDataLossPart1": { - "message": "Contact customer success", + "message": "Hubungi layanan pelanggan", "description": "This is part of a larger sentence. The full sentence will read 'Contact customer success to avoid additional data loss.'" }, "contactCSToAvoidDataLossPart2": { @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Perangkat dipercaya" }, + "trustOrganization": { + "message": "Percayai organisasi" + }, + "trust": { + "message": "Percayai" + }, + "doNotTrust": { + "message": "Jangan percayai" + }, + "organizationNotTrusted": { + "message": "Organisasi tidak tepercaya" + }, + "emergencyAccessTrustWarning": { + "message": "Demi keamanan akun Anda, hanya konfirmasi jika Anda telah memberikan akses darurat ke pengguna ini dan sidik jari mereka cocok dengan apa yang ditampilkan pada akun mereka" + }, + "orgTrustWarning": { + "message": "Demi keamanan akun Anda, hanya lanjutkan apabila Anda adalah anggota dari organisasi ini, pemulihan akun telah aktif, dan sidik jari yang ditampilkan berikut cocok dengan sidik jari organisasi." + }, + "orgTrustWarning1": { + "message": "Organisasi ini memiliki kebijakan perusahaan yang akan mendaftarkan Anda pada pemulihan akun. Pendaftaran ini akan membolehkan pengelola organisasi untuk mengubah kata sandi Anda. Hanya lanjutkan jika Anda mengenali organisasi ini dan frasa sidik jari yang ditampilkan berikut cocok dengan sidik jari organisasi." + }, + "trustUser": { + "message": "Percayai pengguna" + }, "sendsNoItemsTitle": { "message": "Tidak ada Send yang aktif", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Gunakan Send untuk membagikan informasi terenkripsi secara aman dengan siapapun.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Masukan ini harus diisi." }, @@ -4304,7 +4362,7 @@ } }, "viewItemTitleWithField": { - "message": "View item - $ITEMNAME$ - $FIELD$", + "message": "Lihat benda - $ITEMNAME$ - $FIELD$", "description": "Title for a link that opens a view for an item.", "placeholders": { "itemname": { @@ -4328,7 +4386,7 @@ } }, "autofillTitleWithField": { - "message": "Autofill - $ITEMNAME$ - $FIELD$", + "message": "Isi otomatis - $ITEMNAME$ - $FIELD$", "description": "Title for a button that autofills a login item.", "placeholders": { "itemname": { @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Unduh Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Unduh Bitwarden" + }, + "getTheMobileApp": { + "message": "Dapatkan aplikasi ponsel" + }, + "getTheMobileAppDesc": { + "message": "Akses kata sandi Anda di perjalanan dengan aplikasi ponsel Bitwarden." + }, + "getTheDesktopApp": { + "message": "Dapatkan aplikasi desktop" + }, + "getTheDesktopAppDesc": { + "message": "Akses brankas Anda tanpa sebuah peramban, kemudian atur buka dengan biometrik untuk mempercepat membuka di aplikasi desktop dan ekstensi peramban." + }, + "downloadFromBitwardenNow": { + "message": "Unduh dari bitwarden.com sekarang" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Apakah Anda yakin ingin menghapus lampiran ini selamanya?" }, @@ -4732,10 +4817,10 @@ } }, "reorderWebsiteUriButton": { - "message": "Reorder website URI. Use arrow key to move item up or down." + "message": "Urutkan URI situs web. Gunakan tombol panah untuk memindahkan benda ke atas atau ke bawah." }, "reorderFieldUp": { - "message": "$LABEL$ moved up, position $INDEX$ of $LENGTH$", + "message": "$LABEL$ dipindah ke atas, terletak di $INDEX$ dari $LENGTH$", "placeholders": { "label": { "content": "$1", @@ -4752,13 +4837,13 @@ } }, "selectCollectionsToAssign": { - "message": "Select collections to assign" + "message": "Pilih koleksi untuk ditetapkan" }, "personalItemTransferWarningSingular": { - "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + "message": "1 benda akan dipindahkan selamanya ke organisasi terpilih. Anda tidak akan lagi memiliki benda ini." }, "personalItemsTransferWarningPlural": { - "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", + "message": "$PERSONAL_ITEMS_COUNT$ benda akan dipindahkan selamanya ke organisasi terpilih. Anda tidak akan lagi memiliki benda-benda tersebut.", "placeholders": { "personal_items_count": { "content": "$1", @@ -4767,7 +4852,7 @@ } }, "personalItemWithOrgTransferWarningSingular": { - "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "message": "1 benda akan dipindahkan selamanya ke $ORG$. Anda tidak akan lagi memiliki benda ini.", "placeholders": { "org": { "content": "$1", @@ -4776,7 +4861,7 @@ } }, "personalItemsWithOrgTransferWarningPlural": { - "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", + "message": "$PERSONAL_ITEMS_COUNT$ benda akan dipindahkan selamanya ke $ORG$. Anda tidak akan lagi memiliki benda-benda tersebut.", "placeholders": { "personal_items_count": { "content": "$1", @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Authenticating" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Pemberitahuan penting" - }, - "setupTwoStepLogin": { - "message": "Siapkan log masuk dua langkah" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden akan mengirim suatu kode ke akun surel Anda untuk memverifikasi log masuk dari perangkat baru sejak Februari 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "Anda dapat menyiapkan log masuk dua langkah sebagai cara alternatif untuk melindungi akun Anda atau mengubah surel Anda ke yang bisa Anda akses." - }, - "remindMeLater": { - "message": "Ingatkan saya nanti" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Apakah Anda punya akses yang handal ke surel Anda, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "Tidak" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Ya, saya dapat mengakses surel saya secara handla" - }, - "turnOnTwoStepLogin": { - "message": "Nyalakan log masuk dua langkah" - }, - "changeAcctEmail": { - "message": "Ubah surel akun" - }, "extensionWidth": { "message": "Lebar ekstensi" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,37 +5307,82 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Situs web", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "agar info masuk ini muncul sebagai saran pengisian otomatis.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { - "message": "Seamless online checkout" + "message": "Pembayaran daring yang lancar" }, "newCardNudgeBody": { - "message": "With cards, easily autofill payment forms securely and accurately." + "message": "Dengan kartu, isi otomatis dengan mudah formulir pembayaran secara aman dan akurat." }, "newIdentityNudgeTitle": { - "message": "Simplify creating accounts" + "message": "Sederhanakan pembuatan akun" }, "newIdentityNudgeBody": { - "message": "With identities, quickly autofill long registration or contact forms." + "message": "Dengan identitas, isi otomatis dengan cepat formulir pendaftaran atau kontrak yang panjang." }, "newNoteNudgeTitle": { - "message": "Keep your sensitive data safe" + "message": "Menjaga data sensitif Anda tetap aman" }, "newNoteNudgeBody": { - "message": "With notes, securely store sensitive data like banking or insurance details." + "message": "Dengan catatan, simpan secara aman data sensitif seperti rincian perbankan atau asuransi." }, "newSshNudgeTitle": { - "message": "Developer-friendly SSH access" + "message": "Akses SSH yang ramah pengembang" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Simpan kunci-kunci Anda dan sambungkan dengan agen SSH untuk otentikasi yang cepat dan terenkripsi.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Pelajari lebih lanjut tentang agen SSH", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/it/messages.json b/apps/browser/src/_locales/it/messages.json index 724416cdcde..77be022e58c 100644 --- a/apps/browser/src/_locales/it/messages.json +++ b/apps/browser/src/_locales/it/messages.json @@ -3,7 +3,7 @@ "message": "Bitwarden" }, "appLogoLabel": { - "message": "Bitwarden logo" + "message": "Logo di Bitwarden" }, "extName": { "message": "Bitwarden Password Manager", @@ -23,7 +23,7 @@ "message": "Crea account" }, "newToBitwarden": { - "message": "Sei un nuovo utente?" + "message": "Sei nuovo su Bitwarden?" }, "logInWithPasskey": { "message": "Accedi con passkey" @@ -32,7 +32,7 @@ "message": "Usa il Single Sign-On" }, "welcomeBack": { - "message": "Bentornat*" + "message": "Bentornato/a" }, "setAStrongPassword": { "message": "Imposta una password robusta" @@ -887,7 +887,7 @@ "message": "Segui i passaggi qui sotto per completare l'accesso." }, "followTheStepsBelowToFinishLoggingInWithSecurityKey": { - "message": "Follow the steps below to finish logging in with your security key." + "message": "Segui i passaggi seguenti per finire di accedere con la tua chiave di sicurezza." }, "restartRegistration": { "message": "Ricomincia la registrazione" @@ -1063,7 +1063,7 @@ "message": "Salva" }, "notificationViewAria": { - "message": "View $ITEMNAME$, opens in new window", + "message": "Visualizza $ITEMNAME$, si apre in una nuova finestra", "placeholders": { "itemName": { "content": "$1" @@ -1071,15 +1071,19 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "Nuovo elemento, si apre in una nuova finestra", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { - "message": "Edit before saving", + "message": "Modifica prima di salvare", "description": "Tooltip and Aria label for edit button on cipher item" }, "newNotification": { - "message": "New notification" + "message": "Nuova notifica" }, "labelWithNotification": { - "message": "$LABEL$: New notification", + "message": "$LABEL$: Nuova notifica", "description": "Label for the notification with a new login suggestion.", "placeholders": { "label": { @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "salvato in Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "aggiornato in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Seleziona $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Salva come nuovo accesso", "description": "Button text for saving login details as a new entry." @@ -1114,12 +1120,16 @@ "message": "Aggiorna accesso", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Sblocca per salvare questo login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { - "message": "Save login", + "message": "Salva il login", "description": "Prompt asking the user if they want to save their login details." }, "updateLogin": { - "message": "Update existing login", + "message": "Aggiorna login esistente", "description": "Prompt asking the user if they want to update an existing login entry." }, "loginSaveSuccess": { @@ -1131,7 +1141,7 @@ "description": "Message displayed when login details are successfully updated." }, "loginUpdateTaskSuccess": { - "message": "Great job! You took the steps to make you and $ORGANIZATION$ more secure.", + "message": "Congratulazioni! Hai reso $ORGANIZATION$ e te stesso più sicuri.", "placeholders": { "organization": { "content": "$1" @@ -1140,7 +1150,7 @@ "description": "Shown to user after login is updated." }, "loginUpdateTaskSuccessAdditional": { - "message": "Thank you for making $ORGANIZATION$ more secure. You have $TASK_COUNT$ more passwords to update.", + "message": "Grazie per aver reso $ORGANIZATION$ più sicuro. Hai altre $TASK_COUNT$ password da aggiornare.", "placeholders": { "organization": { "content": "$1" @@ -1152,7 +1162,7 @@ "description": "Shown to user after login is updated." }, "nextSecurityTaskAction": { - "message": "Change next password", + "message": "Cambia la prossima password", "description": "Message prompting user to undertake completion of another security task." }, "saveFailure": { @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Suggerimenti per il riempimento automatico" }, + "autofillSpotlightTitle": { + "message": "Trova facilmente suggerimenti di riempimento automatico" + }, + "autofillSpotlightDesc": { + "message": "Disattiva le impostazioni di riempimento automatico del tuo browser, in modo da non entrare in conflitto con Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Disattiva il riempimento automatico di $BROWSER$", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Disattiva il riempimento automatico" + }, "showInlineMenuLabel": { "message": "Mostra suggerimenti di riempimento automatico nei campi del modulo" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Usa questa password" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Usa questo nome utente" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Azione al timeout" }, - "newCustomizationOptionsCalloutTitle": { - "message": "Nuove opzioni di personalizzazione" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Personalizza l'esperienza della tua cassaforte con azioni di copia rapida, modalità compatta e altro ancora!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "Vedi tutte le impostazioni di aspetto" - }, "lock": { "message": "Blocca", "description": "Verb form: to make secure or inaccessible by" @@ -2355,7 +2377,7 @@ "message": "Informativa sulla Privacy" }, "yourNewPasswordCannotBeTheSameAsYourCurrentPassword": { - "message": "Your new password cannot be the same as your current password." + "message": "La tua nuova password non può essere la stessa della tua password attuale." }, "hintEqualsPassword": { "message": "Il suggerimento della password non può essere uguale alla password." @@ -2565,14 +2587,14 @@ "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, "reviewAtRiskLoginSlideImgAltPeriod": { - "message": "Illustration of a list of logins that are at-risk." + "message": "Illustrazione di una lista di login a rischio." }, "generatePasswordSlideDesc": { "message": "Genera rapidamente una parola d'accesso forte e unica con il menu' di riempimento automatico Bitwarden nel sito a rischio.", "description": "Description of the generate password slide on the at-risk password page carousel" }, "generatePasswordSlideImgAltPeriod": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password." + "message": "Illustrazione del menu di riempimento automatico Bitwarden che mostra una password generata." }, "updateInBitwarden": { "message": "Aggiorna in Bitwarden" @@ -2582,7 +2604,7 @@ "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, "updateInBitwardenSlideImgAltPeriod": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." + "message": "Illustrazione di una notifica Bitwarden che richiede all'utente di aggiornare il login." }, "turnOnAutofill": { "message": "Attiva riempimento automatico" @@ -2655,6 +2677,10 @@ "message": "Tutti i Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Nascondi testo come default" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Nessun identificatore univoco trovato." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ sta usando SSO con un server self-hosted. Una password principale non è più necessaria per accedere per i membri di questa organizzazione.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "La password principale non è più richiesta per i membri dell'organizzazione. Per favore, conferma il dominio qui sotto con l'amministratore." + }, + "organizationName": { + "message": "Nome organizzazione" + }, + "keyConnectorDomain": { + "message": "Dominio Key Connector" }, "leaveOrganization": { "message": "Lascia organizzazione" @@ -3038,7 +3064,7 @@ } }, "exportingIndividualVaultWithAttachmentsDescription": { - "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "message": "Solo gli elementi della cassaforte personale associati a $EMAIL$, includendo gli allegati, saranno esportati. Gli elementi della cassaforte dell'organizzazione non saranno inclusi", "placeholders": { "email": { "content": "$1", @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Dispositivo fidato" }, + "trustOrganization": { + "message": "Fidati dell'organizzazione" + }, + "trust": { + "message": "Fidati" + }, + "doNotTrust": { + "message": "Non fidarti" + }, + "organizationNotTrusted": { + "message": "L'organizzazione non è fidata" + }, + "emergencyAccessTrustWarning": { + "message": "Per la sicurezza del tuo account, conferma solo se hai concesso l'accesso di emergenza a questo utente e le loro impronte digitali corrispondono a quelle contenute nel loro account" + }, + "orgTrustWarning": { + "message": "Per la sicurezza del tuo account, procedi solo se sei un membro di questa organizzazione, il recupero dell'account è abilitato e l'impronta digitale visualizzata di seguito corrisponde all'impronta digitale dell'organizzazione." + }, + "orgTrustWarning1": { + "message": "Questa organizzazione ha una politica Enterprise che ti iscriverà al recupero dell'account. La registrazione consentirà agli amministratori dell'organizzazione di modificare la password. Procedi solo se riconosci questa organizzazione e la frase di impronta digitale mostrata di seguito corrisponde all'impronta digitale dell'organizzazione." + }, + "trustUser": { + "message": "Fidati dell'utente" + }, "sendsNoItemsTitle": { "message": "Nessun Send attivo", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Utilizza un Send per condividere in modo sicuro le informazioni con qualsiasi utente.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Invia informazioni sensibili in modo sicuro", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Condividi file e dati in modo sicuro con chiunque, su qualsiasi piattaforma. Le tue informazioni saranno crittografate end-to-end.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Input obbligatorio." }, @@ -4304,7 +4362,7 @@ } }, "viewItemTitleWithField": { - "message": "View item - $ITEMNAME$ - $FIELD$", + "message": "Visualizza elemento - $ITEMNAME$ - $FIELD$", "description": "Title for a link that opens a view for an item.", "placeholders": { "itemname": { @@ -4328,7 +4386,7 @@ } }, "autofillTitleWithField": { - "message": "Autofill - $ITEMNAME$ - $FIELD$", + "message": "Riempimento automatico - $ITEMNAME$ - $FIELD$", "description": "Title for a button that autofills a login item.", "placeholders": { "itemname": { @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Scarica Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Scarica Bitwarden su tutti i dispositivi" + }, + "getTheMobileApp": { + "message": "Scarica l'app mobile" + }, + "getTheMobileAppDesc": { + "message": "Accedi alle tue password ovunque con l'app Bitwarden per dispositivi mobili." + }, + "getTheDesktopApp": { + "message": "Scarica l'app desktop" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Scarica ora da bitwarden.com" + }, + "getItOnGooglePlay": { + "message": "Disponible su Google Play" + }, + "downloadOnTheAppStore": { + "message": "Scarica dall'App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Sei sicuro di voler eliminare definitivamente questo allegato?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Lo sblocco biometrico non è attualmente disponibile per un motivo sconosciuto." }, + "unlockVault": { + "message": "Sblocca la cassaforte in secondi" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Sblocca PIN impostato" + }, "authenticating": { "message": "Autenticazione" }, @@ -4961,7 +5055,7 @@ "description": "Notification message for when a password has been regenerated" }, "saveToBitwarden": { - "message": "Save to Bitwarden", + "message": "Salva su Bitwarden", "description": "Confirmation message for saving a login to Bitwarden" }, "spaceCharacterDescriptor": { @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Avviso importante" - }, - "setupTwoStepLogin": { - "message": "Imposta accesso in due passaggi" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden invierà un codice all'email del tuo account per verificare gli accessi da nuovi dispositivi a partire da febbraio 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "Puoi impostare l'accesso in due passaggi come modo alternativo per proteggere il tuo account, o cambiare la tua e-mail in una alla quale puoi accedere." - }, - "remindMeLater": { - "message": "Ricordamelo più tardi" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Riesci ancora ad accedere a questa email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, non riesco" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Sì, riesco ad accedere a questa email" - }, - "turnOnTwoStepLogin": { - "message": "Attiva accesso in due passaggi" - }, - "changeAcctEmail": { - "message": "Cambia l'email dell'account" - }, "extensionWidth": { "message": "Larghezza estensione" }, @@ -5202,13 +5260,13 @@ "message": "Cambia parola d'accesso a rischio" }, "settingsVaultOptions": { - "message": "Vault options" + "message": "Opzioni cassaforte" }, "emptyVaultDescription": { "message": "The vault protects more than just your passwords. Store secure logins, IDs, cards and notes securely here." }, "introCarouselLabel": { - "message": "Welcome to Bitwarden" + "message": "Benvenuto su Bitwarden" }, "securityPrioritized": { "message": "Security, prioritized" @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/ja/messages.json b/apps/browser/src/_locales/ja/messages.json index be70cd7d939..e66d0a2454c 100644 --- a/apps/browser/src/_locales/ja/messages.json +++ b/apps/browser/src/_locales/ja/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "新規のログイン情報として保存", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "ログイン情報を更新", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "自動入力の候補" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "フォームフィールドに自動入力の候補を表示する" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "このパスワードを使用する" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "このユーザー名を使用する" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "タイムアウト時のアクション" }, - "newCustomizationOptionsCalloutTitle": { - "message": "新しいカスタマイズオプション" - }, - "newCustomizationOptionsCalloutContent": { - "message": "クイックコピーやコンパクトモードなどで保管庫をカスタマイズできます!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "すべての外観設定を表示" - }, "lock": { "message": "ロック", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "すべての Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "デフォルトでテキストを隠す" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "一意の識別子が見つかりませんでした。" }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ は自己ホストの鍵サーバで SSO を使用しています。この組織のメンバーのログインにマスターパスワードは必要ありません。", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "組織から脱退する" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "信頼されたデバイス" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "アクティブな Send なし", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Send を使用すると暗号化された情報を誰とでも安全に共有できます。", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "入力が必要です。" }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "この添付ファイルを完全に削除してもよろしいですか?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "生体認証によるロック解除は、不明な理由により現在利用できません。" }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "認証中" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "ベータ" }, - "importantNotice": { - "message": "重要なお知らせ" - }, - "setupTwoStepLogin": { - "message": "2段階認証を設定する" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden は2025年2月以降、新しいデバイスからのログイン時にアカウントのメールアドレスに確認コードを送信します。" - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "代わりに2段階認証によるログインでアカウントを保護するか、メールアドレスをあなたがアクセスできるものに変更できます。" - }, - "remindMeLater": { - "message": "後で再通知" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "メールアドレス $EMAIL$ は、確実にアクセスできるものですか?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "いいえ、違います。" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "はい、メールアドレスには私が確実にアクセスできます" - }, - "turnOnTwoStepLogin": { - "message": "2段階認証によるログインを有効にする" - }, - "changeAcctEmail": { - "message": "アカウントのメールアドレスを変更する" - }, "extensionWidth": { "message": "拡張機能の幅" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Bitwarden のモバイル、ブラウザ、デスクトップアプリでは、保存できるパスワード数やデバイス数に制限はありません。" }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/ka/messages.json b/apps/browser/src/_locales/ka/messages.json index bb4a9be2a6c..afd301305ff 100644 --- a/apps/browser/src/_locales/ka/messages.json +++ b/apps/browser/src/_locales/ka/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Autofill suggestions" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Show autofill suggestions on form fields" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Use this password" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Use this username" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Timeout action" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "ჩაკეტვა", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "All Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Hide text by default" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ is using SSO with a self-hosted key server. A master password is no longer required to log in for members of this organization.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Leave organization" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Device trusted" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "No active Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Use Send to securely share encrypted information with anyone.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Input is required." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Are you sure you want to permanently delete this attachment?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "ავთენტიკაცია" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Important notice" - }, - "setupTwoStepLogin": { - "message": "Set up two-step login" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Remind me later" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" - }, - "turnOnTwoStepLogin": { - "message": "Turn on two-step login" - }, - "changeAcctEmail": { - "message": "Change account email" - }, "extensionWidth": { "message": "Extension width" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/km/messages.json b/apps/browser/src/_locales/km/messages.json index 99a09c75d41..29223942fd6 100644 --- a/apps/browser/src/_locales/km/messages.json +++ b/apps/browser/src/_locales/km/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Autofill suggestions" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Show autofill suggestions on form fields" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Use this password" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Use this username" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Timeout action" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "Lock", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "All Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Hide text by default" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ is using SSO with a self-hosted key server. A master password is no longer required to log in for members of this organization.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Leave organization" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Device trusted" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "No active Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Use Send to securely share encrypted information with anyone.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Input is required." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Are you sure you want to permanently delete this attachment?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Authenticating" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Important notice" - }, - "setupTwoStepLogin": { - "message": "Set up two-step login" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Remind me later" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" - }, - "turnOnTwoStepLogin": { - "message": "Turn on two-step login" - }, - "changeAcctEmail": { - "message": "Change account email" - }, "extensionWidth": { "message": "Extension width" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/kn/messages.json b/apps/browser/src/_locales/kn/messages.json index 408727f7ec8..6065dec254f 100644 --- a/apps/browser/src/_locales/kn/messages.json +++ b/apps/browser/src/_locales/kn/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Autofill suggestions" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Show autofill suggestions on form fields" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Use this password" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Use this username" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Timeout action" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "ಲಾಕ್‌", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "ಎಲ್ಲಾ ಕಳುಹಿಸುತ್ತದೆ", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Hide text by default" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ is using SSO with a self-hosted key server. A master password is no longer required to log in for members of this organization.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Leave organization" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Device trusted" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "No active Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Use Send to securely share encrypted information with anyone.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Input is required." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Are you sure you want to permanently delete this attachment?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Authenticating" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Important notice" - }, - "setupTwoStepLogin": { - "message": "Set up two-step login" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Remind me later" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" - }, - "turnOnTwoStepLogin": { - "message": "Turn on two-step login" - }, - "changeAcctEmail": { - "message": "Change account email" - }, "extensionWidth": { "message": "Extension width" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/ko/messages.json b/apps/browser/src/_locales/ko/messages.json index 01cb0fbf7c3..ef3402dc496 100644 --- a/apps/browser/src/_locales/ko/messages.json +++ b/apps/browser/src/_locales/ko/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "자동 완성 제안" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "양식 필드에 자동 완성 제안 표시" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "이 비밀번호 사용" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "이 사용자 이름 사용" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "시간초과 시 행동" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "잠금", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "모든 Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "기본적으로 텍스트 숨기기" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "고유 식별자를 찾을 수 없습니다." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ 조직은 자체 호스팅 키 서버로 SSO를 사용하고 있습니다 이 조직의 멤버들은 로그인할 때에 마스터 비밀번호를 필요로 하지 않습니다.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "조직 나가기" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "신뢰할 수 있는 장치" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "활성화된 Send없음", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Send를 사용하여 암호화된 정보를 어느 사람과도 안전하게 공유합니다.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "입력이 필요합니다." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "정말로 이 첨부파일을 영구적으로 삭제하시겠습니까?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "인증 중" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "베타" }, - "importantNotice": { - "message": "Important notice" - }, - "setupTwoStepLogin": { - "message": "Set up two-step login" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Remind me later" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" - }, - "turnOnTwoStepLogin": { - "message": "Turn on two-step login" - }, - "changeAcctEmail": { - "message": "Change account email" - }, "extensionWidth": { "message": "확장 폭" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/lt/messages.json b/apps/browser/src/_locales/lt/messages.json index 51879334614..82952be642c 100644 --- a/apps/browser/src/_locales/lt/messages.json +++ b/apps/browser/src/_locales/lt/messages.json @@ -3,7 +3,7 @@ "message": "Bitwarden" }, "appLogoLabel": { - "message": "Bitwarden logo" + "message": "Bitwarden logotipas" }, "extName": { "message": "„Bitwarden“ slaptažodžių tvarkyklė", @@ -23,16 +23,16 @@ "message": "Sukurti paskyrą" }, "newToBitwarden": { - "message": "New to Bitwarden?" + "message": "Pirmą kartą Bitwarden?" }, "logInWithPasskey": { - "message": "Log in with passkey" + "message": "Prisijungti naudojant prieigos raktą" }, "useSingleSignOn": { "message": "Use single sign-on" }, "welcomeBack": { - "message": "Welcome back" + "message": "Sveiki sugrįžę" }, "setAStrongPassword": { "message": "Nustatyti stiprų slaptažodį" @@ -84,7 +84,7 @@ "message": "Pagrindinio slaptažodžio užuomina (neprivaloma)" }, "passwordStrengthScore": { - "message": "Password strength score $SCORE$", + "message": "Slaptažodžio stiprumas $SCORE$", "placeholders": { "score": { "content": "$1", @@ -93,10 +93,10 @@ } }, "joinOrganization": { - "message": "Join organization" + "message": "Prisijungti prie organizacijos" }, "joinOrganizationName": { - "message": "Join $ORGANIZATIONNAME$", + "message": "Prisijungti prie $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -105,7 +105,7 @@ } }, "finishJoiningThisOrganizationBySettingAMasterPassword": { - "message": "Finish joining this organization by setting a master password." + "message": "Baigėte prisijungimą prie organizacijos nustatant pagrindinį slaptažodį." }, "tab": { "message": "Skirtukas" @@ -132,7 +132,7 @@ "message": "Kopijuoti slaptažodį" }, "copyPassphrase": { - "message": "Copy passphrase" + "message": "Kopijuoti slaptažodžio frazę" }, "copyNote": { "message": "Kopijuoti pastabą" @@ -150,31 +150,31 @@ "message": "Kopijuoti saugos kodą" }, "copyName": { - "message": "Copy name" + "message": "Kopijuoti vardą" }, "copyCompany": { - "message": "Copy company" + "message": "Kopijuoti įmonę" }, "copySSN": { - "message": "Copy Social Security number" + "message": "Kopijuoti socialinės apsaugos numerį" }, "copyPassportNumber": { - "message": "Copy passport number" + "message": "Kopijuoti paso numerį" }, "copyLicenseNumber": { - "message": "Copy license number" + "message": "Kopijuoti licenzijos numerį" }, "copyPrivateKey": { - "message": "Copy private key" + "message": "Kopijuoti privatų raktą" }, "copyPublicKey": { - "message": "Copy public key" + "message": "Kopijuoti viešą raktą" }, "copyFingerprint": { - "message": "Copy fingerprint" + "message": "Kopijuoti piršto antspaudą" }, "copyCustomField": { - "message": "Copy $FIELD$", + "message": "Kopijuoti $FIELD$", "placeholders": { "field": { "content": "$1", @@ -183,13 +183,13 @@ } }, "copyWebsite": { - "message": "Copy website" + "message": "Kopijuoti svetainę" }, "copyNotes": { - "message": "Copy notes" + "message": "Kopijuoti pastabas" }, "copy": { - "message": "Copy", + "message": "Kopijuoti", "description": "Copy to clipboard" }, "fill": { @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Autofill suggestions" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Show autofill suggestions on form fields" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Use this password" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Use this username" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Timeout action" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "Užrakinti", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "Visi siuntimai", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Hide text by default" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Unikalus identifikatorius nerastas." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ naudoja SSO su savarankiškai sukurtu raktų serveriu. Pagrindinis slaptažodis nebėra reikalingas norint šios organizacijos nariams prisijungti.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Palikti organizaciją" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Patikimas įrenginys" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "Nėra aktyvų „Sends“", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Naudokite „Send“, kad saugiai bendrintumėte užšifruotą informaciją su bet kuriuo asmeniu.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Input is required." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Ar tikrai norite negrįžtamai ištrinti šį priedą?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Authenticating" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Important notice" - }, - "setupTwoStepLogin": { - "message": "Set up two-step login" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Remind me later" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" - }, - "turnOnTwoStepLogin": { - "message": "Turn on two-step login" - }, - "changeAcctEmail": { - "message": "Change account email" - }, "extensionWidth": { "message": "Extension width" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/lv/messages.json b/apps/browser/src/_locales/lv/messages.json index 6c39d9ff3e6..23e6d015853 100644 --- a/apps/browser/src/_locales/lv/messages.json +++ b/apps/browser/src/_locales/lv/messages.json @@ -273,7 +273,7 @@ "message": "Turpināt" }, "sendVerificationCode": { - "message": "Sūtīt apstiprinājuma kodu uz e-pastu" + "message": "Nosūtīt apliecinājuma kodu e-pastā" }, "sendCode": { "message": "Nosūtīt kodu" @@ -282,7 +282,7 @@ "message": "Kods nosūtīts" }, "verificationCode": { - "message": "Apstiprināšanas kods" + "message": "Apliecinājuma kods" }, "confirmIdentity": { "message": "Jāapliecina sava identitāte, lai turpinātu." @@ -811,13 +811,13 @@ "message": "Mēs nosūtījām galvenās paroles norādi e-pastā." }, "verificationCodeRequired": { - "message": "Apstiprinājuma kods ir nepieciešams." + "message": "Apliecinājuma kods ir nepieciešams." }, "webauthnCancelOrTimeout": { "message": "Autentifikācija tika atcelta vai tā aizņēma pārāk daudz laika. Lūgums mēģināt vēlreiz." }, "invalidVerificationCode": { - "message": "Nederīgs apstiprinājuma kods" + "message": "Nederīgs apliecinājuma kods" }, "valueCopied": { "message": "$VALUE$ ir starpliktuvē", @@ -845,10 +845,10 @@ "message": "Padarīt divpakāpju apliecināšanu plūdenu" }, "totpHelper": { - "message": "Bitwarden var glabāt un aizpildīt divpakāpju apliecināšanas kodus. Atslēga jāievieto starpliktuvē un jāielīmē šajā laukā." + "message": "Bitwarden var glabāt un aizpildīt divpakāpju apliecinājuma kodus. Atslēga jāievieto starpliktuvē un jāielīmē šajā laukā." }, "totpHelperWithCapture": { - "message": "Bitwarden var glabāt un aizpildīt divpakāpju apliecināšanas kodus. Jāizvēlas kameras ikona, lai veiktu tīmekļvietnes autentificētāja kvadrātkoda ekrānuzņēmumu, vai jāievieto starpliktuvē atslēga un jāielīmē šajā laukā." + "message": "Bitwarden var glabāt un aizpildīt divpakāpju apliecinājuma kodus. Jāizvēlas kameras ikona, lai veiktu tīmekļvietnes autentificētāja kvadrātkoda ekrānuzņēmumu, vai jāievieto starpliktuvē atslēga un jāielīmē šajā laukā." }, "learnMoreAboutAuthenticators": { "message": "Uzzināt vairāk par autentificētājiem" @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "Jauns vienums, atvērsies jaunā logā", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Labot pirms saglabāšanas", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saglabāts Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saglabāts Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ atjaunināts Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "atjaunināts Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Atlasīt $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Saglabāt kā jaunu pieteikšanās vienumu", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Atjaunināt pieteikšanās vienumu", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Jāatslēdz, lai saglabātu šo pieteikšanās vienumu", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Saglabāt pieteikšanās vienumu", "description": "Prompt asking the user if they want to save their login details." @@ -1314,10 +1324,10 @@ "message": "Autentificētāja atslēga (TOTP)" }, "verificationCodeTotp": { - "message": "Apstiprinājuma kods (TOTP)" + "message": "Apliecinājuma kods (TOTP)" }, "copyVerificationCode": { - "message": "Ievietot apstiprinājuma kodu starpliktuvē" + "message": "Ievietot apliecinājuma kodu starpliktuvē" }, "attachments": { "message": "Pielikumi" @@ -1389,7 +1399,7 @@ "message": "Paroļu higiēnas, konta veselības un datu noplūžu pārskati, lai uzturētu glabātavu drošu." }, "ppremiumSignUpTotp": { - "message": "TOTP apstiprinājuma koda (2FA) veidotājs glabātavas pieteikšanās vienumiem." + "message": "TOTP apliecinājuma koda (2FA) veidotājs glabātavas pieteikšanās vienumiem." }, "ppremiumSignUpSupport": { "message": "Priekšrocīgs lietotāju atbalsts." @@ -1437,7 +1447,7 @@ "message": "Automātiski ievietot TOTP starpliktuvē" }, "disableAutoTotpCopyDesc": { - "message": "Ja pieteikšanās vienumam ir pievienota autentificētāja atslēga, TOTP apstiprinājuma kods tiks automātiski ievietots starpliktuvē, kad vien tiks automātiski aizpildīta pieteikšanās veidne." + "message": "Ja pieteikšanās vienumam ir pievienota autentificētāja atslēga, TOTP apliecinājuma kods tiks automātiski ievietots starpliktuvē, kad vien tiks automātiski aizpildīta pieteikšanās veidne." }, "enableAutoBiometricsPrompt": { "message": "Palaižot vaicāt biometriju" @@ -1455,7 +1465,7 @@ "message": "Iestājās autentificēšanās sesijas noildze. Lūgums sākt pieteikšanos no jauna." }, "verificationCodeEmailSent": { - "message": "E-pasts apstiprināšanai nosūtīts uz $EMAIL$.", + "message": "Apliecinājuma e-pasta ziņojums nosūtīts uz $EMAIL$.", "placeholders": { "email": { "content": "$1", @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Automātiskās aizpildes ieteikumi" }, + "autofillSpotlightTitle": { + "message": "Viegla automātiskās aizpildes ieteikumu atrašana" + }, + "autofillSpotlightDesc": { + "message": "Jāizslēdz sava pārlūka automātiskās aizpildes iestatījumi, lai tie nebūtu pretrunā ar Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Izslēgt $BROWSER$ automātisko aizpildi", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Izslēgt automātisko aizpildi" + }, "showInlineMenuLabel": { "message": "Rādīt automātiskās aizpildes ieteikumuis veidlapu laukos" }, @@ -1718,7 +1746,7 @@ "description": "This describes a value that is 'linked' (tied) to another value." }, "popup2faCloseMessage": { - "message": "Klikšķināšana ārpus uznirstošā loga, lai e-pastā apskatītu apstiprinājuma kodu, to aizvērs. Vai atvērt to atsevišķā logā, lai tas netiktu aizvērts?" + "message": "Klikšķināšana ārpus uznirstošā loga, lai e-pastā apskatītu apliecinājuma kodu, to aizvērs. Vai atvērt to atsevišķā logā, lai tas netiktu aizvērts?" }, "popupU2fCloseMessage": { "message": "Šis pārlūks nevar apstrādāt U2F pieprasījumus šajā uznirstošajā logā. Vai atvērt to atsevišķā logā, lai varētu pieteikties, izmantojot U2F?" @@ -2008,7 +2036,7 @@ "description": "A URL's host value. For example, the host of https://sub.domain.com:443 is 'sub.domain.com:443'." }, "exact": { - "message": "Tiešs" + "message": "Tieši" }, "startsWith": { "message": "Sākas ar" @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Izmantot šo paroli" }, + "useThisPassphrase": { + "message": "Izmantot šo paroles vārdkopu" + }, "useThisUsername": { "message": "Izmantot šo lietotājvārdu" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Noildzes darbība" }, - "newCustomizationOptionsCalloutTitle": { - "message": "Jaunas pielāgošanas iespējas" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Savu glabātavas pieredzi var pielāgot ar ātrām kopēšanas darbībām, ciešo izkārtojumu un vēl." - }, - "newCustomizationOptionsCalloutLink": { - "message": "Apskatīt visus izskata iestatījumus" - }, "lock": { "message": "Slēgt", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "Visi Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Pēc noklusējuma paslēpt tekstu" }, @@ -2849,13 +2875,13 @@ "message": "Šī darbība ir aizsargāta. Lai turpinātu, ir jāievada galvenā parole, lai apliecinātu savu identitāti." }, "emailVerificationRequired": { - "message": "Nepieciešama e-pasta adreses apstiprināšana" + "message": "Nepieciešama e-pasta adreses apliecināšana" }, "emailVerifiedV2": { "message": "E-pasta adrese ir apliecināta" }, "emailVerificationRequiredDesc": { - "message": "Ir nepieciešams apstiprināt e-pasta adresi, lai būtu iespējams izmantot šo iespēju. To var izdarīt tīmekļa glabātavā." + "message": "Ir nepieciešams apliecināt savu e-pasta adresi, lai būtu iespējams izmantot šo iespēju. To var izdarīt tīmekļa glabātavā." }, "updatedMasterPassword": { "message": "Galvenā parole atjaunināta" @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Nav atrasts neviens neatkārtojams identifikators" }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ izmanto vienoto pieteikšanos ar pašmitinātu atslēgu serveri. Tās dalībniekiem vairs nav nepieciešama galvenā parole, lai pieteiktos.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "Galvenā parole vairs nav nepieciešama turpmāk minētās apvienības dalībniekiem. Lūgums saskaņot zemāk esošo domēnu ar savas apvienības pārvaldītāju." + }, + "organizationName": { + "message": "Apvienības nosaukums" + }, + "keyConnectorDomain": { + "message": "Key Connector domēns" }, "leaveOrganization": { "message": "Pamest apvienību" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Ierīce ir uzticama" }, + "trustOrganization": { + "message": "Uzticēties apvienībai" + }, + "trust": { + "message": "Uzticēties" + }, + "doNotTrust": { + "message": "Neuzticēties" + }, + "organizationNotTrusted": { + "message": "Apvienība nav uzticama" + }, + "emergencyAccessTrustWarning": { + "message": "Lai nodrošinātu sava konta drošību, jāapstiprina tikai tad, ja šim lietotājam ir nodrošināta ārkārtas piekļuve un tā pirkstu nospiedums atbilsta tam, kas ir attēlots tā kontā" + }, + "orgTrustWarning": { + "message": "Lai nodrošinātu sava konta drošību, jāturpina tikai tad, ja esi šīs apvienības dalībnieks, ir iespējota konta atkope un zemāk attēlotais pirkstu nospiedums atbilst apvienības pirkstu nospiedumam." + }, + "orgTrustWarning1": { + "message": "Šai apvienībai ir uzņēmējdarbības pamatnostādne, kas Tevi iekļaus konta atkopē. Iekļaušana ļaus apvienības pārvaldītājiem nomainīt Tavu paroli. Turpini tikai tad, ja zini šo apvienību un zemāk attēlotā pirkstu nospieduma vārdkopa atbilst apvienības pirkstu nospiedumam!" + }, + "trustUser": { + "message": "Uzticēties lietotājam" + }, "sendsNoItemsTitle": { "message": "Nav spēkā esošu Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Send ir izmantojams, lai ar ikvienu droši kopīgotu šifrētu informāciju.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Drošā veidā nosūti jūtīgu informāciju", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Drošā veidā kopīgo datnes un datus ar ikvienu jebkurā platformā! Tava informācija paliks pilnībā šifrēta, vienlaikus ierobežojot riskantumu.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Jāievada vērtība." }, @@ -3738,7 +3796,7 @@ "description": "Screen reader text (aria-label) for unlock account button in overlay" }, "totpCodeAria": { - "message": "Laikā balstīts vienreizējas izmantošanas paroles apliecināšanas kods", + "message": "Laikā balstīts vienreizējas izmantošanas paroles apliecinājuma kods", "description": "Aria label for the totp code displayed in the inline menu for autofill" }, "totpSecondsSpanAria": { @@ -3831,7 +3889,7 @@ "message": "Jāmēģina vēlreiz" }, "verificationRequiredForActionSetPinToContinue": { - "message": "Šai darbībai ir nepieciešama apliecināšana. Jāiestata PIN, lai turpinātu." + "message": "Šai darbībai ir nepieciešama apliecinājums. Jāiestata PIN, lai turpinātu." }, "setPin": { "message": "Iestatīt PIN" @@ -3977,7 +4035,7 @@ "message": "Piekļuves atslēga netiks ievietota klonētajā vienumā. Vai turpināt šī vienuma klonēšanu?" }, "passkeyFeatureIsNotImplementedForAccountsWithoutMasterPassword": { - "message": "Vietne, kurā tika uzsākta darbība, pieprasa pārbaudi. Šī iespēja vēl nav īstenota kontiem, kuriem nav galvenās paroles." + "message": "Vietne, kurā tika uzsākta darbība, pieprasa apliecinājumu. Šī iespēja vēl nav īstenota kontiem, kuriem nav galvenās paroles." }, "logInWithPasskeyQuestion": { "message": "Pieteikties ar piekļuves atslēgu?" @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Lejupielādē Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Lejupielādē Bitwarden visās ierīcēs" + }, + "getTheMobileApp": { + "message": "Iegūsti viedierīču lietotni" + }, + "getTheMobileAppDesc": { + "message": "Piekļūsti savām parolēm kustībā ar Bitwarden viedierīču lietotni!" + }, + "getTheDesktopApp": { + "message": "Iegūsti darbvirsmas lietotni" + }, + "getTheDesktopAppDesc": { + "message": "Piekļūsti savai glabātavai bez pārlūka, tad iestati atslēgšanu ar biometriju, lai paātrinātu atslēgšanu gan darbvirsmas lietotnē, gan pārlūka paplašinājumā!" + }, + "downloadFromBitwardenNow": { + "message": "Lejupielādē no bitwarden.com tagad" + }, + "getItOnGooglePlay": { + "message": "Iegūt to Google Play" + }, + "downloadOnTheAppStore": { + "message": "Lejupielādēt no App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Vai tiešām neatgriezeniski izdzēst šo pielikumu?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Atslēgšana ar biometriju pašlaik nav pieejama nezināma iemesla dēļ." }, + "unlockVault": { + "message": "Atslēdz savu glabātavu dažās sekundēs" + }, + "unlockVaultDesc": { + "message": "Tu vari pielāgot savus atslēgšanas un noildzes iestatījumus, lai ātrāk piekļūtu savai glabātavai." + }, + "unlockPinSet": { + "message": "Atslēgšanas PIN iestatīts" + }, "authenticating": { "message": "Autentificē" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Svarīgs paziņojums" - }, - "setupTwoStepLogin": { - "message": "Iestatīt divpakāpju pieteikšanos" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden, sākot ar 2025. gada februāri, nosūtīs kodu uz konta e-pasta adresi, lai apliecinātu pieteikšanos no jaunām ierīcēm." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "Var iestatīt divpakāpju pieteikšanos kā citu veidu, kā aizsargāt savu kontu, vai iestatīt savu e-pasta adresi uz tādu, kurai ir piekļuve." - }, - "remindMeLater": { - "message": "Atgādināt man vēlāk" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Vai ir uzticama piekļuve savai e-pasta adresei $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "Nē, nav" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Jā, varu uzticami piekļūt savam e-pastam" - }, - "turnOnTwoStepLogin": { - "message": "Ieslēgt divpakāpju pieteikšanos" - }, - "changeAcctEmail": { - "message": "Mainīt konta e-pasta adresi" - }, "extensionWidth": { "message": "Paplašinājuma platums" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Neierobežotu paroļu skaitu var saglabāt neierobežotā ierīdžu daudzumā ar Bitwarden viedtālruņa, pārlūka un darbvirsmas lietotni." }, + "nudgeBadgeAria": { + "message": "1 paziņojums" + }, "emptyVaultNudgeTitle": { "message": "Ievietot esošas paroles" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Laipni lūdzam Tavā glabātavā!" }, - "hasItemsVaultNudgeBody": { - "message": "Automātiskās aizpldes vienumu pašreizējai lapai\nIzlases vienumi vieglai piekļuvei\nPārējo var meklēt glabātavā" + "hasItemsVaultNudgeBodyOne": { + "message": "Automātiska pašreizējās lapas vienumu aizpildīšana" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Vienumu izlase vieglai piekļuvei" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Meklē savā glabātavā kaut ko citu" }, "newLoginNudgeTitle": { "message": "Laika ietaupīšana ar automātisko aizpildi" }, - "newLoginNudgeBody": { - "message": "Iekļauj tīmekļvietni, lai šis pieteikšanās vienums parādītos kā automātiskās aizpildes ieteikums!" + "newLoginNudgeBodyOne": { + "message": "Iekļauj", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "tīmekļvietni,", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "lai šis pieteikšanās vienums parādītos kā automātiskās aizpildes ieteikums!", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Plūdena apmaksa tiešsaistē" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Izstrādātājiem draudzīga SSH piekļuve" }, - "newSshNudgeBody": { - "message": "Glabā savas atslēgas un savienojies ar SSH aģentu ātrai, šifrētai autentificēšanai!" + "newSshNudgeBodyOne": { + "message": "Glabā savas atslēgas un savienojies ar SSH aģentu ātrai, šifrētai autentificēšanai!", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Uzzināt vairāk par SSH aģentu", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Ātra paroļu izveidošana" + }, + "generatorNudgeBodyOne": { + "message": "Vienkārša spēcīgu un neatkārtojamu paroļu izveidošana ar", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": ", lai palīdzētu uzturērt pieteikšanās vienumus drošus.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Vienkārša spēcīgu un neatkārtojamu paroļu izveidošana ar pogu \"Izveidot paroli\", lai palīdzētu uzturēt pieteikšanās vienumus drošus.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "Nav atļaujas apskatīt šo lapu. Jāmēģina pieteikties ar citu kontu." } } diff --git a/apps/browser/src/_locales/ml/messages.json b/apps/browser/src/_locales/ml/messages.json index 15d35d29c76..cb75a35bf7c 100644 --- a/apps/browser/src/_locales/ml/messages.json +++ b/apps/browser/src/_locales/ml/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Autofill suggestions" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Show autofill suggestions on form fields" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Use this password" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Use this username" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Timeout action" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "പൂട്ടുക", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "All Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Hide text by default" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ is using SSO with a self-hosted key server. A master password is no longer required to log in for members of this organization.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Leave organization" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Device trusted" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "No active Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Use Send to securely share encrypted information with anyone.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Input is required." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Are you sure you want to permanently delete this attachment?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Authenticating" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Important notice" - }, - "setupTwoStepLogin": { - "message": "Set up two-step login" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Remind me later" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" - }, - "turnOnTwoStepLogin": { - "message": "Turn on two-step login" - }, - "changeAcctEmail": { - "message": "Change account email" - }, "extensionWidth": { "message": "Extension width" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/mr/messages.json b/apps/browser/src/_locales/mr/messages.json index 8dee37bfcb8..c269bef17b6 100644 --- a/apps/browser/src/_locales/mr/messages.json +++ b/apps/browser/src/_locales/mr/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Autofill suggestions" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Show autofill suggestions on form fields" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Use this password" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Use this username" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Timeout action" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "Lock", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "All Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Hide text by default" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ is using SSO with a self-hosted key server. A master password is no longer required to log in for members of this organization.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Leave organization" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Device trusted" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "No active Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Use Send to securely share encrypted information with anyone.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Input is required." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Are you sure you want to permanently delete this attachment?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Authenticating" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Important notice" - }, - "setupTwoStepLogin": { - "message": "Set up two-step login" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Remind me later" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" - }, - "turnOnTwoStepLogin": { - "message": "Turn on two-step login" - }, - "changeAcctEmail": { - "message": "Change account email" - }, "extensionWidth": { "message": "Extension width" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/my/messages.json b/apps/browser/src/_locales/my/messages.json index 99a09c75d41..29223942fd6 100644 --- a/apps/browser/src/_locales/my/messages.json +++ b/apps/browser/src/_locales/my/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Autofill suggestions" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Show autofill suggestions on form fields" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Use this password" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Use this username" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Timeout action" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "Lock", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "All Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Hide text by default" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ is using SSO with a self-hosted key server. A master password is no longer required to log in for members of this organization.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Leave organization" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Device trusted" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "No active Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Use Send to securely share encrypted information with anyone.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Input is required." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Are you sure you want to permanently delete this attachment?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Authenticating" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Important notice" - }, - "setupTwoStepLogin": { - "message": "Set up two-step login" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Remind me later" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" - }, - "turnOnTwoStepLogin": { - "message": "Turn on two-step login" - }, - "changeAcctEmail": { - "message": "Change account email" - }, "extensionWidth": { "message": "Extension width" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/nb/messages.json b/apps/browser/src/_locales/nb/messages.json index f3d87aaa067..3f23ead23e6 100644 --- a/apps/browser/src/_locales/nb/messages.json +++ b/apps/browser/src/_locales/nb/messages.json @@ -3,7 +3,7 @@ "message": "Bitwarden" }, "appLogoLabel": { - "message": "Bitwarden logo" + "message": "Bitwarden-logo" }, "extName": { "message": "Bitwarden passordbehandler", @@ -17,7 +17,7 @@ "message": "Logg på eller opprett en ny konto for å få tilgang til ditt sikre hvelv." }, "inviteAccepted": { - "message": "Invitation accepted" + "message": "Invitasjon akseptert" }, "createAccount": { "message": "Opprett en konto" @@ -29,7 +29,7 @@ "message": "Logg inn med passnøkkel" }, "useSingleSignOn": { - "message": "Use single sign-on" + "message": "Bruk singulær pålogging" }, "welcomeBack": { "message": "Velkommen tilbake" @@ -38,7 +38,7 @@ "message": "Velg et sterkt passord" }, "finishCreatingYourAccountBySettingAPassword": { - "message": "Finish creating your account by setting a password" + "message": "Fullfør opprettelsen av kontoen din ved å bestemme et passord" }, "enterpriseSingleSignOn": { "message": "Bedriftsinnlogging (SSO)" @@ -59,10 +59,10 @@ "message": "Hovedpassord" }, "masterPassDesc": { - "message": "Superpassordet er passordet du bruker for å få tilgang til hvelvet ditt. Det er veldig viktig at du aldri glemmer ditt superpassord. Det er ingen måter å få tilbake passordet på dersom du noensinne skulle klare å glemme det." + "message": "Hovedpassordet er passordet du bruker for å få tilgang til hvelvet ditt. Det er veldig viktig at du aldri glemmer hovedpassordet ditt. Det er ingen måter å få tilbake passordet på dersom du skulle klare å glemme det." }, "masterPassHintDesc": { - "message": "Et hint for superpassordet kan hjelpe deg med å huske på passordet dersom du skulle glemme det." + "message": "Et hint for hovedpassordet kan hjelpe deg med å huske passordet dersom du skulle glemme det." }, "masterPassHintText": { "message": "If you forget your password, the password hint can be sent to your email. $CURRENT$/$MAXIMUM$ character maximum.", @@ -84,7 +84,7 @@ "message": "Et hint for hovedpassordet (valgfritt)" }, "passwordStrengthScore": { - "message": "Password strength score $SCORE$", + "message": "Passordstyrke-score: $SCORE$", "placeholders": { "score": { "content": "$1", @@ -132,7 +132,7 @@ "message": "Kopier passordet" }, "copyPassphrase": { - "message": "Copy passphrase" + "message": "Kopier passordfrase" }, "copyNote": { "message": "Kopier notatet" @@ -189,7 +189,7 @@ "message": "Kopiér notater" }, "copy": { - "message": "Copy", + "message": "Kopier", "description": "Copy to clipboard" }, "fill": { @@ -264,10 +264,10 @@ "message": "Be om passordhint" }, "enterYourAccountEmailAddressAndYourPasswordHintWillBeSentToYou": { - "message": "Enter your account email address and your password hint will be sent to you" + "message": "Skriv inn e-postadressen til kontoen din, så får du tilsendt et hint om passordet ditt" }, "getMasterPasswordHint": { - "message": "Få et hint om superpassordet" + "message": "Få et hint om hovedpassordet" }, "continue": { "message": "Fortsett" @@ -303,7 +303,7 @@ "message": "Learn more about how to use Bitwarden on the Help Center." }, "continueToBrowserExtensionStore": { - "message": "Continue to browser extension store?" + "message": "Vil du fortsette til nettleserutvidelsesbutikken?" }, "continueToBrowserExtensionStoreDesc": { "message": "Help others find out if Bitwarden is right for them. Visit your browser's extension store and leave a rating now." @@ -344,7 +344,7 @@ "message": "Bitwarden-autentiserer" }, "continueToAuthenticatorPageDesc": { - "message": "Bitwarden Authenticator allows you to store authenticator keys and generate TOTP codes for 2-step verification flows. Learn more on the bitwarden.com website" + "message": "Med Bitwarden Authenticator kan du lagre autentiseringsnøkler og generere TOTP-koder for 2-trinnspålogging. Les mer på nettstedet bitwarden.com" }, "bitwardenSecretsManager": { "message": "Bitwarden Secrets Manager" @@ -359,7 +359,7 @@ "message": "Create smooth and secure login experiences free from traditional passwords with Passwordless.dev. Learn more on the bitwarden.com website." }, "freeBitwardenFamilies": { - "message": "Free Bitwarden Families" + "message": "Gratis Bitwarden-familier" }, "freeBitwardenFamiliesPageDesc": { "message": "You are eligible for Free Bitwarden Families. Redeem this offer today in the web app." @@ -383,7 +383,7 @@ "message": "Rediger mappen" }, "editFolderWithName": { - "message": "Edit folder: $FOLDERNAME$", + "message": "Rediger mappe: $FOLDERNAME$", "placeholders": { "foldername": { "content": "$1", @@ -635,10 +635,10 @@ "message": "Opplåsingsalternativer" }, "unlockMethodNeededToChangeTimeoutActionDesc": { - "message": "Set up an unlock method to change your vault timeout action." + "message": "Sett opp en opplåsingsmetode for å endre tidsavbruddshandlingen for hvelvet." }, "unlockMethodNeeded": { - "message": "Set up an unlock method in Settings" + "message": "Sett opp en opplåsingsmetode i Innstillinger" }, "sessionTimeoutHeader": { "message": "Tidsavbrudd for økten" @@ -656,7 +656,7 @@ "message": "Nettleseren din støtter ikke kopiering til utklippstavlen på noe enkelt vis. Prøv å kopiere det manuelt i stedet." }, "verifyYourIdentity": { - "message": "Verify your identity" + "message": "Bekreft identiteten din" }, "weDontRecognizeThisDevice": { "message": "We don't recognize this device. Enter the code sent to your email to verify your identity." @@ -693,7 +693,7 @@ } }, "invalidMasterPassword": { - "message": "Ugyldig superpassord" + "message": "Ugyldig hovedpassord" }, "vaultTimeout": { "message": "Tidsavbrudd i hvelvet" @@ -790,7 +790,7 @@ } }, "masterPassDoesntMatch": { - "message": "Superpassord-bekreftelsen er ikke samsvarende." + "message": "Bekreftelsen på hovedpassordet samsvarer ikke." }, "newAccountCreated": { "message": "Din nye konto har blitt opprettet! Du kan nå logge på." @@ -808,7 +808,7 @@ "message": "Du kan lukke dette vinduet" }, "masterPassSent": { - "message": "Vi har sendt deg en E-post med hintet til superpassordet." + "message": "Vi har sendt deg en e-post med hintet til hovedpassordet." }, "verificationCodeRequired": { "message": "En verifiseringskode er påkrevd." @@ -842,7 +842,7 @@ "message": "Scan authenticator QR code from current webpage" }, "totpHelperTitle": { - "message": "Make 2-step verification seamless" + "message": "Gjør 2-trinnsbekreftelse sømløs" }, "totpHelper": { "message": "Bitwarden can store and fill 2-step verification codes. Copy and paste the key into this field." @@ -872,22 +872,22 @@ "message": "Logg inn på Bitwarden" }, "enterTheCodeSentToYourEmail": { - "message": "Enter the code sent to your email" + "message": "Skriv inn koden du har fått tilsendt på e-post" }, "enterTheCodeFromYourAuthenticatorApp": { - "message": "Enter the code from your authenticator app" + "message": "Skriv inn koden fra autentiseringsappen din" }, "pressYourYubiKeyToAuthenticate": { - "message": "Press your YubiKey to authenticate" + "message": "Trykk på YubiKey-en for å autentisere" }, "duoTwoFactorRequiredPageSubtitle": { "message": "Duo two-step login is required for your account. Follow the steps below to finish logging in." }, "followTheStepsBelowToFinishLoggingIn": { - "message": "Follow the steps below to finish logging in." + "message": "Følg trinnene nedenfor for å fullføre innloggingen." }, "followTheStepsBelowToFinishLoggingInWithSecurityKey": { - "message": "Follow the steps below to finish logging in with your security key." + "message": "Følg trinnene nedenfor for å fullføre innloggingen med sikkerhetsnøkkelen din." }, "restartRegistration": { "message": "Start registreringen på nytt" @@ -911,7 +911,7 @@ "message": "Nei" }, "location": { - "message": "Location" + "message": "Sted" }, "unexpectedError": { "message": "En uventet feil har oppstått." @@ -1016,7 +1016,7 @@ "message": "Spør om å legge til innlogging" }, "vaultSaveOptionsTitle": { - "message": "Save to vault options" + "message": "Innstillinger for hvelvlagring" }, "addLoginNotificationDesc": { "message": "\"Legg til innlogging\"-beskjeden ber deg automatisk om å lagre nye innlogginger til hvelvet ditt hver gang du logger på dem for første gang." @@ -1025,7 +1025,7 @@ "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." }, "showCardsInVaultViewV2": { - "message": "Always show cards as Autofill suggestions on Vault view" + "message": "Alltid vis kort som auto-utfyllingsforslag i Hvelv-visningen" }, "showCardsCurrentTab": { "message": "Vis kort på fanesiden" @@ -1034,7 +1034,7 @@ "message": "Vis kortelementer på fanesiden for lett auto-utfylling." }, "showIdentitiesInVaultViewV2": { - "message": "Always show identities as Autofill suggestions on Vault view" + "message": "Alltid vis identiteter som auto-utfyllingsforslag i Hvelv-visningen" }, "showIdentitiesCurrentTab": { "message": "Vis identiteter på fanesiden" @@ -1043,10 +1043,10 @@ "message": "Vis identitetselementer på fanesiden for enkel auto-utfylling." }, "clickToAutofillOnVault": { - "message": "Click items to autofill on Vault view" + "message": "Klikk på gjenstander som skal auto-utfylles i Hvelv-visningen" }, "clickToAutofill": { - "message": "Click items in autofill suggestion to fill" + "message": "Klikk på gjenstander i auto-utfyllingsforslagene for å utfylle" }, "clearClipboard": { "message": "Tøm utklippstavlen", @@ -1063,7 +1063,7 @@ "message": "Ja, lagre nå" }, "notificationViewAria": { - "message": "View $ITEMNAME$, opens in new window", + "message": "Vis $ITEMNAME$, åpnes i nytt vindu", "placeholders": { "itemName": { "content": "$1" @@ -1071,15 +1071,19 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { - "message": "Edit before saving", + "message": "Rediger før du lagrer", "description": "Tooltip and Aria label for edit button on cipher item" }, "newNotification": { - "message": "New notification" + "message": "Nytt varsel" }, "labelWithNotification": { - "message": "$LABEL$: New notification", + "message": "$LABEL$: Nytt varsel", "description": "Label for the notification with a new login suggestion.", "placeholders": { "label": { @@ -1088,46 +1092,52 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { - "message": "Save as new login", + "message": "Lagre som ny pålogging", "description": "Button text for saving login details as a new entry." }, "updateLoginAction": { - "message": "Update login", + "message": "Oppdater pålogging", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { - "message": "Save login", + "message": "Lagre pålogging", "description": "Prompt asking the user if they want to save their login details." }, "updateLogin": { - "message": "Update existing login", + "message": "Oppdater eksisterende pålogging", "description": "Prompt asking the user if they want to update an existing login entry." }, "loginSaveSuccess": { - "message": "Login saved", + "message": "Påloggingen ble lagret", "description": "Message displayed when login details are successfully saved." }, "loginUpdateSuccess": { - "message": "Login updated", + "message": "Påloggingen ble oppdatert", "description": "Message displayed when login details are successfully updated." }, "loginUpdateTaskSuccess": { @@ -1156,7 +1166,7 @@ "description": "Message prompting user to undertake completion of another security task." }, "saveFailure": { - "message": "Error saving", + "message": "Feil under lagring", "description": "Error message shown when the system fails to save login details." }, "saveFailureDetails": { @@ -1173,7 +1183,7 @@ "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": "Spør om å lagre og bruke passnøkler" }, "usePasskeysDesc": { "message": "Ask to save new passkeys or log in with passkeys stored in your vault. Applies to all logged in accounts." @@ -1200,7 +1210,7 @@ "message": "Bruk et sekundært klikk for å få tilgang til passordgenerering og samsvarende innlogginger for nettsiden. " }, "contextMenuItemDescAlt": { - "message": "Use a secondary click to access password generation and matching logins for the website. Applies to all logged in accounts." + "message": "Bruk et andre klikk for å få tilgang til passordgenerering og samsvarende pålogginger for nettstedet. Gjelder for alle innloggede kontoer." }, "defaultUriMatchDetection": { "message": "Standard URI-samsvarsgjenkjenning", @@ -1227,7 +1237,7 @@ "description": "Light color" }, "exportFrom": { - "message": "Export from" + "message": "Eksporter fra" }, "exportVault": { "message": "Eksporter hvelvet" @@ -1257,7 +1267,7 @@ "message": "Account restricted" }, "filePasswordAndConfirmFilePasswordDoNotMatch": { - "message": "“File password” and “Confirm file password“ do not match." + "message": "«Filpassord» og «Bekreft filpassord» stemmer ikke overens." }, "warning": { "message": "ADVARSEL", @@ -1280,7 +1290,7 @@ "message": "Kontokrypteringsnøkler er unike for hver Bitwarden sin brukerkonto, og du kan ikke importere en kryptert eksport til en annen konto." }, "exportMasterPassword": { - "message": "Skriv inn ditt superpassord for å eksportere dine hvelvdataer." + "message": "Skriv inn hovedpassordet ditt for å eksportere dine hvelvdataer." }, "shared": { "message": "Delt" @@ -1422,7 +1432,7 @@ } }, "premiumPriceV2": { - "message": "All for just $PRICE$ per year!", + "message": "Alt for bare $PRICE$ per år!", "placeholders": { "price": { "content": "$1", @@ -1449,7 +1459,7 @@ "message": "Et Premium-medlemskap er påkrevd for å bruke denne funksjonen." }, "authenticationTimeout": { - "message": "Authentication timeout" + "message": "Tidsavbrudd for autentisering" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." @@ -1464,26 +1474,26 @@ } }, "dontAskAgainOnThisDeviceFor30Days": { - "message": "Don't ask again on this device for 30 days" + "message": "Ikke spør igjen på denne enheten på 30 dager" }, "selectAnotherMethod": { - "message": "Select another method", + "message": "Velg en annen metode", "description": "Select another two-step login method" }, "useYourRecoveryCode": { - "message": "Use your recovery code" + "message": "Bruk gjenopprettingskoden din" }, "insertU2f": { "message": "Sett din sikkerhetsnøkkel inn i din datamaskins USB-uttak. Dersom den har en knapp, trykk på den." }, "openInNewTab": { - "message": "Open in new tab" + "message": "Åpne i ny fane" }, "webAuthnAuthenticate": { "message": "Autentiser WebAuthn" }, "readSecurityKey": { - "message": "Read security key" + "message": "Les sikkerhetsnøkkel" }, "awaitingSecurityKeyInteraction": { "message": "Awaiting security key interaction..." @@ -1501,7 +1511,7 @@ "message": "Alternativer for 2-trinnsinnlogging" }, "selectTwoStepLoginMethod": { - "message": "Select two-step login method" + "message": "Velg 2-trinnspåloggingsmetode" }, "recoveryCodeDesc": { "message": "Har du mistet tilgang til alle dine 2-trinnsleverandører? Bruk din gjenopprettingskode til å fjerne alle 2-trinnsleverandører fra din konto." @@ -1513,17 +1523,17 @@ "message": "Autentiseringsapp" }, "authenticatorAppDescV2": { - "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "message": "Skriv inn en kode generert av en autentiseringsapp som Bitwarden Authenticator.", "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, "yubiKeyTitleV2": { - "message": "Yubico OTP Security Key" + "message": "Yubico OTP-sikkerhetsnøkkel" }, "yubiKeyDesc": { "message": "Bruk en YubiKey for å få tilgang til kontoen din. Virker med enheter av typene YubiKey 4, 4 Nano, 4C, og NEO." }, "duoDescV2": { - "message": "Enter a code generated by Duo Security.", + "message": "Skriv inn en kode generert av Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Autoutfyllingsforslag" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Vis autoutfyll-forslag i tekstbokser" }, @@ -1602,7 +1630,7 @@ "message": "Vis forslag når ikonet er valgt" }, "showInlineMenuOnFormFieldsDescAlt": { - "message": "Applies to all logged in accounts." + "message": "Gjelder for alle innloggede kontoer." }, "turnOffBrowserBuiltInPasswordManagerSettings": { "message": "Skru av din nettlesers innebygde passordbehandler for å unngå konflikter." @@ -1615,15 +1643,15 @@ "description": "Overlay setting select option for disabling autofill overlay" }, "autofillOverlayVisibilityOnFieldFocus": { - "message": "When field is selected (on focus)", + "message": "Når et felt er valgt (ved fokus)", "description": "Overlay appearance select option for showing the field on focus of the input element" }, "autofillOverlayVisibilityOnButtonClick": { - "message": "When autofill icon is selected", + "message": "Når auto-utfyllingsikonet er valgt", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, "enableAutoFillOnPageLoadSectionTitle": { - "message": "Autofill on page load" + "message": "Auto-utfyll ved sideinnlasting" }, "enableAutoFillOnPageLoad": { "message": "Aktiver auto-utfylling ved sideinnlastning" @@ -1695,7 +1723,7 @@ "message": "Dra for å sortere" }, "dragToReorder": { - "message": "Drag to reorder" + "message": "Dra for å omorganisere" }, "cfTypeText": { "message": "Tekst" @@ -2107,7 +2135,7 @@ "message": "Svakt hovedpassord" }, "weakMasterPasswordDesc": { - "message": "Superpassordet du har valgt er svakt. Du bør bruke et sterkt superpassord (eller en passordfrase) for å sikre Bitwarden-kontoen din på en forsvarlig måte. Er du sikker på at du vil bruke dette superpassordet?" + "message": "Hovedpassordet du har valgt er svakt. Du bør bruke et sterkt hovedpassord (eller en passordfrase) for å sikre Bitwarden-kontoen din på en forsvarlig måte. Er du sikker på at du vil bruke dette hovedpassordet?" }, "pin": { "message": "PIN", @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Bruk dette passordet" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Bruk dette brukernavnet" }, @@ -2191,7 +2222,7 @@ "description": "This will be used as part of a larger sentence, broken up to include the generator icon. The full sentence will read 'Use the generator [GENERATOR_ICON] to create a strong unique password'" }, "vaultCustomization": { - "message": "Vault customization" + "message": "Tilpasning av hvelv" }, "vaultTimeoutAction": { "message": "Handling ved tidsavbrudd i hvelvet" @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Handling ved tidsavbrudd" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "Lås", "description": "Verb form: to make secure or inaccessible by" @@ -2364,7 +2386,7 @@ "message": "Ok" }, "errorRefreshingAccessToken": { - "message": "Access Token Refresh Error" + "message": "Feil ved oppdatering av tilgangssjetongen" }, "errorRefreshingAccessTokenDesc": { "message": "No refresh token or API keys found. Please try logging out and logging back in." @@ -2406,7 +2428,7 @@ "message": "Kontoen eksisterer ikke" }, "nativeMessagingWrongUserKeyTitle": { - "message": "Biometric key missmatch" + "message": "Biometrisk nøkkel samsvarer ikke" }, "nativeMessagingWrongUserKeyDesc": { "message": "Biometric unlock failed. The biometric secret key failed to unlock the vault. Please try to set up biometrics again." @@ -2424,10 +2446,10 @@ "message": "Biometri i nettleseren støttes ikke på denne enheten." }, "biometricsNotUnlockedTitle": { - "message": "User locked or logged out" + "message": "Brukeren er låst eller avlogget" }, "biometricsNotUnlockedDesc": { - "message": "Please unlock this user in the desktop application and try again." + "message": "Vennligst lås opp denne brukeren i skrivebordsprogrammet og prøv igjen." }, "biometricsNotAvailableTitle": { "message": "Biometrisk opplåsing er utilgjengelig" @@ -2460,7 +2482,7 @@ "message": "En virksomhetsregel påvirker dine eierskapsinnstillinger." }, "personalOwnershipPolicyInEffectImports": { - "message": "An organization policy has blocked importing items into your individual vault." + "message": "En organisasjonsretningslinje har blokkert import av gjenstander til ditt individuelle hvelv." }, "domainsTitle": { "message": "Domener", @@ -2470,7 +2492,7 @@ "message": "Blokkerte domener" }, "learnMoreAboutBlockedDomains": { - "message": "Learn more about blocked domains" + "message": "Finn ut mer om blokkerte domener" }, "excludedDomains": { "message": "Ekskluderte domener" @@ -2485,16 +2507,16 @@ "message": "Autofill and other related features will not be offered for these websites. You must refresh the page for changes to take effect." }, "autofillBlockedNoticeV2": { - "message": "Autofill is blocked for this website." + "message": "Auto-utfylling er blokkert for dette nettstedet." }, "autofillBlockedNoticeGuidance": { "message": "Endre dette i innstillingene" }, "change": { - "message": "Change" + "message": "Endre" }, "changeButtonTitle": { - "message": "Change password - $ITEMNAME$", + "message": "Endre passord - $ITEMNAME$", "placeholders": { "itemname": { "content": "$1", @@ -2575,7 +2597,7 @@ "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { - "message": "Update in Bitwarden" + "message": "Oppdater i Bitwarden" }, "updateInBitwardenSlideDesc": { "message": "Bitwarden will then prompt you to update the password in the password manager.", @@ -2585,13 +2607,13 @@ "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { - "message": "Turn on autofill" + "message": "Skru på auto-utfylling" }, "turnedOnAutofill": { - "message": "Turned on autofill" + "message": "Skrudde på auto-utfylling" }, "dismiss": { - "message": "Dismiss" + "message": "Avvis" }, "websiteItemLabel": { "message": "Nettsted $number$ (URİ)", @@ -2655,6 +2677,10 @@ "message": "Alle Send-er", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Skjul tekst som standard" }, @@ -2843,7 +2869,7 @@ "message": "Forespørsel om hovedpassord på nytt" }, "passwordConfirmation": { - "message": "Hovedpassord bekreftelse" + "message": "Hovedpassord-bekreftelse" }, "passwordConfirmationDesc": { "message": "Denne handlingen er beskyttet. For å fortsette, skriv inn hovedpassordet på nytt for å bekrefte identiteten din." @@ -2929,7 +2955,7 @@ } }, "vaultTimeoutPolicyInEffect1": { - "message": "$HOURS$ hour(s) and $MINUTES$ minute(s) maximum.", + "message": "Maks $HOURS$ time(r) og $MINUTES$ minutt(er).", "placeholders": { "hours": { "content": "$1", @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Ingen unik identifikator ble funnet." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ bruker SSO med en selvdrevet nøkkelserver. Et hovedpassord er ikke lenger nødvendig for å logge inn for medlemmer av denne organisasjonen.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Forlat organisasjonen" @@ -3217,7 +3243,7 @@ } }, "forwaderInvalidOperationWithMessage": { - "message": "$SERVICENAME$ refused your request: $ERRORMESSAGE$", + "message": "$SERVICENAME$ avslo forespørselen din: $ERRORMESSAGE$", "description": "Displayed when the user is forbidden from using the API by the forwarding service with an error message.", "placeholders": { "servicename": { @@ -3251,7 +3277,7 @@ } }, "forwarderNoUrl": { - "message": "Invalid $SERVICENAME$ url.", + "message": "Ugyldig $SERVICENAME$-url.", "description": "Displayed when the url of the forwarding service wasn't supplied.", "placeholders": { "servicename": { @@ -3366,7 +3392,7 @@ "message": "Et varsel er sendt til enheten din." }, "notificationSentDevicePart1": { - "message": "Unlock Bitwarden on your device or on the" + "message": "Lås opp Bitwarden på enheten din eller på" }, "notificationSentDeviceAnchor": { "message": "nett-app" @@ -3444,7 +3470,7 @@ "message": "Innstillinger for auto-utfylling" }, "autofillKeyboardShortcutSectionTitle": { - "message": "Autofill shortcut" + "message": "Auto-utfyllingshurtigtast(er)" }, "autofillKeyboardShortcutUpdateLabel": { "message": "Endre snarvei" @@ -3456,7 +3482,7 @@ "message": "Auto-utfyll tastatursnarvei" }, "autofillLoginShortcutNotSet": { - "message": "The autofill login shortcut is not set. Change this in the browser's settings." + "message": "Snarveien for auto-utfyllingspålogging er ikke angitt. Endre dette i nettleserens innstillinger." }, "autofillLoginShortcutText": { "message": "Autoutfyll-snarveien for pålogging er $COMMAND$. Håndter alle snarveiene i nettleserens innstillinger.", @@ -3489,7 +3515,7 @@ "message": "Enhetsgodkjennelse kreves" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "Velg en godkjenningsmetode nedenfor" }, "rememberThisDevice": { "message": "Husk denne enheten" @@ -3556,7 +3582,7 @@ "message": "Innlogging godkjent" }, "userEmailMissing": { - "message": "User email missing" + "message": "Brukerens e-postadresse mangler" }, "activeUserEmailNotFoundLoggingYouOut": { "message": "Active user email not found. Logging you out." @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Enheten er betrodd" }, + "trustOrganization": { + "message": "Stol på organisasjon" + }, + "trust": { + "message": "Stol på" + }, + "doNotTrust": { + "message": "Ikke stol på" + }, + "organizationNotTrusted": { + "message": "Organisasjonen har ikke blitt stolt på" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Stol på brukler" + }, "sendsNoItemsTitle": { "message": "Ingen aktive Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Bruk Send til å dele kryptert informasjon med noen.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Inndata er påkrevd." }, @@ -3627,17 +3685,17 @@ } }, "multipleInputEmails": { - "message": "1 or more emails are invalid" + "message": "1 eller flere e-postadresser er ugyldige" }, "inputTrimValidator": { - "message": "Input must not contain only whitespace.", + "message": "Inndataen kan ikke bare inneholde tomrom.", "description": "Notification to inform the user that a form's input can't contain only whitespace." }, "inputEmail": { "message": "Inndataen er ikke en E-postadresse." }, "fieldsNeedAttention": { - "message": "$COUNT$ field(s) above need your attention.", + "message": "$COUNT$ felt(er) ovenfor trenger din oppmerksomhet.", "placeholders": { "count": { "content": "$1", @@ -3704,7 +3762,7 @@ "description": "Message appearing below the autofill on load message when master password reprompt is set for a vault item." }, "toggleSideNavigation": { - "message": "Toggle side navigation" + "message": "Skru av/på sidenavigering" }, "skipToContent": { "message": "Hopp frem til innholdet" @@ -3714,7 +3772,7 @@ "description": "Page title for the iframe containing the overlay button" }, "toggleBitwardenVaultOverlay": { - "message": "Toggle Bitwarden autofill menu", + "message": "Skru på/av Bitwardens auto-utfyllmeny", "description": "Screen reader and tool tip label for the overlay button" }, "bitwardenVault": { @@ -3722,11 +3780,11 @@ "description": "Page title in overlay" }, "unlockYourAccountToViewMatchingLogins": { - "message": "Unlock your account to view matching logins", + "message": "Lås opp kontoen din for å se samsvarende pålogginger", "description": "Text to display in overlay when the account is locked." }, "unlockYourAccountToViewAutofillSuggestions": { - "message": "Unlock your account to view autofill suggestions", + "message": "Lås opp kontoen din for å vise auto-utfyllingsforslag", "description": "Text to display in overlay when the account is locked." }, "unlockAccount": { @@ -3734,11 +3792,11 @@ "description": "Button text to display in overlay when the account is locked." }, "unlockAccountAria": { - "message": "Unlock your account, opens in a new window", + "message": "Lås opp kontoen din, åpnes i et nytt vindu", "description": "Screen reader text (aria-label) for unlock account button in overlay" }, "totpCodeAria": { - "message": "Time-based One-Time Password Verification Code", + "message": "Tidsbasert engangskode for bekreftelse av passord", "description": "Aria label for the totp code displayed in the inline menu for autofill" }, "totpSecondsSpanAria": { @@ -3746,7 +3804,7 @@ "description": "Aria label for the totp seconds displayed in the inline menu for autofill" }, "fillCredentialsFor": { - "message": "Fill credentials for", + "message": "Fyll ut innloggingsdetaljer for", "description": "Screen reader text for when overlay item is in focused" }, "partialUsername": { @@ -3770,7 +3828,7 @@ "description": "Button text to display within inline menu when there are no matching items on a login field" }, "addNewLoginItemAria": { - "message": "Add new vault login item, opens in a new window", + "message": "Legg til ny hvelvpåloggingsgjenstand, åpnes i et nytt vindu", "description": "Screen reader text (aria-label) for new login button within inline menu" }, "newCard": { @@ -3778,7 +3836,7 @@ "description": "Button text to display within inline menu when there are no matching items on a credit card field" }, "addNewCardItemAria": { - "message": "Add new vault card item, opens in a new window", + "message": "Legg til ny hvelvkortgjenstand, åpnes i et nytt vindu", "description": "Screen reader text (aria-label) for new card button within inline menu" }, "newIdentity": { @@ -3786,11 +3844,11 @@ "description": "Button text to display within inline menu when there are no matching items on an identity field" }, "addNewIdentityItemAria": { - "message": "Add new vault identity item, opens in a new window", + "message": "Legg til ny hvelvinnstillingsgjenstand, åpnes i et nytt vindu", "description": "Screen reader text (aria-label) for new identity button within inline menu" }, "bitwardenOverlayMenuAvailable": { - "message": "Bitwarden autofill menu available. Press the down arrow key to select.", + "message": "Bitwarden-autoutfyllingsmenyen er tilgjengelig. Trykk på «Piltast ned»-knappen for å velge.", "description": "Screen reader text for announcing when the overlay opens on the page" }, "turnOn": { @@ -3879,16 +3937,16 @@ "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, "duoRequiredForAccount": { - "message": "Duo two-step login is required for your account." + "message": "Duo-totrinnspålogging er påkrevd for kontoen din." }, "popoutExtension": { - "message": "Popout extension" + "message": "Sprett ut utvidelse" }, "launchDuo": { "message": "Start Duo" }, "importFormatError": { - "message": "Data is not formatted correctly. Please check your import file and try again." + "message": "Dataene er ikke formatert riktig. Sjekk importfilen og prøv på nytt." }, "importNothingError": { "message": "Ingenting ble importert." @@ -3897,7 +3955,7 @@ "message": "Error decrypting the exported file. Your encryption key does not match the encryption key used export the data." }, "invalidFilePassword": { - "message": "Invalid file password, please use the password you entered when you created the export file." + "message": "Ugyldig filpassord, vennligst bruk passordet du skrev inn da du opprettet eksportfilen." }, "destination": { "message": "Destinasjon" @@ -3953,7 +4011,7 @@ "message": "Bekreft hvelvimportering" }, "confirmVaultImportDesc": { - "message": "This file is password-protected. Please enter the file password to import data." + "message": "Denne filen er passordbeskyttet. Vennligst skriv inn filpassordet for å importere data." }, "confirmFilePassword": { "message": "Bekreft filpassord" @@ -3980,19 +4038,19 @@ "message": "Verification required by the initiating site. This feature is not yet implemented for accounts without master password." }, "logInWithPasskeyQuestion": { - "message": "Log in with passkey?" + "message": "Vil du logge inn med passnøkkel?" }, "passkeyAlreadyExists": { - "message": "A passkey already exists for this application." + "message": "En passnøkkel finnes allerede for dette programmet." }, "noPasskeysFoundForThisApplication": { - "message": "No passkeys found for this application." + "message": "Ingen passnøkler ble funnet for dette programmet." }, "noMatchingPasskeyLogin": { "message": "Du har ikke en samsvarende innlogging for dette nettstedet." }, "noMatchingLoginsForSite": { - "message": "No matching logins for this site" + "message": "Ingen samsvarende pålogginger for dette nettstedet" }, "searchSavePasskeyNewLogin": { "message": "Søk eller lagre passnøkkelen som en ny innlogging" @@ -4007,16 +4065,16 @@ "message": "Lagre passnøkkelen som en ny pålogging" }, "chooseCipherForPasskeySave": { - "message": "Choose a login to save this passkey to" + "message": "Velg en pålogging å lagre denne passnøkkelen til" }, "chooseCipherForPasskeyAuth": { - "message": "Choose a passkey to log in with" + "message": "Velg en passnøkkel å logge inn med" }, "passkeyItem": { "message": "Passkode-gjenstand" }, "overwritePasskey": { - "message": "Overwrite passkey?" + "message": "Vil du overskrive passnøkkelen?" }, "overwritePasskeyAlert": { "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" @@ -4025,7 +4083,7 @@ "message": "Funksjonen støttes ikke ennå" }, "yourPasskeyIsLocked": { - "message": "Authentication required to use passkey. Verify your identity to continue." + "message": "Autentisering kreves for å bruke passnøkkel. Bekreft identiteten din for å fortsette." }, "multifactorAuthenticationCancelled": { "message": "Multifaktorautentisering ble avbrutt" @@ -4061,7 +4119,7 @@ "message": "LastPass-multifaktorautentisering kreves" }, "lastPassMFADesc": { - "message": "Enter your one-time passcode from your authentication app" + "message": "Skriv inn engangs-passkoden fra autentiseringsappen din" }, "lastPassOOBDesc": { "message": "Approve the login request in your authentication app or enter a one-time passcode." @@ -4113,7 +4171,7 @@ "message": "Aktiv konto" }, "bitwardenAccount": { - "message": "Bitwarden account" + "message": "Bitwarden-konto" }, "availableAccounts": { "message": "Tilgjengelige kontoer" @@ -4195,7 +4253,7 @@ "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": "Klarte ikke å sette Bitwarden som standard passordbehandler", "description": "Title for the dialog that appears when the user has not granted the extension permission to set privacy settings" }, "privacyPermissionAdditionNotGrantedDescription": { @@ -4207,7 +4265,7 @@ "description": "Button text for the setting that allows overriding the default browser autofill settings" }, "saveCipherAttemptSuccess": { - "message": "Credentials saved successfully!", + "message": "Legitimasjonen ble vellykket lagret!", "description": "Notification message for when saving credentials has succeeded." }, "passwordSaved": { @@ -4215,7 +4273,7 @@ "description": "Notification message for when saving credentials has succeeded." }, "updateCipherAttemptSuccess": { - "message": "Credentials updated successfully!", + "message": "Legitimasjonen ble vellykket oppdatert!", "description": "Notification message for when updating credentials has succeeded." }, "passwordUpdated": { @@ -4233,7 +4291,7 @@ "message": "Fjern passordnøkkel" }, "passkeyRemoved": { - "message": "Passkey removed" + "message": "Passnøkkelen ble fjernet" }, "autofillSuggestions": { "message": "Autoutfyllingsforslag" @@ -4242,16 +4300,16 @@ "message": "Foreslåtte gjenstander" }, "autofillSuggestionsTip": { - "message": "Save a login item for this site to autofill" + "message": "Lagre en påloggingsgjenstand for dette nettstedet for å auto-utfylle" }, "yourVaultIsEmpty": { "message": "Hvelvet ditt er tomt" }, "noItemsMatchSearch": { - "message": "No items match your search" + "message": "Ingen gjenstander samsvarer med søket ditt" }, "clearFiltersOrTryAnother": { - "message": "Clear filters or try another search term" + "message": "Tøm filtrene eller prøv et annet søkeuttrykk" }, "copyInfoTitle": { "message": "Kopiér info - $ITEMNAME$", @@ -4304,7 +4362,7 @@ } }, "viewItemTitleWithField": { - "message": "View item - $ITEMNAME$ - $FIELD$", + "message": "Vis gjenstand - $ITEMNAME$ - $FIELD$", "description": "Title for a link that opens a view for an item.", "placeholders": { "itemname": { @@ -4328,7 +4386,7 @@ } }, "autofillTitleWithField": { - "message": "Autofill - $ITEMNAME$ - $FIELD$", + "message": "Auto-utfyll - $ITEMNAME$ - $FIELD$", "description": "Title for a button that autofills a login item.", "placeholders": { "itemname": { @@ -4342,7 +4400,7 @@ } }, "copyFieldValue": { - "message": "Copy $FIELD$, $VALUE$", + "message": "Kopier $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", "placeholders": { "field": { @@ -4362,7 +4420,7 @@ "message": "Legg til i samlinger" }, "copyEmail": { - "message": "Copy email" + "message": "Kopier e-postadresse" }, "copyPhone": { "message": "Kopiér telefonnummer" @@ -4371,7 +4429,7 @@ "message": "Kopiér adresse" }, "adminConsole": { - "message": "Admin Console" + "message": "Administrasjonskonsoll" }, "accountSecurity": { "message": "Kontosikkerhet" @@ -4431,7 +4489,7 @@ "message": "Gjenstandens navn" }, "organizationIsDeactivated": { - "message": "Organization is deactivated" + "message": "Organisasjonen er deaktivert" }, "owner": { "message": "Eier" @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Are you sure you want to permanently delete this attachment?" }, @@ -4501,7 +4586,7 @@ "message": "Filtre" }, "filterVault": { - "message": "Filter vault" + "message": "Filtrer hvelv" }, "filterApplied": { "message": "Ett filter er benyttet" @@ -4597,7 +4682,7 @@ } }, "autoFillOnPageLoad": { - "message": "Autofill on page load?" + "message": "Vil du auto-utfylle ved sideinnlasting?" }, "cardExpiredTitle": { "message": "Utløpt kort" @@ -4681,7 +4766,7 @@ "message": "Bruk tekstfelter for data som sikkerhetsspørsmål" }, "hiddenHelpText": { - "message": "Use hidden fields for sensitive data like a password" + "message": "Bruk skjulte felter for sensitive data, for eksempel passord" }, "checkBoxHelpText": { "message": "Use checkboxes if you'd like to autofill a form's checkbox, like a remember email" @@ -4848,7 +4933,7 @@ "message": "Kontohandlinger" }, "showNumberOfAutofillSuggestions": { - "message": "Show number of login autofill suggestions on extension icon" + "message": "Vis antall auto-utfyllingsforslag for pålogging på utvidelsesikonet" }, "showQuickCopyActions": { "message": "Vis hurtigkopieringshandlinger i hvelvet" @@ -4920,22 +5005,22 @@ "message": "Slett for alltid" }, "noEditPermissions": { - "message": "You don't have permission to edit this item" + "message": "Du har ikke tillatelse til å redigere denne gjenstanden" }, "biometricsStatusHelptextUnlockNeeded": { - "message": "Biometric unlock is unavailable because PIN or password unlock is required first." + "message": "Biometrisk opplåsing er ikke tilgjengelig fordi PIN-kode eller passord kreves først." }, "biometricsStatusHelptextHardwareUnavailable": { "message": "Biometrisk opplåsing er utilgjengelig for øyeblikket." }, "biometricsStatusHelptextAutoSetupNeeded": { - "message": "Biometric unlock is unavailable due to misconfigured system files." + "message": "Biometrisk opplåsing er ikke tilgjengelig på grunn av feilkonfigurerte systemfiler." }, "biometricsStatusHelptextManualSetupNeeded": { - "message": "Biometric unlock is unavailable due to misconfigured system files." + "message": "Biometrisk opplåsing er ikke tilgjengelig på grunn av feilkonfigurerte systemfiler." }, "biometricsStatusHelptextDesktopDisconnected": { - "message": "Biometric unlock is unavailable because the Bitwarden desktop app is closed." + "message": "Biometrisk opplåsing er ikke tilgjengelig fordi Bitwarden-skrivebordsappen er lukket." }, "biometricsStatusHelptextNotEnabledInDesktop": { "message": "Biometric unlock is unavailable because it is not enabled for $EMAIL$ in the Bitwarden desktop app.", @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Autentiserer" }, @@ -4961,7 +5055,7 @@ "description": "Notification message for when a password has been regenerated" }, "saveToBitwarden": { - "message": "Save to Bitwarden", + "message": "Lagre til Bitwarden", "description": "Confirmation message for saving a login to Bitwarden" }, "spaceCharacterDescriptor": { @@ -4985,7 +5079,7 @@ "description": "Represents the @ key in screen reader content as a readable word" }, "hashSignCharacterDescriptor": { - "message": "Hash sign", + "message": "Hashtag-symbol", "description": "Represents the # key in screen reader content as a readable word" }, "dollarSignCharacterDescriptor": { @@ -5029,7 +5123,7 @@ "description": "Represents the + key in screen reader content as a readable word" }, "equalsCharacterDescriptor": { - "message": "Equals", + "message": "Er lik", "description": "Represents the = key in screen reader content as a readable word" }, "braceLeftCharacterDescriptor": { @@ -5049,7 +5143,7 @@ "description": "Represents the ] key in screen reader content as a readable word" }, "pipeCharacterDescriptor": { - "message": "Pipe", + "message": "Rør", "description": "Represents the | key in screen reader content as a readable word" }, "backSlashCharacterDescriptor": { @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Viktig melding" - }, - "setupTwoStepLogin": { - "message": "Sett opp 2-trinnspålogging" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Minn meg på det senere" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "Nei, det gjør jeg ikke" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" - }, - "turnOnTwoStepLogin": { - "message": "Slå på 2-trinnsinnlogging" - }, - "changeAcctEmail": { - "message": "Endre kontoens E-postadresse" - }, "extensionWidth": { "message": "Utvidelsens bredde" }, @@ -5157,31 +5215,31 @@ "message": "Ekstra bred" }, "sshKeyWrongPassword": { - "message": "The password you entered is incorrect." + "message": "Passordet du skrev inn er feil." }, "importSshKey": { - "message": "Import" + "message": "Importer" }, "confirmSshKeyPassword": { - "message": "Confirm password" + "message": "Bekreft passordet" }, "enterSshKeyPasswordDesc": { "message": "Enter the password for the SSH key." }, "enterSshKeyPassword": { - "message": "Enter password" + "message": "Skriv inn passord" }, "invalidSshKey": { - "message": "The SSH key is invalid" + "message": "SSH-nøkkelen er ugyldig" }, "sshKeyTypeUnsupported": { "message": "The SSH key type is not supported" }, "importSshKeyFromClipboard": { - "message": "Import key from clipboard" + "message": "Importer nøkkel fra utklippstavlen" }, "sshKeyImported": { - "message": "SSH key imported successfully" + "message": "SSH-nøkkelen ble vellykket importert" }, "cannotRemoveViewOnlyCollections": { "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", @@ -5202,22 +5260,22 @@ "message": "Change at-risk password" }, "settingsVaultOptions": { - "message": "Vault options" + "message": "Hvelvinnstillinger" }, "emptyVaultDescription": { "message": "The vault protects more than just your passwords. Store secure logins, IDs, cards and notes securely here." }, "introCarouselLabel": { - "message": "Welcome to Bitwarden" + "message": "Velkommen til Bitwarden" }, "securityPrioritized": { - "message": "Security, prioritized" + "message": "Sikkerhet, prioritert" }, "securityPrioritizedBody": { "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." }, "quickLogin": { - "message": "Quick and easy login" + "message": "Rask og enkel pålogging" }, "quickLoginBody": { "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." @@ -5229,31 +5287,52 @@ "message": "Use the generator to create and save strong, unique passwords for all your accounts." }, "secureDevices": { - "message": "Your data, when and where you need it" + "message": "Dine data, når og hvor du trenger dem" }, "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { - "message": "Import existing passwords" + "message": "Importer eksisterende passord" }, "emptyVaultNudgeBody": { "message": "Use the importer to quickly transfer logins to Bitwarden without manually adding them." }, "emptyVaultNudgeButton": { - "message": "Import now" + "message": "Importér nå" }, "hasItemsVaultNudgeTitle": { - "message": "Welcome to your vault!" + "message": "Velkommen til hvelvet ditt!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { - "message": "Save time with autofill" + "message": "Spar tid med auto-utfylling" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5262,21 +5341,48 @@ "message": "With cards, easily autofill payment forms securely and accurately." }, "newIdentityNudgeTitle": { - "message": "Simplify creating accounts" + "message": "Forenkle oppretting av kontoer" }, "newIdentityNudgeBody": { "message": "With identities, quickly autofill long registration or contact forms." }, "newNoteNudgeTitle": { - "message": "Keep your sensitive data safe" + "message": "Beskytt dine sensitive data" }, "newNoteNudgeBody": { "message": "With notes, securely store sensitive data like banking or insurance details." }, "newSshNudgeTitle": { - "message": "Developer-friendly SSH access" + "message": "Utviklervennlig SSH-tilgang" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/ne/messages.json b/apps/browser/src/_locales/ne/messages.json index 99a09c75d41..29223942fd6 100644 --- a/apps/browser/src/_locales/ne/messages.json +++ b/apps/browser/src/_locales/ne/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Autofill suggestions" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Show autofill suggestions on form fields" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Use this password" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Use this username" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Timeout action" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "Lock", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "All Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Hide text by default" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ is using SSO with a self-hosted key server. A master password is no longer required to log in for members of this organization.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Leave organization" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Device trusted" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "No active Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Use Send to securely share encrypted information with anyone.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Input is required." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Are you sure you want to permanently delete this attachment?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Authenticating" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Important notice" - }, - "setupTwoStepLogin": { - "message": "Set up two-step login" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Remind me later" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" - }, - "turnOnTwoStepLogin": { - "message": "Turn on two-step login" - }, - "changeAcctEmail": { - "message": "Change account email" - }, "extensionWidth": { "message": "Extension width" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/nl/messages.json b/apps/browser/src/_locales/nl/messages.json index 2934c5da3fd..b98814df45e 100644 --- a/apps/browser/src/_locales/nl/messages.json +++ b/apps/browser/src/_locales/nl/messages.json @@ -468,7 +468,7 @@ "message": "Wachtwoord gegenereerd" }, "passphraseGenerated": { - "message": "Wachtwoorden gegenereerd" + "message": "Wachtwoordzin gegenereerd" }, "usernameGenerated": { "message": "Gebruikersnaam gegenereerd" @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "Nieuw Item, opent in nieuw venster", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Bewerken voor opslaan", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ opgeslagen in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "opslaan in Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ bijgewerkt in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "bijgewerkt in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "$ITEMTYPE$, $ITEMNAME$ selecteren", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Opslaan als nieuwe login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Login bijwerken", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Ontgrendel voor het opslaan van deze login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Login opslaan", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Suggesties automatisch invullen" }, + "autofillSpotlightTitle": { + "message": "Gemakkelijk suggesties voor automatisch invullen vinden" + }, + "autofillSpotlightDesc": { + "message": "Schakel de autofill-instellingen van je browser uit, zodat ze niet conflicteren met Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Automatisch invullen van $BROWSER$ uitschakelen", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Automatisch invullen uitschakelen" + }, "showInlineMenuLabel": { "message": "Suggesties voor automatisch invullen op formuliervelden weergeven" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Dit wachtwoord gebruiken" }, + "useThisPassphrase": { + "message": "Deze wachtwoordzin gebruiken" + }, "useThisUsername": { "message": "Deze gebruikersnaam gebruiken" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Time-out actie" }, - "newCustomizationOptionsCalloutTitle": { - "message": "Nieuwe aanpassingsopties" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Pas je kluis ervaring aan met snelle kopieeracties, compacte modus en meer!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "Alle weergave-instellingen bekijken" - }, "lock": { "message": "Vergrendelen", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "Alle Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Maximum aantal keren benaderd", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Tekst standaard verbergen" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Geen unieke id gevonden." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ gebruikt SSO met een zelf gehoste sleutelserver. Leden van deze organisatie kunnen inloggen zonder hoofdwachtwoord.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Organisatie verlaten" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Vertrouwd apparaat" }, + "trustOrganization": { + "message": "Organisatie vertrouwen" + }, + "trust": { + "message": "Vertrouwen" + }, + "doNotTrust": { + "message": "Niet vertrouwen" + }, + "organizationNotTrusted": { + "message": "Organisatie is niet vertrouwd" + }, + "emergencyAccessTrustWarning": { + "message": "Bevestig, voor de veiligheid van je account, alleen als je noodtoegang hebt verleend aan deze gebruiker en de vingerafdruk voldoet aan wat er in hun account wordt weergegeven" + }, + "orgTrustWarning": { + "message": "Ga, voor de veiligheid van je account, alleen verder als je lid bent van deze organisatie, accountherstel hebt ingeschakeld en de hieronder weergegeven vingerafdruk overeenkomt met de vingerafdruk van de organisatie." + }, + "orgTrustWarning1": { + "message": "Deze organisatie heeft een Enterprise-beleid dat je inschrijft voor accountherstel. Inschrijving stelt beheerders van de organisatie in staat om je wachtwoord te wijzigen. Ga alleen verder als je deze organisatie herkent en de vingerafdrukzin die hieronder wordt weergegeven overeenkomt met de vingerafdruk van de organisatie." + }, + "trustUser": { + "message": "Gebruiker vertrouwen" + }, "sendsNoItemsTitle": { "message": "Geen actieve Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Gebruik Send voor het veilig delen van versleutelde informatie met wie dan ook.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Gevoelige informatie veilig versturen", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Deel bestanden en gegevens veilig met iedereen, op elk platform. Je informatie blijft end-to-end versleuteld terwijl en blootstelling beperkt.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Invoer vereist." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Bitwarden downloaden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Bitwarden op alle apparaten downloaden" + }, + "getTheMobileApp": { + "message": "De mobiele app downloaden" + }, + "getTheMobileAppDesc": { + "message": "Toegang tot je wachtwoorden onderweg met de mobiele Bitwarden-app." + }, + "getTheDesktopApp": { + "message": "De desktop-app downloaden" + }, + "getTheDesktopAppDesc": { + "message": "Toegang tot je kluis zonder browser, vervolgens ontgrendelen met biometrische gegevens om sneller te ontgrendelen in zowel de desktopapp als browserextensie." + }, + "downloadFromBitwardenNow": { + "message": "Nu van bitwarden.com downloaden" + }, + "getItOnGooglePlay": { + "message": "Download op Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Weet je zeker dat je deze bijlage definitief wilt verwijderen?" }, @@ -4538,7 +4623,7 @@ "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." }, "loginCredentials": { - "message": "Login referenties" + "message": "Inloggegevens" }, "authenticatorKey": { "message": "Authenticatiesleutel" @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometrisch ontgrendelen is momenteel niet beschikbaar om een onbekende reden." }, + "unlockVault": { + "message": "Ontgrendel je kluis in seconden" + }, + "unlockVaultDesc": { + "message": "Je kunt de instellingen voor ontgrendelen en time-out aanpassen om sneller toegang te krijgen tot je kluis." + }, + "unlockPinSet": { + "message": "PIN-code ontgrendelen instellen" + }, "authenticating": { "message": "Aan het inloggen" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Belangrijke mededeling" - }, - "setupTwoStepLogin": { - "message": "Tweestapsaanmelding instellen" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Vanaf februari 2025 stuurt Bitwarden een code naar het e-mailadres van je account om inloggen op nieuwe apparaten te verifiëren." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "Je kunt tweestapsaanmelding instellen als een alternatieve manier om je account te beschermen of je e-mailadres te veranderen naar een waar je toegang toe hebt." - }, - "remindMeLater": { - "message": "Herinner me later" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Heb je betrouwbare toegang tot je e-mail, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "Nee, dat heb ik niet" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Ja, ik heb betrouwbare toegang tot mijn e-mail" - }, - "turnOnTwoStepLogin": { - "message": "Tweestapsaanmelding inschakelen" - }, - "changeAcctEmail": { - "message": "E-mailadres van het account veranderen" - }, "extensionWidth": { "message": "Extensiebreedte" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Onbeperkt wachtwoorden opslaan op alle apparaten met Bitwarden-apps voor mobiel, browser en desktop." }, + "nudgeBadgeAria": { + "message": "1 melding" + }, "emptyVaultNudgeTitle": { "message": "Bestaande wachtwoorden importeren" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welkom in je kluis!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items voor de huidige pagina\nFavoriete items voor eenvoudige toegang\nDoorzoek je kluis naar iets anders" + "hasItemsVaultNudgeBodyOne": { + "message": "Automatisch invullen van items voor de huidige pagina" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Items als favoriet markeren voor gemakkelijke toegang" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Je kluis doorzoeken naar iets anders" }, "newLoginNudgeTitle": { "message": "Tijd besparen met automatisch aanvullen" }, - "newLoginNudgeBody": { - "message": "Voeg een website toe zodat deze login wordt weergegeven als een automatische invulsuggestie." + "newLoginNudgeBodyOne": { + "message": "Voeg een", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "toe zodat deze login wordt weergegeven als een automatische invulsuggestie.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Naadloos online afrekenen" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Ontwikkelaars-vriendelijke SSH-toegang" }, - "newSshNudgeBody": { - "message": "Sla je sleutels op en verbind met de SSH-agent voor snelle, versleutelde authenticatie." + "newSshNudgeBodyOne": { + "message": "Sla je sleutels op en verbind met de SSH-agent voor snelle, versleutelde authenticatie.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Meer informatie over SSH-agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Snel wachtwoorden maken" + }, + "generatorNudgeBodyOne": { + "message": "Maak eenvoudig sterke en unieke wachtwoorden door te klikken op", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "om je te helpen je inloggegevens veilig te houden.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Maak eenvoudig sterke en unieke wachtwoorden door op de knop Wachtwoord genereren te klikken om je logins veilig te houden.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "Je hebt geen rechten om deze pagina te bekijken. Probeer in te loggen met een ander account." } } diff --git a/apps/browser/src/_locales/nn/messages.json b/apps/browser/src/_locales/nn/messages.json index 99a09c75d41..29223942fd6 100644 --- a/apps/browser/src/_locales/nn/messages.json +++ b/apps/browser/src/_locales/nn/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Autofill suggestions" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Show autofill suggestions on form fields" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Use this password" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Use this username" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Timeout action" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "Lock", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "All Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Hide text by default" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ is using SSO with a self-hosted key server. A master password is no longer required to log in for members of this organization.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Leave organization" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Device trusted" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "No active Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Use Send to securely share encrypted information with anyone.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Input is required." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Are you sure you want to permanently delete this attachment?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Authenticating" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Important notice" - }, - "setupTwoStepLogin": { - "message": "Set up two-step login" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Remind me later" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" - }, - "turnOnTwoStepLogin": { - "message": "Turn on two-step login" - }, - "changeAcctEmail": { - "message": "Change account email" - }, "extensionWidth": { "message": "Extension width" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/or/messages.json b/apps/browser/src/_locales/or/messages.json index 99a09c75d41..29223942fd6 100644 --- a/apps/browser/src/_locales/or/messages.json +++ b/apps/browser/src/_locales/or/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Autofill suggestions" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Show autofill suggestions on form fields" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Use this password" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Use this username" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Timeout action" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "Lock", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "All Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Hide text by default" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ is using SSO with a self-hosted key server. A master password is no longer required to log in for members of this organization.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Leave organization" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Device trusted" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "No active Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Use Send to securely share encrypted information with anyone.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Input is required." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Are you sure you want to permanently delete this attachment?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Authenticating" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Important notice" - }, - "setupTwoStepLogin": { - "message": "Set up two-step login" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Remind me later" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" - }, - "turnOnTwoStepLogin": { - "message": "Turn on two-step login" - }, - "changeAcctEmail": { - "message": "Change account email" - }, "extensionWidth": { "message": "Extension width" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/pl/messages.json b/apps/browser/src/_locales/pl/messages.json index 042cafb0300..80119b2be25 100644 --- a/apps/browser/src/_locales/pl/messages.json +++ b/apps/browser/src/_locales/pl/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "Nowy element, otwiera się w nowym oknie", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edytuj przed zapisaniem", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ został zapisany w Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "zapisano w Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ został zaktualizowany w Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "zaktualizowano w Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Wybierz $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Zapisz jako nowy login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Zaktualizuj dane logowania", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Odblokuj, aby zapisać ten login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Zapisz dane logowania", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Sugestie autouzupełniania" }, + "autofillSpotlightTitle": { + "message": "Łatwe znajdowanie sugestii autouzupełniania" + }, + "autofillSpotlightDesc": { + "message": "Wyłącz ustawienia autouzupełniania swojej przeglądarki, aby nie kolidowały z Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Wyłącz autouzupełnianie $BROWSER$", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Wyłącz autouzupełnienie" + }, "showInlineMenuLabel": { "message": "Pokaż sugestie autouzupełniania na polach formularza" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Użyj tego hasła" }, + "useThisPassphrase": { + "message": "Użyj tego hasła wyrazowego" + }, "useThisUsername": { "message": "Użyj tej nazwy użytkownika" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Akcja po przekroczeniu limitu czasu" }, - "newCustomizationOptionsCalloutTitle": { - "message": "Nowe opcje dostosowywania" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Dostosuj swój sejf dzięki akcjom szybkiego kopiowania, trybowi kompaktowemu i więcej!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "Zobacz wszystkie ustawienia wyglądu" - }, "lock": { "message": "Zablokuj", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "Wszystkie wysyłki", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Maksymalna liczba dostępów została osiągnięta", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Domyślnie ukryj tekst" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Nie znaleziono unikatowego identyfikatora." }, - "convertOrganizationEncryptionDesc": { - "message": "Organizacja $ORGANIZATION$ używa jednokrotnego logowania SSO z własnym serwerem kluczy. Użytkownicy nie muszą logować się za pomocą hasła głównego.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "Hasło główne nie jest już wymagane dla członków następującej organizacji. Proszę potwierdzić poniższą domenę u administratora organizacji." + }, + "organizationName": { + "message": "Nazwa organizacji" + }, + "keyConnectorDomain": { + "message": "Domena Key Connector'a" }, "leaveOrganization": { "message": "Opuść organizację" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Zaufano urządzeniu" }, + "trustOrganization": { + "message": "Zaufaj organizacji" + }, + "trust": { + "message": "Zaufaj" + }, + "doNotTrust": { + "message": "Nie ufaj" + }, + "organizationNotTrusted": { + "message": "Organizacja nie jest zaufana" + }, + "emergencyAccessTrustWarning": { + "message": "Dla bezpieczeństwa Twojego konta potwierdź tylko, jeśli przyznano temu użytkownikowi dostęp awaryjny i jego odcisk palca pasuje do tego, co widnieje na jego koncie" + }, + "orgTrustWarning": { + "message": "Dla zapewnienia bezpieczeństwa konta kontynuuj tylko wtedy, gdy jesteś członkiem tej organizacji, włączono odzyskiwanie konta, a odcisk palca wyświetlany poniżej pasuje do odcisku palca organizacji." + }, + "orgTrustWarning1": { + "message": "Polityka korporacyjna tej organizacji umożliwia zapisanie Cię do programu odzyskiwania kont. Rejestracja umożliwi administratorom organizacji zmianę Twojego hasła. Możesz kontynuować tylko wtedy, gdy znasz tę organizację, a odcisk palca pokazany poniżej pasuje do odcisku palca tej organizacji." + }, + "trustUser": { + "message": "Zaufaj użytkownikowi" + }, "sendsNoItemsTitle": { "message": "Brak aktywnych wysyłek", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Użyj wysyłki, aby bezpiecznie dzielić się zaszyfrowanymi informacjami ze wszystkimi.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Wysyłaj bezpiecznie poufne informacje", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Udostępniaj pliki i dane bezpiecznie każdemu, na każdej platformie. Twoje dane pozostaną zaszyfrowane end-to-end przy jednoczesnym ograniczeniu narażenia.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Dane wejściowe są wymagane." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Pobierz Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Pobierz Bitwarden na wszystkich urządzeniach" + }, + "getTheMobileApp": { + "message": "Pobierz aplikację mobilną" + }, + "getTheMobileAppDesc": { + "message": "Uzyskaj dostęp do haseł przy pomocy aplikacji mobilnej Bitwarden." + }, + "getTheDesktopApp": { + "message": "Pobierz aplikację desktopową" + }, + "getTheDesktopAppDesc": { + "message": "Uzyskaj dostęp do sejfu bez przeglądarki, a następnie ustaw odblokowanie biometryczne, aby przyspieszyć odblokowanie zarówno w aplikacji desktopowej, jak i w rozszerzeniu przeglądarki." + }, + "downloadFromBitwardenNow": { + "message": "Pobierz teraz z bitwarden.com" + }, + "getItOnGooglePlay": { + "message": "Pobierz z Google Play" + }, + "downloadOnTheAppStore": { + "message": "Pobierz z App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Czy na pewno chcesz trwale usunąć ten załącznik?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Odblokowanie biometryczne jest obecnie niedostępne z nieznanego powodu." }, + "unlockVault": { + "message": "Odblokuj swój sejf w kilka sekund" + }, + "unlockVaultDesc": { + "message": "Możesz dostosować ustawienia odblokowania i limitu czasu, aby szybciej uzyskać dostęp do sejfu." + }, + "unlockPinSet": { + "message": "Ustaw kod PIN odblokowujący" + }, "authenticating": { "message": "Uwierzytelnianie" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Ważna informacja" - }, - "setupTwoStepLogin": { - "message": "Skonfiguruj dwustopniowe logowanie" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden wyśle kod na Twój adres e-mail w celu zweryfikowania logowania z nowych urządzeń, począwszy od lutego 2025 r." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "Możesz skonfigurować dwustopniowe logowanie jako alternatywny sposób ochrony konta lub zmienić swój adres e-mail, do którego masz dostęp." - }, - "remindMeLater": { - "message": "Przypomnij mi później" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Czy masz pewny dostęp do swojego adresu e-mail, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "Nie, nie mam" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Tak, mam pewny dostęp do mojego adresu e-mail" - }, - "turnOnTwoStepLogin": { - "message": "Włącz dwustopniowe logowanie" - }, - "changeAcctEmail": { - "message": "Zmień adres e-mail konta" - }, "extensionWidth": { "message": "Szerokość rozszerzenia" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Zapisuj nieograniczoną liczbę haseł na nieograniczonej liczbie urządzeń dzięki aplikacjom Bitwarden na urządzenia mobilne, przeglądarki i komputery stacjonarne." }, + "nudgeBadgeAria": { + "message": "1 powiadomienie" + }, "emptyVaultNudgeTitle": { "message": "Importuj istniejące hasła" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Witaj w Twoim Sejfie!" }, - "hasItemsVaultNudgeBody": { - "message": "Autouzupełnianie elementów dla bieżącej strony\nUlubione elementy dla łatwego dostępu\nPrzeszukaj swój sejf w poszukiwaniu czegoś innego" + "hasItemsVaultNudgeBodyOne": { + "message": "Autouzupełnianie elementów dla bieżącej strony" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Ulubione elementy dla szybkiego dostępu" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Przeszukaj swój sejf w poszukiwaniu czegoś innego" }, "newLoginNudgeTitle": { "message": "Oszczędzaj czas dzięki autouzupełnianiu" }, - "newLoginNudgeBody": { - "message": "Dołącz stronę internetową, aby ten login pojawił się jako sugestia autouzupełniania." + "newLoginNudgeBodyOne": { + "message": "Dołącz", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "stronę internetową, ", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "aby ten login pojawił się jako sugestia autouzupełniania.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Bezproblemowe zamówienia online" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Przyjazny dla deweloperów dostęp SSH" }, - "newSshNudgeBody": { - "message": "Przechowuj swoje klucze i połącz się z agentem SSH dla szybkiego, szyfrowanego uwierzytelniania." + "newSshNudgeBodyOne": { + "message": "Przechowuj swoje klucze i połącz się z agentem SSH dla szybkiego, szyfrowanego uwierzytelniania.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Dowiedz się więcej o agencie SSH", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Szybko twórz hasła" + }, + "generatorNudgeBodyOne": { + "message": "Łatwo twórz silne i unikalne hasła, klikając na", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": ", aby pomóc Ci zachować bezpieczeństwo Twoich danych logowania.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Łatwo twórz silne i unikalne hasła, klikając na Wygeneruj Hasło, aby pomóc Ci zachować bezpieczeństwo Twoich danych logowania.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "Nie masz uprawnień do przeglądania tej strony. Spróbuj zalogować się na inne konto." } } diff --git a/apps/browser/src/_locales/pt_BR/messages.json b/apps/browser/src/_locales/pt_BR/messages.json index c4fb561b5be..56a4ce3018b 100644 --- a/apps/browser/src/_locales/pt_BR/messages.json +++ b/apps/browser/src/_locales/pt_BR/messages.json @@ -200,19 +200,19 @@ "message": "Autopreencher" }, "autoFillLogin": { - "message": "Preenchimento automático ‘login’" + "message": "Preencher login automaticamente" }, "autoFillCard": { - "message": "Preenchimento automático cartão" + "message": "Preencher cartão automaticamente" }, "autoFillIdentity": { - "message": "Preenchimento automático identidade" + "message": "Preencher identidade automaticamente" }, "fillVerificationCode": { "message": "Preencher o código de verificação" }, "fillVerificationCodeAria": { - "message": "Preencher o código de verificação", + "message": "Preencher código de verificação", "description": "Aria label for the heading displayed the inline menu for totp code autofill" }, "generatePasswordCopied": { @@ -830,7 +830,7 @@ } }, "autofillError": { - "message": "Não é possível auto-preencher o item selecionado nesta página. Em alternativa, copie e cole a informação." + "message": "Não é possível preencher automaticamente o item selecionado nesta página. Em vez disso, copie e cole a informação." }, "totpCaptureError": { "message": "Não foi possível escanear o código QR a partir da página atual" @@ -1025,7 +1025,7 @@ "message": "Pedir para adicionar um item se um não for encontrado no seu cofre. Aplica-se a todas as contas logadas." }, "showCardsInVaultViewV2": { - "message": "Sempre mostrar cartões como sugestões de preenchimento automático na Tela do Cofre" + "message": "Sempre mostrar cartões como sugestões de preenchimento automático na tela do Cofre" }, "showCardsCurrentTab": { "message": "Mostrar cartões em páginas com guias." @@ -1043,10 +1043,10 @@ "message": "Liste os itens de identidade na aba atual para facilitar preenchimento automático." }, "clickToAutofillOnVault": { - "message": "Clique em itens para autopreencher na Tela do Cofre" + "message": "Clique em itens na tela do Cofre para preencher automaticamente" }, "clickToAutofill": { - "message": "Selecione itens sugeridos pelo autopreenchimento" + "message": "Selecione o item para preenchê-lo automaticamente" }, "clearClipboard": { "message": "Limpar Área de Transferência", @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Salvar como nova sessão", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Atualizar sessão", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1185,7 +1195,7 @@ "message": "Atualizar" }, "notificationUnlockDesc": { - "message": "Desbloqueie o seu cofre do Bitwarden para concluir a solicitação de autopreenchimento." + "message": "Desbloqueie o seu cofre do Bitwarden para concluir a solicitação de preenchimento automático." }, "notificationUnlock": { "message": "Desbloquear" @@ -1203,7 +1213,7 @@ "message": "Use um clique secundário para acessar a geração de senha e os logins correspondentes para o site. Aplica-se a todas as contas logadas." }, "defaultUriMatchDetection": { - "message": "Detecção de Correspondência de URI Padrão", + "message": "Detecção de correspondência de URI padrão", "description": "Default URI match detection for autofill." }, "defaultUriMatchDetectionDesc": { @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Sugestões de preenchimento automático" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Mostrar sugestões de preenchimento automático nos campos de formulários" }, @@ -1626,7 +1654,7 @@ "message": "Preenchimento automático ao carregar a página" }, "enableAutoFillOnPageLoad": { - "message": "Auto-preencher ao carregar a página" + "message": "Preencher automaticamente ao carregar a página" }, "enableAutoFillOnPageLoadDesc": { "message": "Se um formulário de login for detectado, realizar automaticamente um auto-preenchimento quando a página web carregar." @@ -1644,19 +1672,19 @@ "message": "Configuração de autopreenchimento padrão para itens de credenciais" }, "defaultAutoFillOnPageLoadDesc": { - "message": "Depois de habilitar o Auto-preenchimento ao carregar a página, você pode habilitar ou desabilitar o recurso para itens de credenciais individuais. Esta é a configuração padrão para itens de credenciais que não são configurados separadamente." + "message": "Você pode desativar o preenchimento automático no carregamento da página para credenciais individuais na tela de Editar do item." }, "itemAutoFillOnPageLoad": { - "message": "Auto-preencher no Carregamento da Página (se ativado nas Opções)" + "message": "Preencher automaticamente ao carregar a página (se configurado nas Opções)" }, "autoFillOnPageLoadUseDefault": { "message": "Usar configuração padrão" }, "autoFillOnPageLoadYes": { - "message": "Auto-preencher ao carregar a página" + "message": "Preencher automaticamente ao carregar a página" }, "autoFillOnPageLoadNo": { - "message": "Não auto-preencher ao carregar a página" + "message": "Não preencher automaticamente ao carregar a página" }, "commandOpenPopup": { "message": "Abrir pop-up do cofre" @@ -1668,10 +1696,10 @@ "message": "Preencher automaticamente o último login utilizado para o site atual" }, "commandAutofillCardDesc": { - "message": "Preenchimento automático do último cartão utilizado para o site atual" + "message": "Preencher automaticamente o último cartão utilizado para o site atual" }, "commandAutofillIdentityDesc": { - "message": "Autopreencher a última identidade usada para o site atual" + "message": "Preencher automaticamente a última identidade usada para o site atual" }, "commandGeneratePasswordDesc": { "message": "Gerar e copiar uma nova senha aleatória para a área de transferência." @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Use esta senha" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Use este nome de usuário" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Ação do tempo" }, - "newCustomizationOptionsCalloutTitle": { - "message": "Novas opções de personalização" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Personalize a experiência do seu cofre com ações de cópia rápida, modo compacto e muito mais!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "Ver todas as configurações de aparência" - }, "lock": { "message": "Bloquear", "description": "Verb form: to make secure or inaccessible by" @@ -2244,16 +2266,16 @@ "message": "Confirmação de Ação de Tempo Limite" }, "autoFillAndSave": { - "message": "Autopreencher e Salvar" + "message": "Preencher automaticamente e salvar" }, "fillAndSave": { "message": "Preencher e salvar" }, "autoFillSuccessAndSavedUri": { - "message": "Item Auto-Preenchido e URI Salvo" + "message": "Item preenchido automaticamente e URI salva" }, "autoFillSuccess": { - "message": "Item Auto-Preenchido" + "message": "Item preenchido automaticamente " }, "insecurePageWarning": { "message": "Aviso: Esta é uma página HTTP não segura, e qualquer informação que você enviar poderá ser interceptada e modificada por outras pessoas. Este login foi originalmente salvo em uma página segura (HTTPS)." @@ -2482,10 +2504,10 @@ "message": "O Bitwarden não irá pedir para salvar os detalhes de credencial para estes domínios. Você deve atualizar a página para que as alterações entrem em vigor." }, "blockedDomainsDesc": { - "message": "\"Autopreencher\" e outros recursos podem não estar disponíveis para estes sites. Atualize a página para que as mudanças surtam efeito." + "message": "O preenchimento automático e outros recursos podem não estar disponíveis para estes sites. Atualize a página para que as mudanças surtam efeito." }, "autofillBlockedNoticeV2": { - "message": "\"Auto completar\" está bloqueado para este site." + "message": "O preenchimento automático está bloqueado para este site." }, "autofillBlockedNoticeGuidance": { "message": "Altere isso em configurações" @@ -2655,6 +2677,10 @@ "message": "Todos os Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Ocultar texto por padrão" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Nenhum identificador exclusivo encontrado." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ está usando SSO com um servidor de chaves auto-hospedado. Não é mais necessária uma senha mestra para os membros desta organização entrarem.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Sair da Organização" @@ -3420,10 +3446,10 @@ } }, "autofillPageLoadPolicyActivated": { - "message": "Suas políticas de organização ativaram o autopreenchimento ao carregar a página." + "message": "Suas políticas de organização ativaram o preenchimento automático ao carregar a página." }, "howToAutofill": { - "message": "Como autopreencher" + "message": "Como preencher automaticamente" }, "autofillSelectInfoWithCommand": { "message": "Selecione um item desta tela, use o atalho $COMMAND$, ou explore outras opções nas configurações.", @@ -3441,10 +3467,10 @@ "message": "Entendi" }, "autofillSettings": { - "message": "Configurações de autopreenchimento" + "message": "Configurações de preenchimento automático" }, "autofillKeyboardShortcutSectionTitle": { - "message": "Autofill shortcut" + "message": "Atalho de preenchimento automático" }, "autofillKeyboardShortcutUpdateLabel": { "message": "Alterar atalho" @@ -3453,13 +3479,13 @@ "message": "Gerenciar atalhos" }, "autofillShortcut": { - "message": "Atalho para autopreenchimento" + "message": "Atalho de teclado para preenchimento automático" }, "autofillLoginShortcutNotSet": { - "message": "O atalho de acesso ao preenchimento automático não está definido. Altere isso nas configurações do navegador." + "message": "O atalho do preenchimento automático não está definido. Altere isso nas configurações do navegador." }, "autofillLoginShortcutText": { - "message": "O atalho de login de preenchimento automático é $COMMAND$. Gerencie todos os atalhos nas configurações do navegador.", + "message": "O atalho de preenchimento automático é $COMMAND$. Gerencie todos os atalhos nas configurações do navegador.", "placeholders": { "command": { "content": "$1", @@ -3468,7 +3494,7 @@ } }, "autofillShortcutTextSafari": { - "message": "Atalho padrão de autopreenchimento: $COMMAND$.", + "message": "Atalho padrão de preenchimento automático: $COMMAND$.", "placeholders": { "command": { "content": "$1", @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Dispositivo confiável" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "Nenhum Send ativo", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Use o Send para compartilhar informação criptografa com qualquer um.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Entrada necessária." }, @@ -3692,11 +3750,11 @@ "message": "Alias do domínio" }, "passwordRepromptDisabledAutofillOnPageLoad": { - "message": "Os itens com confirmação de senha mestra não podem ser auto-preenchidos ao carregar a página. O carregamento da página será desativado.", + "message": "Os itens com confirmação de senha mestra não podem ser preenchidos automaticamente ao carregar a página. O preenchimento automático ao carregar a página será desativado.", "description": "Toast message for describing that master password re-prompt cannot be autofilled on page load." }, "autofillOnPageLoadSetToDefault": { - "message": "Definir preenchimento automático ao carregar página para usar a configuração padrão.", + "message": "O preenchimento automático ao carregar a página está usando a configuração padrão.", "description": "Toast message for informing the user that autofill on page load has been set to the default setting." }, "turnOffMasterPasswordPromptToEditField": { @@ -3710,15 +3768,15 @@ "message": "Ir para o conteúdo" }, "bitwardenOverlayButton": { - "message": "Botão de Menu de Autopreenchimento Bitwarden", + "message": "Botão de menu de preenchimento automático do Bitwarden", "description": "Page title for the iframe containing the overlay button" }, "toggleBitwardenVaultOverlay": { - "message": "Alternar menu de autopreenchimento do Bitwarden", + "message": "Ativar menu de preenchimento automático do Bitwarden", "description": "Screen reader and tool tip label for the overlay button" }, "bitwardenVault": { - "message": "Menu de autopreenchimento Bitwarden", + "message": "Menu de preenchimento automático do Bitwarden", "description": "Page title in overlay" }, "unlockYourAccountToViewMatchingLogins": { @@ -3738,11 +3796,11 @@ "description": "Screen reader text (aria-label) for unlock account button in overlay" }, "totpCodeAria": { - "message": "Código de Verificação TOTP", + "message": "Código de verificação TOTP", "description": "Aria label for the totp code displayed in the inline menu for autofill" }, "totpSecondsSpanAria": { - "message": "Tempo até expirar o código", + "message": "Tempo até o código expirar", "description": "Aria label for the totp seconds displayed in the inline menu for autofill" }, "fillCredentialsFor": { @@ -3790,7 +3848,7 @@ "description": "Screen reader text (aria-label) for new identity button within inline menu" }, "bitwardenOverlayMenuAvailable": { - "message": "Menu de autopreenchimento do Bitwarden disponível. Pressione a tecla de seta para baixo para selecionar.", + "message": "Menu de preenchimento automático do Bitwarden disponível. Pressione a tecla de seta para baixo para selecionar.", "description": "Screen reader text for announcing when the overlay opens on the page" }, "turnOn": { @@ -4167,7 +4225,7 @@ "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" }, "confirmContinueToHelpCenterPasswordManagementContent": { - "message": "Alterar as configurações de autopreenchimento e gerenciamento de senhas do seu navegador.", + "message": "Altere as configurações de preenchimento automático e gerenciamento de senhas do seu navegador.", "description": "Body content for dialog which asks if the user wants to proceed to the Help Center's page about browser password management settings" }, "confirmContinueToHelpCenterKeyboardShortcutsContent": { @@ -4175,7 +4233,7 @@ "description": "Body content for dialog which asks if the user wants to proceed to the Help Center's page about browser keyboard shortcut settings" }, "confirmContinueToBrowserPasswordManagementSettingsContent": { - "message": "Alterar as configurações de autopreenchimento e gerenciamento de senhas do seu navegador.", + "message": "Altere as configurações de preenchimento automático e gerenciamento de senhas do seu navegador.", "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" }, "confirmContinueToBrowserKeyboardShortcutSettingsContent": { @@ -4187,7 +4245,7 @@ "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignorar esta opção pode causar conflitos entre o menu de autopreenchimento do Bitwarden e o do seu navegador.", + "message": "Ignorar esta opção pode causar conflitos entre o menu de preenchimento automático do Bitwarden e o do seu navegador.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -4318,7 +4376,7 @@ } }, "autofillTitle": { - "message": "Auto-preenchimento - $ITEMNAME$", + "message": "Preencher automaticamente - $ITEMNAME$", "description": "Title for a button that autofills a login item.", "placeholders": { "itemname": { @@ -4328,7 +4386,7 @@ } }, "autofillTitleWithField": { - "message": "Autocompletar - $ITEMNAME$ - $FIELD$", + "message": "Preencher automaticamente - $ITEMNAME$ - $FIELD$", "description": "Title for a button that autofills a login item.", "placeholders": { "itemname": { @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Tem certeza de que deseja excluir este anexo permanentemente?" }, @@ -4544,7 +4629,7 @@ "message": "Chave do autenticador" }, "autofillOptions": { - "message": "Opções de autopreenchimento" + "message": "Opções de preenchimento automático" }, "websiteUri": { "message": "Site (URI)" @@ -4597,7 +4682,7 @@ } }, "autoFillOnPageLoad": { - "message": "Preenchimento automático ao carregar a página?" + "message": "Preencher automaticamente ao carregar a página?" }, "cardExpiredTitle": { "message": "Cartão expirado" @@ -4687,7 +4772,7 @@ "message": "Use caixas de seleção se gostaria de preencher automaticamente a caixa de seleção de um formulário, como um e-mail de lembrança" }, "linkedHelpText": { - "message": "Use um campo vinculado quando estiver enfrentando problemas com o auto-preenchimento com um site específico." + "message": "Use um campo vinculado quando estiver enfrentando problemas com o preenchimento automático com um site específico." }, "linkedLabelHelpText": { "message": "Digite o Id html do campo, nome, nome aria-label, ou espaço reservado." @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "O desbloqueio por biometria está indisponível por razões desconhecidas." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Autenticando" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Aviso importante" - }, - "setupTwoStepLogin": { - "message": "Configurar login em duas etapas" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden enviará um código para o seu e-mail para verificar novos dispositivos a partir de fevereiro de 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "Você pode configurar o login em duas etapas como uma forma alternativa de proteger sua conta ou mudar seu e-mail para um que você possa acessar." - }, - "remindMeLater": { - "message": "Lembre-me depois" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Você tem acesso ao seu e-mail, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "Não tenho" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Sim, posso acessar meu e-mail de forma confiável" - }, - "turnOnTwoStepLogin": { - "message": "Ativar login em duas etapas" - }, - "changeAcctEmail": { - "message": "Alterar e-mail" - }, "extensionWidth": { "message": "Largura da janela" }, @@ -5220,7 +5278,7 @@ "message": "Login rápido e fácil" }, "quickLoginBody": { - "message": "Ative o desbloqueio por biometria e o autopreenchimento para acessar suas contas sem digitar uma única letra." + "message": "Ative o desbloqueio por biometria e o preenchimento automático para acessar suas contas sem digitar uma única letra." }, "secureUser": { "message": "Melhore seus logins de nível" @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Guarde quantas senhas quiser e acesse de qualquer lugar com o Bitwarden. No seu celular, navegador e computador." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,26 +5307,44 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { - "message": "Save time with autofill" + "message": "Seja mais rápido com o preenchimento automático" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" }, "newCardNudgeBody": { - "message": "With cards, easily autofill payment forms securely and accurately." + "message": "Preencha automaticamente formulários de pagamento com cartões de forma segura e precisa." }, "newIdentityNudgeTitle": { "message": "Simplify creating accounts" }, "newIdentityNudgeBody": { - "message": "With identities, quickly autofill long registration or contact forms." + "message": "Preencha automaticamente formulários longos de registro ou contato de forma rápida." }, "newNoteNudgeTitle": { "message": "Keep your sensitive data safe" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/pt_PT/messages.json b/apps/browser/src/_locales/pt_PT/messages.json index 0af5cb2d13f..50a2aeb20bd 100644 --- a/apps/browser/src/_locales/pt_PT/messages.json +++ b/apps/browser/src/_locales/pt_PT/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "Novo item, abre numa nova janela", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Editar antes de guardar", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ guardado no Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "guardado no Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ atualizado no Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "atualizado no Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Selecionar $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Guardar como nova credencial", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Atualizar credencial", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Desbloqueie para guardar esta credencial", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Guardar credencial", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Sugestões de preenchimento automático" }, + "autofillSpotlightTitle": { + "message": "Encontre facilmente sugestões de preenchimento automático" + }, + "autofillSpotlightDesc": { + "message": "Desative as definições de preenchimento automático do seu navegador, para que não entrem em conflito com o Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Desative o preenchimento automático do $BROWSER$", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Desativar o preenchimento automático" + }, "showInlineMenuLabel": { "message": "Mostrar sugestões de preenchimento automático nos campos do formulário" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Utilizar esta palavra-passe" }, + "useThisPassphrase": { + "message": "Utilizar esta frase de acesso" + }, "useThisUsername": { "message": "Utilizar este nome de utilizador" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Ação de tempo limite" }, - "newCustomizationOptionsCalloutTitle": { - "message": "Novas opções de personalização" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Personalize a sua experiência no cofre com ações de cópia rápida, modo compacto e muito mais!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "Ver todas as definições de Aspeto" - }, "lock": { "message": "Bloquear", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "Todos os Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Número máximo de acessos atingido", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Ocultar texto por predefinição" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Não foi encontrado um identificador único." }, - "convertOrganizationEncryptionDesc": { - "message": "A $ORGANIZATION$ está a utilizar o SSO com um servidor de chaves auto-hospedado. Já não é necessária uma palavra-passe mestra para iniciar sessão para os membros desta organização.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "Já não é necessária uma palavra-passe mestra para os membros da seguinte organização. Por favor, confirme o domínio abaixo com o administrador da sua organização." + }, + "organizationName": { + "message": "Nome da organização" + }, + "keyConnectorDomain": { + "message": "Domínio do Key Connector" }, "leaveOrganization": { "message": "Sair da organização" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Dispositivo de confiança" }, + "trustOrganization": { + "message": "Confiar na organização" + }, + "trust": { + "message": "Confiar" + }, + "doNotTrust": { + "message": "Não confiar" + }, + "organizationNotTrusted": { + "message": "A organização não é de confiança" + }, + "emergencyAccessTrustWarning": { + "message": "Para segurança da sua conta, confirme apenas se tiver concedido acesso de emergência a este utilizador e se a sua impressão digital corresponder à que é apresentada na sua conta" + }, + "orgTrustWarning": { + "message": "Para segurança da sua conta, prossiga apenas se for membro desta organização, tiver a recuperação de conta ativada e a impressão digital apresentada abaixo corresponder à impressão digital da organização." + }, + "orgTrustWarning1": { + "message": "Esta organização tem uma política empresarial que o registará na recuperação de conta. A inscrição permitirá que os administradores da organização alterem a sua palavra-passe. Avance apenas se reconhecer esta organização e se a frase de impressão digital apresentada abaixo corresponder à impressão digital da organização." + }, + "trustUser": { + "message": "Confiar no utilizador" + }, "sendsNoItemsTitle": { "message": "Sem Sends ativos", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Utilize o Send para partilhar de forma segura informações encriptadas com qualquer pessoa.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Envie informações sensíveis com segurança", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Partilhe ficheiros e dados de forma segura com qualquer pessoa, em qualquer plataforma. As suas informações permanecerão encriptadas ponto a ponto, limitando a exposição.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Campo obrigatório." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Descarregar o Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Descarregue o Bitwarden em todos os dispositivos" + }, + "getTheMobileApp": { + "message": "Obtenha a app móvel" + }, + "getTheMobileAppDesc": { + "message": "Aceda às suas palavras-passe em qualquer lugar com a app móvel Bitwarden." + }, + "getTheDesktopApp": { + "message": "Obtenha a app para computador" + }, + "getTheDesktopAppDesc": { + "message": "Aceda ao seu cofre sem um navegador e, em seguida, configure o desbloqueio com biometria para acelerar o desbloqueio na app para computador e na extensão do navegador." + }, + "downloadFromBitwardenNow": { + "message": "Descarregue já a partir de bitwarden.com" + }, + "getItOnGooglePlay": { + "message": "Obtenha-a na Google Play" + }, + "downloadOnTheAppStore": { + "message": "Descarregue na App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Tem a certeza de que pretende eliminar permanentemente este anexo?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "O desbloqueio biométrico está atualmente indisponível por um motivo desconhecido." }, + "unlockVault": { + "message": "Desbloqueie o seu cofre em segundos" + }, + "unlockVaultDesc": { + "message": "Pode personalizar as suas definições de desbloqueio e de tempo limite para aceder mais rapidamente ao seu cofre." + }, + "unlockPinSet": { + "message": "Definição do PIN de desbloqueio" + }, "authenticating": { "message": "A autenticar" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Aviso importante" - }, - "setupTwoStepLogin": { - "message": "Definir a verificação de dois passos" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "O Bitwarden enviará um código para o e-mail da sua conta para verificar as credenciais de novos dispositivos a partir de fevereiro de 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "Pode configurar a verificação de dois passos como forma alternativa de proteger a sua conta ou alterar o seu e-mail para um a que possa aceder." - }, - "remindMeLater": { - "message": "Lembrar-me mais tarde" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Tem um acesso fiável ao seu e-mail, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "Não, não tenho" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Sim, consigo aceder de forma fiável ao meu e-mail" - }, - "turnOnTwoStepLogin": { - "message": "Ativar a verificação de dois passos" - }, - "changeAcctEmail": { - "message": "Alterar o e-mail da conta" - }, "extensionWidth": { "message": "Largura da extensão" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Guarde palavras-passe ilimitadas em dispositivos ilimitados com as apps Bitwarden para telemóvel, navegador e computador." }, + "nudgeBadgeAria": { + "message": "1 notificação" + }, "emptyVaultNudgeTitle": { "message": "Importar palavras-passe existentes" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Bem-vindo ao seu cofre!" }, - "hasItemsVaultNudgeBody": { - "message": "Preenchimento automático de itens para a página atual\nItens favoritos para um acesso fácil\nProcurar outra coisa no seu cofre" + "hasItemsVaultNudgeBodyOne": { + "message": "Preenchimento automático de itens para a página atual" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Adicione itens aos favoritos para fácil acesso" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Procure outras coisas no seu cofre" }, "newLoginNudgeTitle": { "message": "Poupe tempo com o preenchimento automático" }, - "newLoginNudgeBody": { - "message": "Inclua um site para que esta credencial apareça como uma sugestão de preenchimento automático." + "newLoginNudgeBodyOne": { + "message": "Inclua um", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "site", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "para que esta credencial apareça como uma sugestão de preenchimento automático.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Pagamentos online sem problemas" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Acesso SSH de fácil utilização pelos programadores" }, - "newSshNudgeBody": { - "message": "Guarde as suas chaves e ligue-se ao agente SSH para uma autenticação rápida e encriptada." + "newSshNudgeBodyOne": { + "message": "Guarde as suas chaves e ligue-se ao agente SSH para uma autenticação rápida e encriptada.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Saiba mais sobre o agente SSH", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Criar rapidamente palavras-passe" + }, + "generatorNudgeBodyOne": { + "message": "Crie facilmente palavras-passe fortes e únicas clicando em", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "para o ajudar a manter as suas credenciais seguras.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Crie facilmente palavras-passe fortes e únicas clicando no botão Gerar palavra-passe para o ajudar a manter as suas credenciais seguras.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "Não tem permissões para ver esta página. Tente iniciar sessão com uma conta diferente." } } diff --git a/apps/browser/src/_locales/ro/messages.json b/apps/browser/src/_locales/ro/messages.json index bf08e0969b2..375f97ef265 100644 --- a/apps/browser/src/_locales/ro/messages.json +++ b/apps/browser/src/_locales/ro/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Autofill suggestions" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Show autofill suggestions on form fields" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Use this password" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Use this username" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Timeout action" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "Blocare", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "Toate Send-urile", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Hide text by default" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Nu a fost găsit niciun identificator unic." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ folosește SSO cu un server de chei autogăzduit. Membrii acestei organizații nu mai au nevoie de o parolă principală pentru autentificare.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Părăsire organizație" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Dispozitiv de încredere" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "No active Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Use Send to securely share encrypted information with anyone.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Este necesară o intrare." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Are you sure you want to permanently delete this attachment?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Authenticating" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Important notice" - }, - "setupTwoStepLogin": { - "message": "Set up two-step login" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Remind me later" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" - }, - "turnOnTwoStepLogin": { - "message": "Turn on two-step login" - }, - "changeAcctEmail": { - "message": "Change account email" - }, "extensionWidth": { "message": "Extension width" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/ru/messages.json b/apps/browser/src/_locales/ru/messages.json index f6343f6d2bb..a6c16ca01ce 100644 --- a/apps/browser/src/_locales/ru/messages.json +++ b/apps/browser/src/_locales/ru/messages.json @@ -206,7 +206,7 @@ "message": "Автозаполнение карты" }, "autoFillIdentity": { - "message": "Автозаполнение личности" + "message": "Автозаполнение личной информации" }, "fillVerificationCode": { "message": "Заполнить код подтверждения" @@ -228,7 +228,7 @@ "message": "Нет карт" }, "noIdentities": { - "message": "Нет личностей" + "message": "Нет личной информации" }, "addLoginMenu": { "message": "Добавить логин" @@ -237,7 +237,7 @@ "message": "Добавить карту" }, "addIdentityMenu": { - "message": "Добавить личность" + "message": "Добавить личную информацию" }, "unlockVaultMenu": { "message": "Разблокировать хранилище" @@ -1037,10 +1037,10 @@ "message": "Всегда показывать личности как предложения автозаполнения при просмотре хранилища" }, "showIdentitiesCurrentTab": { - "message": "Показывать Личности на вкладке" + "message": "Показывать Личную информацию на вкладке" }, "showIdentitiesCurrentTabDesc": { - "message": "Личности будут отображены на вкладке для удобного автозаполнения." + "message": "Личная информация будет отображена на вкладке для удобного автозаполнения." }, "clickToAutofillOnVault": { "message": "Кликните элементы для автозаполнения в режиме просмотра хранилища" @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "Новый элемент, откроется в новом окне", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Изменить перед сохранением", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ сохранен в Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "сохранено в Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ обновлен в Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "обновлено в Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Выберите $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Сохранить как новый логин", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Обновить логин", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Разблокировать, чтобы сохранить этот логин", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Сохранить логин", "description": "Prompt asking the user if they want to save their login details." @@ -1589,11 +1599,29 @@ "autofillSuggestionsSectionTitle": { "message": "Предложения по автозаполнению" }, + "autofillSpotlightTitle": { + "message": "Легкий поиск предложений автозаполнения" + }, + "autofillSpotlightDesc": { + "message": "Отключите настройки автозаполнения в браузере, чтобы они не конфликтовали с Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Отключить автозаполнение $BROWSER$", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Отключить автозаполнение" + }, "showInlineMenuLabel": { "message": "Показывать предположения автозаполнения в полях формы" }, "showInlineMenuIdentitiesLabel": { - "message": "Показывать Личности как предложения" + "message": "Показывать Личную информацию как предложения" }, "showInlineMenuCardsLabel": { "message": "Показывать Карты как предложения" @@ -1671,7 +1699,7 @@ "message": "Автозаполнение последней использованной карты для текущего сайта" }, "commandAutofillIdentityDesc": { - "message": "Автозаполнение последней использованной личности для текущего сайта" + "message": "Автозаполнение последних использованных личных данных для текущего сайта" }, "commandGeneratePasswordDesc": { "message": "Сгенерировать и скопировать новый случайный пароль в буфер обмена." @@ -1829,7 +1857,7 @@ "message": "Полное имя" }, "identityName": { - "message": "Название личности" + "message": "Название личной информации" }, "company": { "message": "Компания" @@ -1961,7 +1989,7 @@ "message": "Карты" }, "identities": { - "message": "Личные данные" + "message": "Личная информация" }, "logins": { "message": "Логины" @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Использовать этот пароль" }, + "useThisPassphrase": { + "message": "Использовать эту парольную фразу" + }, "useThisUsername": { "message": "Использовать это имя пользователя" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Тайм-аут действия" }, - "newCustomizationOptionsCalloutTitle": { - "message": "Новые возможности настроек" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Настройте работу с хранилищем с помощью действий быстрого копирования, компактного режима и многого другого!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "Посмотреть все настройки внешнего вида" - }, "lock": { "message": "Блокировка", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "Все Send’ы", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Достигнут максимум обращений", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Скрыть текст по умолчанию" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Уникальный идентификатор не найден." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ использует SSO с собственным сервером ключей. Для авторизации пользователям этой организации больше не требуется мастер-пароль.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "Мастер-пароль больше не требуется для членов следующей организации. Пожалуйста, подтвердите указанный ниже домен у администратора вашей организации." + }, + "organizationName": { + "message": "Название организации" + }, + "keyConnectorDomain": { + "message": "Домен соединителя ключей" }, "leaveOrganization": { "message": "Покинуть организацию" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Доверенное устройство" }, + "trustOrganization": { + "message": "Доверенная организация" + }, + "trust": { + "message": "Доверять" + }, + "doNotTrust": { + "message": "Не доверять" + }, + "organizationNotTrusted": { + "message": "Организации не доверяют" + }, + "emergencyAccessTrustWarning": { + "message": "В целях обеспечения безопасности вашего аккаунта подтверждайте только в том случае, если вы предоставили этому пользователю экстренный доступ и его отпечаток совпадает с отображаемым в его аккаунте" + }, + "orgTrustWarning": { + "message": "В целях обеспечения безопасности вашего аккаунта продолжайте только в том случае, если вы являетесь членом этой организации, у вас включено восстановление аккаунта, а отображаемый ниже отпечаток совпадает с отпечатком организации." + }, + "orgTrustWarning1": { + "message": "В этой организации действует политика, которая позволит вам участвовать в восстановлении аккаунта. Регистрация позволит администраторам организации изменить ваш пароль. Продолжайте, только если вы знаете эту организацию и фраза отпечатков, показанная ниже, совпадает с отпечатками организации." + }, + "trustUser": { + "message": "Доверенный пользователь" + }, "sendsNoItemsTitle": { "message": "Нет активных Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Используйте Send для безопасного обмена зашифрованной информацией с кем угодно.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Безопасная отправка конфиденциальной информации", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Безопасно обменивайтесь файлами и данными с кем угодно на любой платформе. Ваша информация надежно шифруется и доступ к ней ограничен.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Необходимо ввести данные." }, @@ -3782,11 +3840,11 @@ "description": "Screen reader text (aria-label) for new card button within inline menu" }, "newIdentity": { - "message": "Новая личность", + "message": "Новая личная информация", "description": "Button text to display within inline menu when there are no matching items on an identity field" }, "addNewIdentityItemAria": { - "message": "Добавление новой личности в хранилище, откроется в новом окне", + "message": "Добавление новой личной информации в хранилище, откроется в новом окне", "description": "Screen reader text (aria-label) for new identity button within inline menu" }, "bitwardenOverlayMenuAvailable": { @@ -4025,7 +4083,7 @@ "message": "Функция пока не поддерживается" }, "yourPasskeyIsLocked": { - "message": "Для использования passkey необходима аутентификация. Для продолжения работы подтвердите свою личность." + "message": "Для использования passkey необходима аутентификация. Для продолжения работы подтвердите вашу личность." }, "multifactorAuthenticationCancelled": { "message": "Многофакторная аутентификация отменена" @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Скачать Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Скачать Bitwarden на все устройства" + }, + "getTheMobileApp": { + "message": "Скачать мобильное приложение" + }, + "getTheMobileAppDesc": { + "message": "Доступ к вашим паролям через мобильное приложение Bitwarden." + }, + "getTheDesktopApp": { + "message": "Скачать приложение для компьютера" + }, + "getTheDesktopAppDesc": { + "message": "Получите доступ к хранилищу без браузера, затем настройте разблокировку с помощью биометрии для ускорения разблокировки в приложении для компьютера и расширении браузера." + }, + "downloadFromBitwardenNow": { + "message": "Скачать с bitwarden.com" + }, + "getItOnGooglePlay": { + "message": "Получить на Google Play" + }, + "downloadOnTheAppStore": { + "message": "Скачать из App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Вы уверены, что хотите навсегда удалить это вложение?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Биометрическая разблокировка в настоящее время недоступна по неизвестной причине." }, + "unlockVault": { + "message": "Разблокируйте свое хранилище за считанные секунды" + }, + "unlockVaultDesc": { + "message": "Вы можете настроить параметры разблокировки и тайм-аута для более быстрого доступа к хранилищу." + }, + "unlockPinSet": { + "message": "Установить PIN--код разблокировки" + }, "authenticating": { "message": "Аутентификация" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Важное уведомление" - }, - "setupTwoStepLogin": { - "message": "Настроить двухэтапную аутентификацию" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Начиная с февраля 2025 года Bitwarden будет отправлять код на электронную почту вашего аккаунта для подтверждения авторизации с новых устройств." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "В качестве альтернативного способа защиты учетной записи вы можете настроить двухэтапную аутентификацию или сменить электронную почту на ту, к которой вы можете получить доступ." - }, - "remindMeLater": { - "message": "Напомнить позже" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Есть ли у вас надежный доступ к электронной почте $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "Нет, не знаю" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Да, я имею надежный доступ к своей электронной почте" - }, - "turnOnTwoStepLogin": { - "message": "Включить двухэтапную аутентификацию" - }, - "changeAcctEmail": { - "message": "Изменить email аккаунта" - }, "extensionWidth": { "message": "Ширина расширения" }, @@ -5214,7 +5272,7 @@ "message": "Безопасность, приоритет" }, "securityPrioritizedBody": { - "message": "Сохраняйте логины, карты и личные данные в своем защищенном хранилище. Bitwarden использует сквозное шифрование, чтобы защитить то, что для вас важно." + "message": "Сохраняйте логины, карты и личную информацию в своем защищенном хранилище. Bitwarden использует сквозное шифрование, чтобы защитить то, что для вас важно." }, "quickLogin": { "message": "Быстрая и простая авторизация" @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Сохраняйте неограниченное количество паролей на неограниченном количестве устройств с помощью мобильных, браузерных и десктопных приложений Bitwarden." }, + "nudgeBadgeAria": { + "message": "1 уведомление" + }, "emptyVaultNudgeTitle": { "message": "Импорт существующих паролей" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Добро пожаловать в ваше хранилище!" }, - "hasItemsVaultNudgeBody": { - "message": "Автозаполнение элементов для текущей страницы\nИзбранные элементы для легкого доступа\nПоиск в хранилище для чего-либо еще" + "hasItemsVaultNudgeBodyOne": { + "message": "Автозаполнение элементов на текущей странице" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Избранные элементы для легкого доступа" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Ищите в своем хранилище все, что хотите" }, "newLoginNudgeTitle": { "message": "Экономьте время с помощью автозаполнения" }, - "newLoginNudgeBody": { - "message": "Включите сайт, чтобы этот логин отображался в качестве предложения для автозаполнения." + "newLoginNudgeBodyOne": { + "message": "Включите", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "сайт", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "чтобы этот логин отображался в качестве предложения для автозаполнения.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Оформление заказа через интернет" @@ -5265,7 +5344,7 @@ "message": "Упрощение создания аккаунтов" }, "newIdentityNudgeBody": { - "message": "С помощью личностей можно быстро заполнять длинные регистрационные или контактные формы." + "message": "С помощью личной информации можно быстро заполнять длинные регистрационные или контактные формы." }, "newNoteNudgeTitle": { "message": "Храните ваши конфиденциальные данные в безопасности" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Удобный для разработчиков SSH-доступ" }, - "newSshNudgeBody": { - "message": "Храните свои ключи и подключайтесь с помощью агента SSH для быстрой и зашифрованной аутентификации." + "newSshNudgeBodyOne": { + "message": "Храните свои ключи и подключайтесь с помощью агента SSH для быстрой и зашифрованной аутентификации.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Узнайте больше об агенте SSH", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Быстрое создание паролей" + }, + "generatorNudgeBodyOne": { + "message": "Легко создавайте надежные и уникальные пароли, нажатием на кнопку,", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "чтобы обеспечить безопасность ваших логинов.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Легко создавайте надежные и уникальные пароли, нажатием на кнопку 'Сгенерировать пароль', чтобы обеспечить безопасность ваших логинов.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "У вас нет прав для просмотра этой страницы. Попробуйте авторизоваться под другим аккаунтом." } } diff --git a/apps/browser/src/_locales/si/messages.json b/apps/browser/src/_locales/si/messages.json index a5f7e772505..1b024ddaae8 100644 --- a/apps/browser/src/_locales/si/messages.json +++ b/apps/browser/src/_locales/si/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Autofill suggestions" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Show autofill suggestions on form fields" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Use this password" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Use this username" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Timeout action" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "අගුල", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "සියලු යවයි", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Hide text by default" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "අද්විතීය හඳුනාගැනීමක් සොයාගත නොහැකි විය." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ ස්වයං සත්කාරක යතුරු සේවාදායකයක් සමඟ SSO භාවිතා කරයි. මෙම සංවිධානයේ සාමාජිකයන් සඳහා ප්රවිෂ්ට වීමට ප්රධාන මුරපදයක් තවදුරටත් අවශ්ය නොවේ.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "සංවිධානය හැරයන්න" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Device trusted" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "No active Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Use Send to securely share encrypted information with anyone.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Input is required." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Are you sure you want to permanently delete this attachment?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Authenticating" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Important notice" - }, - "setupTwoStepLogin": { - "message": "Set up two-step login" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Remind me later" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" - }, - "turnOnTwoStepLogin": { - "message": "Turn on two-step login" - }, - "changeAcctEmail": { - "message": "Change account email" - }, "extensionWidth": { "message": "Extension width" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/sk/messages.json b/apps/browser/src/_locales/sk/messages.json index 5f65633e44c..d25ea28a614 100644 --- a/apps/browser/src/_locales/sk/messages.json +++ b/apps/browser/src/_locales/sk/messages.json @@ -474,7 +474,7 @@ "message": "Používateľské meno vygenerované" }, "emailGenerated": { - "message": "E-mail vygenoravný" + "message": "E-mail vygenerovaný" }, "regeneratePassword": { "message": "Vygenerovať nové heslo" @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "Nová položka, otvorí sa v novom okne", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Upraviť pred uložením", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ uložené do Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "uložené do Bitwardenu.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ aktualizované v Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "aktualizované v Bitwardene.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Vybrať $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Uložiť ako nové prihlasovacie údaje", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Aktualizovať prihlasovacie údaje", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Odomknúť na uloženie prihlasovacích údajov", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Uložiť prihlasovacie údaje", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Návrhy automatického vypĺňania" }, + "autofillSpotlightTitle": { + "message": "Jednoduché vyhľadávanie návrhov na automatické vypĺňanie" + }, + "autofillSpotlightDesc": { + "message": "Vypnite nastavenia automatického vypĺňania v prehliadači, aby nedošlo ku konfliktu s Bitwardenom." + }, + "turnOffBrowserAutofill": { + "message": "Vypnúť automatické vypĺňanie v $BROWSER$", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Vypnúť automatické vypĺňanie" + }, "showInlineMenuLabel": { "message": "Zobraziť návrhy automatického vypĺňania v poliach formulára" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Použiť toto heslo" }, + "useThisPassphrase": { + "message": "Použiť túto prístupovú frázu" + }, "useThisUsername": { "message": "Použiť toto používateľské meno" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Akcia pri vypršaní časového limitu" }, - "newCustomizationOptionsCalloutTitle": { - "message": "Nové možnosti prispôsobenia" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Prispôsobte si trezor pomocou akcií rýchleho kopírovania, kompaktného režimu a ďalších možností!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "Zobraziť všetky nastavenia vzhľadu" - }, "lock": { "message": "Uzamknúť", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "Všetky Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Bol dosiahnutý maximálny počet prístupov", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "V predvolenom nastavení skryť text" }, @@ -2747,7 +2773,7 @@ "message": "Nové heslo" }, "sendDisabled": { - "message": "Send zakázaný", + "message": "Send bol odstránený", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendDisabledWarning": { @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Nenašiel sa žiadny jedinečný identifikátor." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ používa SSO s vlastným kľúčovým serverom. Na prihlásenie členov tejto organizácie už nie je potrebné hlavné heslo.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "Hlavné heslo sa už nevyžaduje pre členov tejto organizácie. Nižšie uvedenú doménu potvrďte u správcu organizácie." + }, + "organizationName": { + "message": "Názov organizácie" + }, + "keyConnectorDomain": { + "message": "Doména Key Connectora" }, "leaveOrganization": { "message": "Opustiť organizáciu" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Dôveryhodné zariadenie" }, + "trustOrganization": { + "message": "Dôverovať organizácii" + }, + "trust": { + "message": "Dôverovať" + }, + "doNotTrust": { + "message": "Nedôverovať" + }, + "organizationNotTrusted": { + "message": "Organizácia nie je dôveryhodná" + }, + "emergencyAccessTrustWarning": { + "message": "Pre bezpečnosť vášho účtu stačí overiť, ze ste tomuto používateľovi udelili núdzový pristúp, a že odtlačok sa zhoduje s odtlačkom zobrazenom v používateľovom účte" + }, + "orgTrustWarning": { + "message": "Pre bezpečnosť vášho účtu pokračujte, iba ak ste členom organizácie, máte povolenú obnovu účtu a odtlačok sa zhoduje s odtlačkom organizácie." + }, + "orgTrustWarning1": { + "message": "Táto organizácia má pravidlá spoločnosti, ktoré vás zaregistrujú do obnovy účtu. Zápis umožní správcom organizácie zmeniť vaše heslo. Pokračujte len vtedy, ak túto organizáciu poznáte a nižšie zobrazená fráza odtlačku prsta sa zhoduje s odtlačkom prsta organizácie." + }, + "trustUser": { + "message": "Dôverovať používateľovi" + }, "sendsNoItemsTitle": { "message": "Žiadne aktívne Sendy", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Použite Send na bezpečné zdieľanie zašifrovaných informácii s kýmkoľvek.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send, citlivé informácie bezpečne", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Bezpečne zdieľajte súbory a údaje s kýmkoľvek a na akejkoľvek platforme. Vaše informácie zostanú end-to-end zašifrované a zároveň sa obmedzí ich odhalenie.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Vstup je povinný." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Stiahnuť Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Stiahnuť Bitwarden na všetky zariadenia" + }, + "getTheMobileApp": { + "message": "Získajte mobilnú aplikáciu" + }, + "getTheMobileAppDesc": { + "message": "Majte prístup k heslám na cestách pomocou mobilnej aplikácie Bitwarden." + }, + "getTheDesktopApp": { + "message": "Získať desktopovú aplikáciu" + }, + "getTheDesktopAppDesc": { + "message": "Pristupujte k trezoru bez prehliadača, a potom nastavte odomykanie pomocou biometrie, aby ste urýchlili odomykanie v desktopovej aplikácii aj v rozšírení prehliadača." + }, + "downloadFromBitwardenNow": { + "message": "Stiahnuť teraz z bitwarden.com" + }, + "getItOnGooglePlay": { + "message": "Získať z Google Play" + }, + "downloadOnTheAppStore": { + "message": "Stiahnuť z App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Naozaj chcete natrvalo odstrániť túto prílohu?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Odomykanie biometrickými údajmi je momentálne z neznámych dôvodov nedostupné." }, + "unlockVault": { + "message": "Odomknite trezor za pár sekúnd" + }, + "unlockVaultDesc": { + "message": "Pre rýchlejší prístup k trezoru si môžete upraviť nastavenia odomknutia a časový limit." + }, + "unlockPinSet": { + "message": "PIN na odomknutie nastavený" + }, "authenticating": { "message": "Overuje sa" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Dôležité upozornenie" - }, - "setupTwoStepLogin": { - "message": "Nastavenie dvojstupňového prihlásenia" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden vám od februára 2025 pošle na e-mail vášho účtu kód na overenie prihlásenia z nových zariadení." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "Ako alternatívny spôsob ochrany svojho účtu môžete nastaviť dvojstupňové prihlásenie alebo zmeniť e-mail na taký, ku ktorému máte prístup." - }, - "remindMeLater": { - "message": "Pripomenúť neskôr" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Máte zaručený prístup k e-mailu $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "Nie, nemám" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Áno, mám zaručený prístup k e-mailu" - }, - "turnOnTwoStepLogin": { - "message": "Zapnúť dvojstupňové prihlásenie" - }, - "changeAcctEmail": { - "message": "Zmeniť e-mail účtu" - }, "extensionWidth": { "message": "Šírka rozšírenia" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Ukladajte neobmedzený počet hesiel na neobmedzenom počte zariadení pomocou mobilných aplikácií, prehliadačov a desktopových aplikácií Bitwardenu." }, + "nudgeBadgeAria": { + "message": "1 upozornenie" + }, "emptyVaultNudgeTitle": { "message": "Import existujúcich hesiel" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Vitajte vo svojom trezore!" }, - "hasItemsVaultNudgeBody": { - "message": "Automatické vypĺňanie položiek pre aktuálnu stránku\nObľúbené položky pre ľahký prístup\nVyhľadajte v trezore niečo iné" + "hasItemsVaultNudgeBodyOne": { + "message": "Položky na automatické vypĺňanie pre aktuálnu stránku" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Obľúbené položky pre jednoduchý prístup" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Vyhľadajte v trezore niečo iné" }, "newLoginNudgeTitle": { "message": "Ušetrite čas s automatickým vypĺňaním" }, - "newLoginNudgeBody": { - "message": "Zadajte webovú stránku, aby sa tieto prihlasovacie údaje zobrazili ako návrh na automatické vyplnenie." + "newLoginNudgeBodyOne": { + "message": "Zahrnúť", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "webstránku", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "aby sa tieto prihlasovacie údaje zobrazili ako návrh na automatické vyplnenie.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Bezproblémová online registrácia" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Prístup SSH vhodný pre vývojárov" }, - "newSshNudgeBody": { - "message": "Uložte si kľúče a pripojte sa pomocou agenta SSH na rýchle šifrované overovanie." + "newSshNudgeBodyOne": { + "message": "Uložte si kľúče a pripojte sa pomocou agenta SSH na rýchle šifrované overovanie.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Viac informácií o agentovi SSH", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Rýchle vytváranie hesiel" + }, + "generatorNudgeBodyOne": { + "message": "Jednoducho vytvorte silné a jedinečné heslá kliknutím na", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "aby ste mohli ochrániť prihlasovacie údaje.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Jednoducho vytvorte silné a jedinečné heslá kliknutím na tlačidlo Generovať heslo, aby ste zabezpečili prihlasovacie údaje.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "Nemáte oprávnenie na zobrazenie tejto stránky. Skúste sa prihlásiť pomocou iného účtu." } } diff --git a/apps/browser/src/_locales/sl/messages.json b/apps/browser/src/_locales/sl/messages.json index c7585878d8a..703563523ac 100644 --- a/apps/browser/src/_locales/sl/messages.json +++ b/apps/browser/src/_locales/sl/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Autofill suggestions" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Show autofill suggestions on form fields" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Use this password" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Use this username" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Timeout action" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "Zaklepanje", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "Vse pošiljke", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Hide text by default" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ is using SSO with a self-hosted key server. A master password is no longer required to log in for members of this organization.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Leave organization" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Device trusted" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "No active Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Use Send to securely share encrypted information with anyone.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Input is required." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Are you sure you want to permanently delete this attachment?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Authenticating" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Important notice" - }, - "setupTwoStepLogin": { - "message": "Set up two-step login" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Remind me later" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" - }, - "turnOnTwoStepLogin": { - "message": "Turn on two-step login" - }, - "changeAcctEmail": { - "message": "Change account email" - }, "extensionWidth": { "message": "Extension width" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/sr/messages.json b/apps/browser/src/_locales/sr/messages.json index a5b18b0da21..59d72b93173 100644 --- a/apps/browser/src/_locales/sr/messages.json +++ b/apps/browser/src/_locales/sr/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "Нова ставка, отвара се у новом прозору", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Уреди пре сачувавања", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ сачувано и Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "сачувано у Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ ажурирано у Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "ажурирано у Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Одабрати $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Сачувати као нову пријаву", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Ажурирати пријаву", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Откључајте да бисте сачували ову пријаву", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Сачувати пријаву", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Предлог за ауто-попуњавања" }, + "autofillSpotlightTitle": { + "message": "Једноставно пронађите предлоге за ауто-пуњење" + }, + "autofillSpotlightDesc": { + "message": "Искључите подешавања ауто-пуњења прегледача, тако да се не сукобљавај са Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Прикажи предлоге за ауто-попуњавање у пољима обрасца" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Употреби ову лозинку" }, + "useThisPassphrase": { + "message": "Употреби ову приступну фразу" + }, "useThisUsername": { "message": "Употреби ово корисничко име" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Акција тајмаута" }, - "newCustomizationOptionsCalloutTitle": { - "message": "Нове опције прилагођавања" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Прилагодите своје искуство сефа помоћу брзих акција копирања, компактног режима и још много тога!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "Погледајте сва подешавања изглед" - }, "lock": { "message": "Закључај", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "Све „Send“", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Достигнут максималан број приступа", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Сакриј текст подразумевано" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Није пронађен ниједан јединствени идентификатор." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ користи SSO уз сопствени сервер за кључеве. Главна лозинка за пријаву више није неопходна за чланове ове организације.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "Главна лозинка више није потребна за чланове следеће организације. Молимо потврдите домен са администратором организације." + }, + "organizationName": { + "message": "Назив организације" + }, + "keyConnectorDomain": { + "message": "Домен конектора кључа" }, "leaveOrganization": { "message": "Напусти организацију" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Уређај поуздан" }, + "trustOrganization": { + "message": "Повери организацију" + }, + "trust": { + "message": "Повери" + }, + "doNotTrust": { + "message": "Не повери" + }, + "organizationNotTrusted": { + "message": "Организација није поверљива" + }, + "emergencyAccessTrustWarning": { + "message": "За сигурност вашег налога, потврдите само ако сте добили хитни приступ овом кориснику и њиховим отискама одговарају оно што се приказује на њиховом налогу" + }, + "orgTrustWarning": { + "message": "За сигурност вашег рачуна, наставите само ако сте члан ове организације, омогућили опоравак рачуна и отисак који се приказује испод одговара прстима организације." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Повери кориснику" + }, "sendsNoItemsTitle": { "message": "Нема активних Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Употребите Send да безбедно делите шифроване информације са било ким.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Шаљите безбедно осетљиве информације", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Делите датотеке и податке безбедно са било ким, на било којој платформи. Ваше информације ће остати шифроване од почетка-до-краја уз ограничење изложености.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Унос је потребан." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Преузети Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Преузети Bitwarden на све уређаје" + }, + "getTheMobileApp": { + "message": "Узети мобилну апликацију" + }, + "getTheMobileAppDesc": { + "message": "Приступите лозинци у покрету са Bitwarden мобилном апликацијом." + }, + "getTheDesktopApp": { + "message": "Узети desktop апликацију" + }, + "getTheDesktopAppDesc": { + "message": "Приступите свом сефу без прегледача, а затим поставите откључавање са биометристима да бисте убрзали откључавање и у програму и у додатку." + }, + "downloadFromBitwardenNow": { + "message": "Преузети сада са bitwarden.com" + }, + "getItOnGooglePlay": { + "message": "Набавите на Google Play" + }, + "downloadOnTheAppStore": { + "message": "Преузмите са App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Да ли сте сигурни да желите да трајно избришете овај прилог?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Биометријско откључавање није доступно из непознатог разлога." }, + "unlockVault": { + "message": "Откључајте сеф у секунди" + }, + "unlockVaultDesc": { + "message": "Можете да прилагодите своје поставке за откључавање и истек времена да бисте брзо приступили сефу." + }, + "unlockPinSet": { + "message": "Постављен ПИН деблокирања" + }, "authenticating": { "message": "Аутентификација" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Бета" }, - "importantNotice": { - "message": "Важно обавештење" - }, - "setupTwoStepLogin": { - "message": "Поставити дво-степенску пријаву" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden ће послати кôд на имејл вашег налога за верификовање пријављивања са нових уређаја почевши од фебруара 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "Можете да подесите пријаву у два корака као алтернативни начин да заштитите свој налог или да промените свој имејл у један који можете да приступите." - }, - "remindMeLater": { - "message": "Подсети ме касније" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Да ли имате поуздан приступ својим имејлом, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "Не, ненам" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Да, могу поуздано да приступим овим имејлом" - }, - "turnOnTwoStepLogin": { - "message": "Упалити дво-степенску пријаву" - }, - "changeAcctEmail": { - "message": "Променити имејл налога" - }, "extensionWidth": { "message": "Ширина додатка" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Сачувајте неограничене лозинке на неограниченим уређајима помоћу Bitwarden мобилних апликација, претраживача и десктоп апликација." }, + "nudgeBadgeAria": { + "message": "1 нотификација" + }, "emptyVaultNudgeTitle": { "message": "Увоз постојеће лозинке" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Добродошли у ваш сеф!" }, - "hasItemsVaultNudgeBody": { - "message": "Ауто-пуњење предмета за тренутну страницу\nОмиљени предмети за лак приступ\nПретражите сеф за нешто друго" + "hasItemsVaultNudgeBodyOne": { + "message": "Ауто-пуњење предмета за тренутну страницу" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Предмети као омиљен за лак приступ" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Претражите сеф за нешто друго" }, "newLoginNudgeTitle": { "message": "Уштедите време са ауто-пуњењем" }, - "newLoginNudgeBody": { - "message": "Укључите веб страницу тако да се ова пријава појављује као предлог за ауто-пуњење." + "newLoginNudgeBodyOne": { + "message": "Укључите", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Веб сајт", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "тако да се ова пријава појављује као предлог за ауто-пуњење.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Лак SSH приступ" }, - "newSshNudgeBody": { - "message": "Чувајте кључеве и повежите се са SSH агент за брзу, шифровану аутентификацију." + "newSshNudgeBodyOne": { + "message": "Чувајте кључеве и повежите се са SSH агент за брзу, шифровану аутентификацију.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Сазнајте више о SSH агенту", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Брзо креирајте лозинке" + }, + "generatorNudgeBodyOne": { + "message": "Лако креирајте снажне и јединствене лозинке кликом на", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "да вам помогне да задржите своје пријаве сигурно.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Лако креирајте снажне и јединствене лозинке кликом на дугме „Генерирате лозинку“ да вам помогне да чувате своје пријаве на сигурно.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "Немате дозволе за преглед ове странице. Покушајте да се пријавите са другим налогом." } } diff --git a/apps/browser/src/_locales/sv/messages.json b/apps/browser/src/_locales/sv/messages.json index 27443c64140..1fcd208136e 100644 --- a/apps/browser/src/_locales/sv/messages.json +++ b/apps/browser/src/_locales/sv/messages.json @@ -246,7 +246,7 @@ "message": "Logga in i ditt valv" }, "autoFillInfo": { - "message": "Det finns inga inloggningar tillgängliga för automatisk ifyllnad på den nuvarande fliken." + "message": "Det finns inga inloggningar tillgängliga för autofyll på den nuvarande fliken." }, "addLogin": { "message": "Lägg till en inloggning" @@ -383,7 +383,7 @@ "message": "Redigera mapp" }, "editFolderWithName": { - "message": "Edit folder: $FOLDERNAME$", + "message": "Redigera mapp: $FOLDERNAME$", "placeholders": { "foldername": { "content": "$1", @@ -575,13 +575,13 @@ "message": "Favorit" }, "unfavorite": { - "message": "Unfavorite" + "message": "Ta bort favorit" }, "itemAddedToFavorites": { - "message": "Item added to favorites" + "message": "Objekt tillagt i favoriter" }, "itemRemovedFromFavorites": { - "message": "Item removed from favorites" + "message": "Objekt borttaget från favoriter" }, "notes": { "message": "Anteckningar" @@ -608,10 +608,10 @@ "message": "Öppna" }, "launchWebsite": { - "message": "Launch website" + "message": "Öppna webbplats" }, "launchWebsiteName": { - "message": "Launch website $ITEMNAME$", + "message": "Öppna webbplats $ITEMNAME$", "placeholders": { "itemname": { "content": "$1", @@ -641,10 +641,10 @@ "message": "Ställ in en upplåsningsmetod i Inställningar" }, "sessionTimeoutHeader": { - "message": "Session timeout" + "message": "Timeout för session" }, "vaultTimeoutHeader": { - "message": "Vault timeout" + "message": "Timeout för valv" }, "otherOptions": { "message": "Andra alternativ" @@ -656,13 +656,13 @@ "message": "Din webbläsare har inte stöd för att enkelt kopiera till urklipp. Kopiera till urklipp manuellt istället." }, "verifyYourIdentity": { - "message": "Verify your identity" + "message": "Verifiera din identitet" }, "weDontRecognizeThisDevice": { "message": "We don't recognize this device. Enter the code sent to your email to verify your identity." }, "continueLoggingIn": { - "message": "Continue logging in" + "message": "Fortsätt logga in" }, "yourVaultIsLocked": { "message": "Ditt valv är låst. Verifiera din identitet för att fortsätta." @@ -842,7 +842,7 @@ "message": "Scan authenticator QR code from current webpage" }, "totpHelperTitle": { - "message": "Make 2-step verification seamless" + "message": "Gör tvåstegsverifiering sömlös" }, "totpHelper": { "message": "Bitwarden can store and fill 2-step verification codes. Copy and paste the key into this field." @@ -872,13 +872,13 @@ "message": "Logga in på Bitwarden" }, "enterTheCodeSentToYourEmail": { - "message": "Enter the code sent to your email" + "message": "Ange koden som skickats till din e-post" }, "enterTheCodeFromYourAuthenticatorApp": { - "message": "Enter the code from your authenticator app" + "message": "Ange koden från din autentiseringsapp" }, "pressYourYubiKeyToAuthenticate": { - "message": "Press your YubiKey to authenticate" + "message": "Tryck på din YubiKey för att autentisera" }, "duoTwoFactorRequiredPageSubtitle": { "message": "Duo two-step login is required for your account. Follow the steps below to finish logging in." @@ -890,16 +890,16 @@ "message": "Follow the steps below to finish logging in with your security key." }, "restartRegistration": { - "message": "Restart registration" + "message": "Starta om registrering" }, "expiredLink": { - "message": "Expired link" + "message": "Utgången länk" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Starta om registreringen eller försök logga in." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Du kanske redan har ett konto" }, "logOutConfirmation": { "message": "Är du säker på att du vill logga ut?" @@ -911,7 +911,7 @@ "message": "Nej" }, "location": { - "message": "Location" + "message": "Plats" }, "unexpectedError": { "message": "Ett okänt fel har inträffat." @@ -926,10 +926,10 @@ "message": "Tvåstegsverifiering gör ditt konto säkrare genom att kräva att du verifierar din inloggning med en annan enhet, t.ex. en säkerhetsnyckel, autentiseringsapp, SMS, telefonsamtal eller e-post. Tvåstegsverifiering kan aktiveras i Bitwardens webbvalv. Vill du besöka webbplatsen nu?" }, "twoStepLoginConfirmationContent": { - "message": "Make your account more secure by setting up two-step login in the Bitwarden web app." + "message": "Gör ditt konto säkrare genom att konfigurera tvåstegsverifiering i Bitwardens webbapp." }, "twoStepLoginConfirmationTitle": { - "message": "Continue to web app?" + "message": "Fortsätt till webbapp?" }, "editedFolder": { "message": "Mapp sparad" @@ -1031,7 +1031,7 @@ "message": "Visa kort på fliksida" }, "showCardsCurrentTabDesc": { - "message": "Lista kortobjekt på fliksidan för enkel automatisk fyllning." + "message": "Lista kortobjekt på fliksidan för enkel autofyll." }, "showIdentitiesInVaultViewV2": { "message": "Always show identities as Autofill suggestions on Vault view" @@ -1040,7 +1040,7 @@ "message": "Visa identiteter på fliksidan" }, "showIdentitiesCurrentTabDesc": { - "message": "Lista identitetsobjekt på fliksidan för enkel automatisk fyllning." + "message": "Lista identitetsobjekt på fliksidan för enkel autofyll." }, "clickToAutofillOnVault": { "message": "Click items to autofill on Vault view" @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,8 +1120,12 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { - "message": "Save login", + "message": "Spara inloggning", "description": "Prompt asking the user if they want to save their login details." }, "updateLogin": { @@ -1123,11 +1133,11 @@ "description": "Prompt asking the user if they want to update an existing login entry." }, "loginSaveSuccess": { - "message": "Login saved", + "message": "Inloggning sparad", "description": "Message displayed when login details are successfully saved." }, "loginUpdateSuccess": { - "message": "Login updated", + "message": "Inloggning uppdaterad", "description": "Message displayed when login details are successfully updated." }, "loginUpdateTaskSuccess": { @@ -1185,7 +1195,7 @@ "message": "Uppdatera" }, "notificationUnlockDesc": { - "message": "Lås upp ditt Bitwarden-valv för att slutföra begäran om automatisk ifyllnad." + "message": "Lås upp ditt Bitwarden-valv för att slutföra begäran om autofyll." }, "notificationUnlock": { "message": "Lås upp" @@ -1207,7 +1217,7 @@ "description": "Default URI match detection for autofill." }, "defaultUriMatchDetectionDesc": { - "message": "Välj standardalternativet för hur matchning av URI är hanterat för inloggningar när du utför operationer såsom automatisk ifyllnad." + "message": "Välj standardalternativet för hur matchning av URI är hanterat för inloggningar när du utför operationer såsom autofyll." }, "theme": { "message": "Tema" @@ -1264,7 +1274,7 @@ "description": "WARNING (should stay in capitalized letters if the language permits)" }, "warningCapitalized": { - "message": "Warning", + "message": "Varning", "description": "Warning (should maintain locale-relevant capitalization)" }, "confirmVaultExport": { @@ -1464,29 +1474,29 @@ } }, "dontAskAgainOnThisDeviceFor30Days": { - "message": "Don't ask again on this device for 30 days" + "message": "Fråga inte igen på den här enheten i 30 dagar" }, "selectAnotherMethod": { - "message": "Select another method", + "message": "Välj en annan metod", "description": "Select another two-step login method" }, "useYourRecoveryCode": { - "message": "Use your recovery code" + "message": "Använd din återställningskod" }, "insertU2f": { "message": "Sätt i din säkerhetsnyckel i en av datorns USB-portar. Om nyckeln har en knapp, sätt fingret på den." }, "openInNewTab": { - "message": "Open in new tab" + "message": "Öppna i ny flik" }, "webAuthnAuthenticate": { "message": "Autentisera WebAuthn" }, "readSecurityKey": { - "message": "Read security key" + "message": "Läs säkerhetsnyckel" }, "awaitingSecurityKeyInteraction": { - "message": "Awaiting security key interaction..." + "message": "Väntar på interaktion med säkerhetsnyckel..." }, "loginUnavailable": { "message": "Inloggning ej tillgänglig" @@ -1501,7 +1511,7 @@ "message": "Alternativ för tvåstegsverifiering" }, "selectTwoStepLoginMethod": { - "message": "Select two-step login method" + "message": "Välj metod för tvåstegsverifiering" }, "recoveryCodeDesc": { "message": "Förlorat åtkomst till alla dina metoder för tvåstegsverifiering? Använd din återställningskod för att inaktivera tvåstegsverifiering på ditt konto." @@ -1513,7 +1523,7 @@ "message": "Autentiseringsapp" }, "authenticatorAppDescV2": { - "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "message": "Ange en kod som genererats av en autentiseringsapp som Bitwarden Authenticator.", "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, "yubiKeyTitleV2": { @@ -1546,13 +1556,13 @@ "message": "Egen-hostad miljö" }, "selfHostedBaseUrlHint": { - "message": "Specify the base URL of your on-premises hosted Bitwarden installation. Example: https://bitwarden.company.com" + "message": "Ange bas-URL:en för din självhostade Bitwarden-installation. Exempel: https://bitwarden.company.com" }, "selfHostedCustomEnvHeader": { - "message": "For advanced configuration, you can specify the base URL of each service independently." + "message": "För avancerad konfiguration kan du ange bas-URL för varje tjänst separat." }, "selfHostedEnvFormInvalid": { - "message": "You must add either the base Server URL or at least one custom environment." + "message": "Du måste lägga till antingen serverns bas-URL eller minst en anpassad miljö." }, "customEnvironment": { "message": "Anpassad miljö" @@ -1561,7 +1571,7 @@ "message": "Server-URL" }, "selfHostBaseUrl": { - "message": "Self-host server URL", + "message": "Självhostad server-URL", "description": "Label for field requesting a self-hosted integration service URL" }, "apiUrl": { @@ -1583,12 +1593,30 @@ "message": "Miljö-URL:erna har sparats" }, "showAutoFillMenuOnFormFields": { - "message": "Visa menyn för automatisk ifyllnad på formulärfält", + "message": "Visa menyn för autofyll på formulärfält", "description": "Represents the message for allowing the user to enable the autofill overlay" }, "autofillSuggestionsSectionTitle": { "message": "Förslag för autofyll" }, + "autofillSpotlightTitle": { + "message": "Hitta förslag på autofyll enkelt" + }, + "autofillSpotlightDesc": { + "message": "Stäng av webbläsarens autofyllinställningar så att de inte orsakar konflikt med Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Stäng av $BROWSER$ autofyll", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Stäng av autofyll" + }, "showInlineMenuLabel": { "message": "Visa förslag för autofyll i formulärfält" }, @@ -1599,13 +1627,13 @@ "message": "Visa kort som förslag" }, "showInlineMenuOnIconSelectionLabel": { - "message": "Display suggestions when icon is selected" + "message": "Visa förslag när ikonen markerats" }, "showInlineMenuOnFormFieldsDescAlt": { - "message": "Applies to all logged in accounts." + "message": "Gäller för alla inloggade konton." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser's built in password manager settings to avoid conflicts." + "message": "Stäng av webbläsarens inbyggda lösenordshanterarinställningar för att undvika konflikter." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Redigera webbläsarinställningar." @@ -1615,11 +1643,11 @@ "description": "Overlay setting select option for disabling autofill overlay" }, "autofillOverlayVisibilityOnFieldFocus": { - "message": "When field is selected (on focus)", + "message": "När fältet är markerat (i fokus)", "description": "Overlay appearance select option for showing the field on focus of the input element" }, "autofillOverlayVisibilityOnButtonClick": { - "message": "När ikonen för automatisk ifyllnad är vald", + "message": "När ikonen för autofyll är vald", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, "enableAutoFillOnPageLoadSectionTitle": { @@ -1665,13 +1693,13 @@ "message": "Öppna valvet i sidofältet" }, "commandAutofillLoginDesc": { - "message": "Autofill the last used login for the current website" + "message": "Autofyll den senast använda inloggningen för den aktuella webbplatsen" }, "commandAutofillCardDesc": { - "message": "Autofill the last used card for the current website" + "message": "Autofyll det senast använda kortet för den aktuella webbplatsen" }, "commandAutofillIdentityDesc": { - "message": "Autofill the last used identity for the current website" + "message": "Autofyll den senast använda identiteten för den aktuella webbplatsen" }, "commandGeneratePasswordDesc": { "message": "Skapa och kopiera ett nytt slumpmässigt lösenord till urklipp." @@ -1695,7 +1723,7 @@ "message": "Dra för att sortera" }, "dragToReorder": { - "message": "Drag to reorder" + "message": "Dra för att ändra ordning" }, "cfTypeText": { "message": "Text" @@ -1730,7 +1758,7 @@ "message": "Visa en identifierbar bild bredvid varje inloggning." }, "faviconDescAlt": { - "message": "Show a recognizable image next to each login. Applies to all logged in accounts." + "message": "Visa en igenkännbar bild bredvid varje inloggning. Gäller för alla inloggade konton." }, "enableBadgeCounter": { "message": "Visa aktivitetsräknaren" @@ -1931,7 +1959,7 @@ "message": "Rensa generatorhistorik" }, "cleargGeneratorHistoryDescription": { - "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + "message": "Om du fortsätter kommer alla poster att raderas permanent från generatorns historik. Är du säker på att du vill fortsätta?" }, "back": { "message": "Tillbaka" @@ -1970,7 +1998,7 @@ "message": "Säkra anteckningar" }, "sshKeys": { - "message": "SSH Keys" + "message": "SSH-nycklar" }, "clear": { "message": "Rensa", @@ -2053,10 +2081,10 @@ "message": "Rensa historik" }, "nothingToShow": { - "message": "Nothing to show" + "message": "Inget tillgängligt innehåll" }, "nothingGeneratedRecently": { - "message": "You haven't generated anything recently" + "message": "Du har inte genererat något nyligen" }, "remove": { "message": "Ta bort" @@ -2126,7 +2154,7 @@ "message": "Ange en PIN-kod för att låsa upp Bitwarden. Dina PIN-inställningar återställs om du någonsin loggar ut helt från programmet." }, "setYourPinCode1": { - "message": "Your PIN will be used to unlock Bitwarden instead of your master password. Your PIN will reset if you ever fully log out of Bitwarden." + "message": "Din PIN-kod kommer att användas för att låsa upp Bitwarden istället för ditt huvudlösenord. Din PIN-kod kommer att återställas om du någonsin helt loggar ut från Bitwarden." }, "pinRequired": { "message": "PIN-kod krävs." @@ -2153,7 +2181,7 @@ "message": "Lås med huvudlösenordet vid omstart av webbläsaren" }, "lockWithMasterPassOnRestart1": { - "message": "Require master password on browser restart" + "message": "Kräv huvudlösenord vid omstart av webbläsaren" }, "selectOneCollection": { "message": "Du måste markera minst en samling." @@ -2168,45 +2196,39 @@ "message": "Lösenordsgenerator" }, "usernameGenerator": { - "message": "Username generator" + "message": "Användarnamnsgenerator" }, "useThisEmail": { - "message": "Use this email" + "message": "Använd denna e-post" }, "useThisPassword": { - "message": "Use this password" + "message": "Använd detta lösenord" + }, + "useThisPassphrase": { + "message": "Use this passphrase" }, "useThisUsername": { - "message": "Use this username" + "message": "Använd detta användarnamn" }, "securePasswordGenerated": { - "message": "Secure password generated! Don't forget to also update your password on the website." + "message": "Säkert lösenord genererat! Glöm inte att även uppdatera ditt lösenord på webbplatsen." }, "useGeneratorHelpTextPartOne": { - "message": "Use the generator", + "message": "Använd generatorn", "description": "This will be used as part of a larger sentence, broken up to include the generator icon. The full sentence will read 'Use the generator [GENERATOR_ICON] to create a strong unique password'" }, "useGeneratorHelpTextPartTwo": { - "message": "to create a strong unique password", + "message": "för att skapa ett starkt unikt lösenord", "description": "This will be used as part of a larger sentence, broken up to include the generator icon. The full sentence will read 'Use the generator [GENERATOR_ICON] to create a strong unique password'" }, "vaultCustomization": { - "message": "Vault customization" + "message": "Anpassning av valv" }, "vaultTimeoutAction": { "message": "Åtgärd när valvets tidsgräns överskrids" }, "vaultTimeoutAction1": { - "message": "Timeout action" - }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" + "message": "Åtgärd vid timeout" }, "lock": { "message": "Lås", @@ -2328,16 +2350,16 @@ "message": "Ditt nya huvudlösenord uppfyller inte kraven i policyn." }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "Få råd, nyheter och forskningsmöjligheter från Bitwarden i din inkorg." }, "unsubscribe": { - "message": "Unsubscribe" + "message": "Avprenumerera" }, "atAnyTime": { "message": "när som helst." }, "byContinuingYouAgreeToThe": { - "message": "By continuing, you agree to the" + "message": "Genom att fortsätta godkänner du" }, "and": { "message": "och" @@ -2655,6 +2677,10 @@ "message": "Alla Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Hide text by default" }, @@ -2852,7 +2878,7 @@ "message": "E-postverifiering krävs" }, "emailVerifiedV2": { - "message": "Email verified" + "message": "E-post verifierad" }, "emailVerificationRequiredDesc": { "message": "Du måste verifiera din e-postadress för att använda den här funktionen. Du kan verifiera din e-postadress i webbvalvet." @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Ingen unik identifierare hittades." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ använder SSO med en egen nyckelserver. Ett huvudlösenord krävs inte längre för att logga in för medlemmar i denna organisation.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organisationsnamn" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Lämna organisation" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Enhet betrodd" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "Inga aktiva Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Use Send to securely share encrypted information with anyone.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Inmatning är obligatoriskt." }, @@ -3726,7 +3784,7 @@ "description": "Text to display in overlay when the account is locked." }, "unlockYourAccountToViewAutofillSuggestions": { - "message": "Unlock your account to view autofill suggestions", + "message": "Lås upp ditt konto för att visa förslag för autofyll", "description": "Text to display in overlay when the account is locked." }, "unlockAccount": { @@ -4187,7 +4245,7 @@ "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", + "message": "Att ignorera det här alternativet kan orsaka konflikter mellan Bitwardens autofyllförslag och webbläsarens.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -4236,13 +4294,13 @@ "message": "Passkey borttagen" }, "autofillSuggestions": { - "message": "Autofill suggestions" + "message": "Förslag för autofyll" }, "itemSuggestions": { "message": "Suggested items" }, "autofillSuggestionsTip": { - "message": "Save a login item for this site to autofill" + "message": "Spara ett inloggningsobjekt för den här webbplatsen för autofyll" }, "yourVaultIsEmpty": { "message": "Ditt valv är tomt" @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Are you sure you want to permanently delete this attachment?" }, @@ -4848,7 +4933,7 @@ "message": "Kontoåtgärder" }, "showNumberOfAutofillSuggestions": { - "message": "Show number of login autofill suggestions on extension icon" + "message": "Visa antal autofyllförslag för inloggning på tilläggsikonen" }, "showQuickCopyActions": { "message": "Show quick copy actions on Vault" @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Authenticating" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Important notice" - }, - "setupTwoStepLogin": { - "message": "Set up two-step login" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Remind me later" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" - }, - "turnOnTwoStepLogin": { - "message": "Turn on two-step login" - }, - "changeAcctEmail": { - "message": "Change account email" - }, "extensionWidth": { "message": "Extension width" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "så att den här inloggningen visas som ett förslag för autofyll.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/te/messages.json b/apps/browser/src/_locales/te/messages.json index 99a09c75d41..29223942fd6 100644 --- a/apps/browser/src/_locales/te/messages.json +++ b/apps/browser/src/_locales/te/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Autofill suggestions" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Show autofill suggestions on form fields" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Use this password" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Use this username" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Timeout action" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "Lock", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "All Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Hide text by default" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ is using SSO with a self-hosted key server. A master password is no longer required to log in for members of this organization.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Leave organization" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Device trusted" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "No active Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Use Send to securely share encrypted information with anyone.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Input is required." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Are you sure you want to permanently delete this attachment?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Authenticating" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Important notice" - }, - "setupTwoStepLogin": { - "message": "Set up two-step login" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Remind me later" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" - }, - "turnOnTwoStepLogin": { - "message": "Turn on two-step login" - }, - "changeAcctEmail": { - "message": "Change account email" - }, "extensionWidth": { "message": "Extension width" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/th/messages.json b/apps/browser/src/_locales/th/messages.json index f6c8a9f0584..87e5be28d79 100644 --- a/apps/browser/src/_locales/th/messages.json +++ b/apps/browser/src/_locales/th/messages.json @@ -3,7 +3,7 @@ "message": "bitwarden" }, "appLogoLabel": { - "message": "Bitwarden logo" + "message": "โลโก้ Bitwarden" }, "extName": { "message": "Bitwarden Password Manager", @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Autofill suggestions" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Show autofill suggestions on form fields" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Use this password" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Use this username" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Timeout action" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "ล็อก", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "Send ทั้งหมด", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Hide text by default" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "No unique identifier found." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ is using SSO with a self-hosted key server. A master password is no longer required to log in for members of this organization.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Leave organization" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Device trusted" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "No active Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Use Send to securely share encrypted information with anyone.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Input is required." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Are you sure you want to permanently delete this attachment?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Authenticating" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Important notice" - }, - "setupTwoStepLogin": { - "message": "Set up two-step login" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Remind me later" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" - }, - "turnOnTwoStepLogin": { - "message": "Turn on two-step login" - }, - "changeAcctEmail": { - "message": "Change account email" - }, "extensionWidth": { "message": "Extension width" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/tr/messages.json b/apps/browser/src/_locales/tr/messages.json index 052941f2281..a72e3593ff9 100644 --- a/apps/browser/src/_locales/tr/messages.json +++ b/apps/browser/src/_locales/tr/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "Yeni kayıt (yeni pencerede açılır)", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Kaydetmeden önce düzenle", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ Bitwarden'a kaydedildi.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "Bitwarden’a kaydedildi.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ Bitwarden'da güncellendi.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "Bitwarden’da güncellendi.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Seç: $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Yeni hesap olarak kaydet", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Hesabı güncelle", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Bu hesabı kaydetmek için kilidi açın", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Hesabı kaydet", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Otomatik doldurma önerileri" }, + "autofillSpotlightTitle": { + "message": "Otomatik doldurma önerilerini kolayca bulun" + }, + "autofillSpotlightDesc": { + "message": "Bitwarden ile çakışmaması için tarayıcınızın otomatik doldurma ayarını kapatın." + }, + "turnOffBrowserAutofill": { + "message": "$BROWSER$ ile otomatik doldurmayı kapat", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Otomatik doldurmayı kapat" + }, "showInlineMenuLabel": { "message": "Form alanlarında otomatik doldurma önerilerini göster" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Bu parolayı kullan" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Bu kullanıcı adını kullan" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Zaman aşımı eylemi" }, - "newCustomizationOptionsCalloutTitle": { - "message": "Yeni özelleştirme seçenekleri" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "Görünüm ayarlarının hepsini göster" - }, "lock": { "message": "Kilitle", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "Tüm Send'ler", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Maksimum erişim sayısına ulaşıldı", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Metni varsayılan olarak gizle" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Benzersiz tanımlayıcı bulunamadı." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ kendi barındırdığı bir anahtar sunucusuyla SSO kullanıyor. Bu kuruluşun üyelerinin artık ana parola kullanması gerekmiyor.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Kuruluş adı" + }, + "keyConnectorDomain": { + "message": "Key Connector alan adı" }, "leaveOrganization": { "message": "Kuruluştan ayrıl" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Cihaza güvenildi" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Güvenme" + }, + "organizationNotTrusted": { + "message": "Kuruluş güvenilir değil" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "Aktif Send yok", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Şifrelenmiş bilgileri güvenle paylaşmak için Send'i kullanabilirsiniz.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Hassas bilgileri güvenle paylaşın", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Girdi gerekli." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Bitwarden’ı indirin" + }, + "downloadBitwardenOnAllDevices": { + "message": "Bitwarden’ı tüm cihazlarınıza indirin" + }, + "getTheMobileApp": { + "message": "Mobil uygulamayı indirin" + }, + "getTheMobileAppDesc": { + "message": "Parolalarınıza Bitwarden mobil uygulaması sayesinde her yerden ulaşın." + }, + "getTheDesktopApp": { + "message": "Masaüstü uygulamasını indirin" + }, + "getTheDesktopAppDesc": { + "message": "Kasanıza tarayıcıyı kullanmadan erişin, biyometri ile kilit açmayı etkinleştirerek hem masaüstü uygulamasından hem de tarayıcı uzantısından kilit açmayı geliştirin." + }, + "downloadFromBitwardenNow": { + "message": "Şimdi bitwarden.com’dan indirin" + }, + "getItOnGooglePlay": { + "message": "Google Play'den edinin" + }, + "downloadOnTheAppStore": { + "message": "App Store'dan indirin" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Bu dosyayı kalıcı olarak silmek istediğinizden emin misiniz?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Kasanızın kilidini saniyeler içinde açın" + }, + "unlockVaultDesc": { + "message": "Kasanıza daha hızlı ulaşmak için kilit açma ve zaman aşımı ayarlarınızı özelleştirebilirsiniz." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Kimlik doğrulanıyor" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Önemli uyarı" - }, - "setupTwoStepLogin": { - "message": "İki adımlı girişi ayarla" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Şubat 2025 itibarıyla Bitwarden, yeni cihazlardan yeni girişleri doğrulamanız için e-posta adresinize bir kod gönderecektir." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "Hesabınızı korumanın alternatif bir yolu olarak iki adımlı girişi etkinleştirebilirsiniz. Aksi halde e-posta adresinizin doğru olduğundan emin olmalısınız." - }, - "remindMeLater": { - "message": "Daha sonra hatırlat" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "$EMAIL$ adresinize sağlıklı bir şekilde erişebiliyor musunuz?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "Hayır, erişemiyorum" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Evet, e-postalarıma sağlıklı bir şekilde erişebiliyorum" - }, - "turnOnTwoStepLogin": { - "message": "İki adımlı girişi etkinleştir" - }, - "changeAcctEmail": { - "message": "Hesap e-postasını değiştir" - }, "extensionWidth": { "message": "Uzantı genişliği" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Bitwarden mobil, tarayıcı ve masaüstü uygulamalarıyla istediğiniz kadar cihaza istediğiniz kadar parola kaydedebilirsiniz." }, + "nudgeBadgeAria": { + "message": "1 bildirim" + }, "emptyVaultNudgeTitle": { "message": "Mevcut parolaları içe aktar" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Kasanıza hoş geldiniz!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Otomatik doldurmayla zaman kazanın" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Bu hesabın otomatik doldurma önerisi olarak görünmesi için bir", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "web sitesi", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "ekleyin.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Kesintisiz çevrimiçi alışveriş" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "Bu sayfayı görüntüleme izniniz yok. Farklı bir hesapla giriş yapmayı deneyin." } } diff --git a/apps/browser/src/_locales/uk/messages.json b/apps/browser/src/_locales/uk/messages.json index 7b62690d03c..01c4fa2d73b 100644 --- a/apps/browser/src/_locales/uk/messages.json +++ b/apps/browser/src/_locales/uk/messages.json @@ -1071,8 +1071,12 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "Новий запис, відкривається у новому вікні", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { - "message": "Edit before saving", + "message": "Редагувати перед збереженням", "description": "Tooltip and Aria label for edit button on cipher item" }, "newNotification": { @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ збережено до Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "збережено до Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ оновлено в Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "оновлено в Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Вибрати $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Зберегти як новий запис", "description": "Button text for saving login details as a new entry." @@ -1114,12 +1120,16 @@ "message": "Оновити запис", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Розблокуйте, щоб зберегти цей запис", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { - "message": "Save login", + "message": "Зберегти запис", "description": "Prompt asking the user if they want to save their login details." }, "updateLogin": { - "message": "Update existing login", + "message": "Оновити наявний запис", "description": "Prompt asking the user if they want to update an existing login entry." }, "loginSaveSuccess": { @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Пропозиції автозаповнення" }, + "autofillSpotlightTitle": { + "message": "Користуйтеся пропозиціями автозаповнення" + }, + "autofillSpotlightDesc": { + "message": "Вимкніть налаштування автозаповнення вашого браузера, щоб вони не конфліктували з Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Вимкнути автозаповнення $BROWSER$", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Вимкніть автозаповнення" + }, "showInlineMenuLabel": { "message": "Пропозиції автозаповнення на полях форм" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Використати цей пароль" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Використати це ім'я користувача" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Дія після часу очікування" }, - "newCustomizationOptionsCalloutTitle": { - "message": "Нові можливості налаштування" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Налаштуйте своє сховище за допомогою швидких дій копіювання, компактного режиму та інших можливостей!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "Всі налаштування подання" - }, "lock": { "message": "Блокувати", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "Усі відправлення", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Типово приховувати текст" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Не знайдено унікальний ідентифікатор." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ використовує SSO з власним сервером ключів. Головний пароль для учасників цієї організації більше не вимагається.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "Головний пароль більше не є обов'язковим для учасників зазначеної організації. Підтвердьте вказаний нижче домен з адміністратором вашої організації." + }, + "organizationName": { + "message": "Назва організації" + }, + "keyConnectorDomain": { + "message": "Домен Key Connector" }, "leaveOrganization": { "message": "Покинути організацію" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Довірений пристрій" }, + "trustOrganization": { + "message": "Довіряти організації" + }, + "trust": { + "message": "Довіряти" + }, + "doNotTrust": { + "message": "Не довіряти" + }, + "organizationNotTrusted": { + "message": "Це не довірена організація" + }, + "emergencyAccessTrustWarning": { + "message": "Щоб захистити свій обліковий запис, підтверджуйте лише якщо ви надали цьому користувачу екстрений доступ, і його цифровий відбиток збігається з показаним в його обліковому записі." + }, + "orgTrustWarning": { + "message": "Щоб захистити свій обліковий запис, продовжуйте лише якщо ви є учасником цієї організації, маєте ввімкнене відновлення облікового запису, і показаний нижче цифровий відбиток збігається з відбитком організації." + }, + "orgTrustWarning1": { + "message": "Ця організація має політику компанії, яка розгорне для вас відновлення облікового запису. Розгортання дасть змогу адміністраторам організації змінювати ваш пароль. Продовжуйте тільки якщо ви впізнаєте організацію і наведена нижче фраза відбитка відповідає відбитку організації." + }, + "trustUser": { + "message": "Довіряти користувачу" + }, "sendsNoItemsTitle": { "message": "Немає активних відправлень", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Використовуйте відправлення, щоб безпечно надавати доступ іншим до зашифрованої інформації.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Безпечно надсилайте конфіденційну інформацію", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Безпечно діліться файлами й даними з ким завгодно, на будь-якій платформі. Ваша інформація наскрізно зашифрована та має обмежений доступ.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Необхідно ввести дані." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Завантажити Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Завантажити Bitwarden на всіх пристроях" + }, + "getTheMobileApp": { + "message": "Отримати програму для мобільного пристрою" + }, + "getTheMobileAppDesc": { + "message": "Користуйтеся своїми паролями звідусіль за допомогою програми Bitwarden для мобільних пристроїв." + }, + "getTheDesktopApp": { + "message": "Отримати програму для комп'ютера" + }, + "getTheDesktopAppDesc": { + "message": "Користуйтеся сховищем без браузера, налаштуйте біометричне розблокування, щоб спростити доступ у програмі на комп'ютері та в розширенні браузера." + }, + "downloadFromBitwardenNow": { + "message": "Завантажити з bitwarden.com" + }, + "getItOnGooglePlay": { + "message": "Завантажити з Google Play" + }, + "downloadOnTheAppStore": { + "message": "Завантажити з App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Ви дійсно хочете остаточно видалити це вкладення?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Біометричне розблокування зараз недоступне з невідомої причини." }, + "unlockVault": { + "message": "Розблоковуйте сховище за секунди" + }, + "unlockVaultDesc": { + "message": "Ви можете налаштувати розблокування і час очікування для швидшого доступу до сховища." + }, + "unlockPinSet": { + "message": "Розблокування PIN-кодом встановлено" + }, "authenticating": { "message": "Аутентифікація" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Бета" }, - "importantNotice": { - "message": "Важлива інформація" - }, - "setupTwoStepLogin": { - "message": "Налаштувати двоетапну перевірку" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden надсилатиме код підтвердження на електронну пошту вашого облікового запису під час входу з нових пристроїв, починаючи з лютого 2025 року." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "Ви можете налаштувати двоетапну перевірку як альтернативний спосіб захисту свого облікового запису, або змінити електронну пошту на таку, до якої ви маєте доступ." - }, - "remindMeLater": { - "message": "Нагадати пізніше" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Ви маєте постійний доступ до своєї електронної пошти $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "Ні, не маю" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Так, я маю постійний доступ до своєї електронної пошти" - }, - "turnOnTwoStepLogin": { - "message": "Увімкнути двоетапну перевірку" - }, - "changeAcctEmail": { - "message": "Змінити адресу е-пошти" - }, "extensionWidth": { "message": "Ширина вікна розширення" }, @@ -5202,10 +5260,10 @@ "message": "Змінити ризикований пароль" }, "settingsVaultOptions": { - "message": "Vault options" + "message": "Параметри сховища" }, "emptyVaultDescription": { - "message": "The vault protects more than just your passwords. Store secure logins, IDs, cards and notes securely here." + "message": "Сховище захищає не лише ваші паролі. Безпечно зберігайте дані для входу, посвідчення, картки й нотатки." }, "introCarouselLabel": { "message": "Вітаємо в Bitwarden" @@ -5234,49 +5292,97 @@ "secureDevicesBody": { "message": "Зберігайте скільки завгодно паролів на необмеженій кількості пристроїв, використовуючи Bitwarden для мобільних пристроїв, браузерів та комп'ютерів." }, + "nudgeBadgeAria": { + "message": "1 сповіщення" + }, "emptyVaultNudgeTitle": { - "message": "Import existing passwords" + "message": "Імпортуйте наявні паролі" }, "emptyVaultNudgeBody": { - "message": "Use the importer to quickly transfer logins to Bitwarden without manually adding them." + "message": "Скористайтеся інструментом імпортування, щоб швидко перенести записи до Bitwarden, а не додавати їх вручну." }, "emptyVaultNudgeButton": { - "message": "Import now" + "message": "Імпортувати" }, "hasItemsVaultNudgeTitle": { - "message": "Welcome to your vault!" + "message": "Вітаємо у вашому сховищі!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Автозаповнення записів для поточної сторінки" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Обрані записи для швидкого доступу" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Пошук інших елементів у сховищі" }, "newLoginNudgeTitle": { - "message": "Save time with autofill" + "message": "Заощаджуйте час з автозаповненням" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Включити", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Вебсайт", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "щоб цей запис з'являвся у пропозиціях автозаповнення.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { - "message": "Seamless online checkout" + "message": "Швидке оформлення замовлень" }, "newCardNudgeBody": { - "message": "With cards, easily autofill payment forms securely and accurately." + "message": "За допомогою записів для карток можна безпечно й точно заповнювати платіжні форми." }, "newIdentityNudgeTitle": { - "message": "Simplify creating accounts" + "message": "Спростіть створення облікових записів" }, "newIdentityNudgeBody": { - "message": "With identities, quickly autofill long registration or contact forms." + "message": "За допомогою записів для посвідчень можна швидко заповнювати форми реєстрації чи контактів." }, "newNoteNudgeTitle": { - "message": "Keep your sensitive data safe" + "message": "Захистіть свої конфіденційні дані" }, "newNoteNudgeBody": { - "message": "With notes, securely store sensitive data like banking or insurance details." + "message": "За допомогою нотаток можна надійно зберігати конфіденційні дані, як-от банківську інформацію або страхування." }, "newSshNudgeTitle": { - "message": "Developer-friendly SSH access" + "message": "SSH-доступ для розробників" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Зберігайте свої ключі та під'єднуйтеся за допомогою SSH-агента для швидкої зашифрованої автентифікації.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Докладніше про SSH-агента", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Швидко створюйте паролі" + }, + "generatorNudgeBodyOne": { + "message": "Легко створюйте надійні та унікальні паролі, натиснувши на", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "щоб зберегти свої записи в безпеці.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Легко створюйте надійні та унікальні паролі, натиснувши кнопку Генерувати пароль, щоб зберегти свої записи в безпеці.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "У вас немає дозволу переглядати цю сторінку. Спробуйте ввійти з іншим обліковим записом." } } diff --git a/apps/browser/src/_locales/vi/messages.json b/apps/browser/src/_locales/vi/messages.json index 280a590033a..fcbcb8f7b6d 100644 --- a/apps/browser/src/_locales/vi/messages.json +++ b/apps/browser/src/_locales/vi/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "Các gợi ý điền tự động" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "Hiển thị các gợi ý tự động điền trên các trường biểu mẫu" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "Use this password" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "Use this username" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "Timeout action" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "Khóa", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "Tất cả mục Gửi", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "Hide text by default" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "Không tìm thấy danh tính duy nhất." }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ đang sử dụng SSO với khóa máy chủ tự lưu trữ. Mật khẩu chính không còn cần để đăng nhập cho các thành viên của tổ chức này.", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "Rời tổ chức" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "Thiết bị tin cậy" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "Không có mục Gửi nào đang hoạt động", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "Sử dụng Gửi để chia sẻ thông tin mã hóa một cách an toàn với bất kỳ ai.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "Trường này là bắt buộc." }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "Bạn có chắc chắn muốn xóa vĩnh viễn tệp đính kèm này không?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "Biometric unlock is currently unavailable for an unknown reason." }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "Authenticating" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta" }, - "importantNotice": { - "message": "Thông báo quan trọng" - }, - "setupTwoStepLogin": { - "message": "Thiết lập đăng nhập hai bước" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." - }, - "remindMeLater": { - "message": "Nhắc sau" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "Không, tôi không có" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Có, tôi có quyền truy cập email này" - }, - "turnOnTwoStepLogin": { - "message": "Turn on two-step login" - }, - "changeAcctEmail": { - "message": "Đổi email tài khoản" - }, "extensionWidth": { "message": "Extension width" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/_locales/zh_CN/messages.json b/apps/browser/src/_locales/zh_CN/messages.json index 521c72a2fb5..e370f7749f6 100644 --- a/apps/browser/src/_locales/zh_CN/messages.json +++ b/apps/browser/src/_locales/zh_CN/messages.json @@ -1071,6 +1071,10 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "新增项目(在新窗口中打开)", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "保存前编辑", "description": "Tooltip and Aria label for edit button on cipher item" @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ 已保存到 Bitwarden。", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "已保存到 Bitwarden。", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ 已在 Bitwarden 中更新。", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "已更新到 Bitwarden。", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "选择 $ITEMTYPE$,$ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "保存为新的登录", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "更新登录", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "解锁以保存此登录", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "保存登录", "description": "Prompt asking the user if they want to save their login details." @@ -1131,7 +1141,7 @@ "description": "Message displayed when login details are successfully updated." }, "loginUpdateTaskSuccess": { - "message": "干得好!您采取了使您和 $ORGANIZATION$ 更加安全的措施。", + "message": "干得好!您采取了使您和 $ORGANIZATION$ 更加安全的步骤。", "placeholders": { "organization": { "content": "$1" @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "自动填充建议" }, + "autofillSpotlightTitle": { + "message": "轻松找到自动填充建议" + }, + "autofillSpotlightDesc": { + "message": "关闭浏览器的自动填充设置,以免与 Bitwarden 产生冲突。" + }, + "turnOffBrowserAutofill": { + "message": "关闭 $BROWSER$ 的自动填充", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "关闭自动填充" + }, "showInlineMenuLabel": { "message": "在表单字段中显示自动填充建议" }, @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "使用此密码" }, + "useThisPassphrase": { + "message": "使用此密码短语" + }, "useThisUsername": { "message": "使用此用户名" }, @@ -2187,7 +2218,7 @@ "description": "This will be used as part of a larger sentence, broken up to include the generator icon. The full sentence will read 'Use the generator [GENERATOR_ICON] to create a strong unique password'" }, "useGeneratorHelpTextPartTwo": { - "message": "创建一个强大且唯一的密码", + "message": "创建强大且唯一的密码", "description": "This will be used as part of a larger sentence, broken up to include the generator icon. The full sentence will read 'Use the generator [GENERATOR_ICON] to create a strong unique password'" }, "vaultCustomization": { @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "超时动作" }, - "newCustomizationOptionsCalloutTitle": { - "message": "新的自定义选项" - }, - "newCustomizationOptionsCalloutContent": { - "message": "自定义您的密码库体验,包括快速复制操作、紧凑模式等!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "查看所有外观设置" - }, "lock": { "message": "锁定", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "所有 Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "已达最大访问次数", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "默认隐藏文本" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "未找到唯一的标识符。" }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ 使用自托管密钥服务器 SSO。这个组织的成员登录时将不再需要主密码。", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "以下组织的成员不再需要主密码。请与您的组织管理员确认下面的域名。" + }, + "organizationName": { + "message": "组织名称" + }, + "keyConnectorDomain": { + "message": "Key Connector 域名" }, "leaveOrganization": { "message": "退出组织" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "设备已信任" }, + "trustOrganization": { + "message": "信任组织" + }, + "trust": { + "message": "信任" + }, + "doNotTrust": { + "message": "不信任" + }, + "organizationNotTrusted": { + "message": "组织未被信任" + }, + "emergencyAccessTrustWarning": { + "message": "为了您的账户安全,确认前请先确认:您已授予该用户紧急访问权限,以及其指纹与其账户中显示的指纹相匹配" + }, + "orgTrustWarning": { + "message": "为了您的账户安全,继续前请先确认:您是启用了账户恢复功能的该组织的成员,以及下方显示的指纹与此组织的指纹相匹配。" + }, + "orgTrustWarning1": { + "message": "此组织有一个企业策略,将为您注册账户恢复。注册后将允许组织管理员更改您的主密码。继续前请先确认:您认识此组织,以及下方显示的指纹短语与此组织的指纹相匹配。" + }, + "trustUser": { + "message": "信任用户" + }, "sendsNoItemsTitle": { "message": "没有活跃的 Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "使用 Send 与任何人安全地分享加密信息。", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "安全地发送敏感信息", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "在任何平台上安全地与任何人共享文件和数据。您的信息将在限制曝光的同时保持端到端加密。", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "必须输入内容。" }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "下载 Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "在所有设备上下载 Bitwarden" + }, + "getTheMobileApp": { + "message": "获取移动 App" + }, + "getTheMobileAppDesc": { + "message": "使用 Bitwarden 移动 App,随时随地访问您的密码。" + }, + "getTheDesktopApp": { + "message": "获取桌面 App" + }, + "getTheDesktopAppDesc": { + "message": "无需使用浏览器访问您的密码库,然后在桌面 App 和浏览器扩展中同时设置生物识别解锁,即可实现快速解锁。" + }, + "downloadFromBitwardenNow": { + "message": "立即从 bitwarden.com 下载" + }, + "getItOnGooglePlay": { + "message": "从 Google Play 获取" + }, + "downloadOnTheAppStore": { + "message": "从 App Store 下载" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "您确定要永久删除此附件吗?" }, @@ -4603,7 +4688,7 @@ "message": "过期的支付卡" }, "cardExpiredMessage": { - "message": "如果您的支付卡已续期,请更新该卡的信息。" + "message": "如果您的支付卡已续期,请更新该卡的信息" }, "cardDetails": { "message": "支付卡详细信息" @@ -4890,7 +4975,7 @@ "message": "自定义超时时间最小为 1 分钟。" }, "additionalContentAvailable": { - "message": "有更多内容可用" + "message": "更多内容可用" }, "fileSavedToDevice": { "message": "文件已保存到设备。可以在设备下载中进行管理。" @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "由于某个未知的原因,生物识别解锁当前不可用。" }, + "unlockVault": { + "message": "数秒内解锁您的密码库" + }, + "unlockVaultDesc": { + "message": "您可以自定义解锁和超时设置,以便更快速地访问您的密码库。" + }, + "unlockPinSet": { + "message": "解锁 PIN 设置" + }, "authenticating": { "message": "正在验证" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "Beta 版" }, - "importantNotice": { - "message": "重要通知" - }, - "setupTwoStepLogin": { - "message": "设置两步登录" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "从 2025 年 02 月起,当有来自新设备的登录时,Bitwarden 将向您的账户电子邮箱发送验证码。" - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "您可以设置两步登录作为保护账户的替代方法,或将您的电子邮箱更改为您可以访问的电子邮箱。" - }, - "remindMeLater": { - "message": "稍后提醒我" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "您可以正常访问您的电子邮箱 $EMAIL$ 吗?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "不,我不能" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "是的,我可以正常访问我的电子邮箱" - }, - "turnOnTwoStepLogin": { - "message": "启用两步登录" - }, - "changeAcctEmail": { - "message": "更改账户电子邮箱" - }, "extensionWidth": { "message": "扩展宽度" }, @@ -5184,7 +5242,7 @@ "message": "SSH 密钥导入成功" }, "cannotRemoveViewOnlyCollections": { - "message": "您无法删除仅具有「查看」权限的集合:$COLLECTIONS$", + "message": "您无法移除仅具有「查看」权限的集合:$COLLECTIONS$", "placeholders": { "collections": { "content": "$1", @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "使用 Bitwarden 移动端、浏览器和桌面 App 在无限制的设备上保存无限数量的密码。" }, + "nudgeBadgeAria": { + "message": "1 个通知" + }, "emptyVaultNudgeTitle": { "message": "导入现有密码" }, @@ -5246,37 +5307,82 @@ "hasItemsVaultNudgeTitle": { "message": "欢迎来到您的密码库!" }, - "hasItemsVaultNudgeBody": { - "message": "自动填充项目用于当前页面\n收藏夹项目用于轻松访问\n搜索密码库用于其他目的" + "hasItemsVaultNudgeBodyOne": { + "message": "为当前页面自动填充项目" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "收藏项目以便轻松访问" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "在密码库中搜索其他内容" }, "newLoginNudgeTitle": { - "message": "Save time with autofill" + "message": "使用自动填充节省时间" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "包含", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "网站", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "以便将此登录显示为自动填充建议。", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { - "message": "Seamless online checkout" + "message": "无缝在线结账" }, "newCardNudgeBody": { - "message": "With cards, easily autofill payment forms securely and accurately." + "message": "使用支付卡,安全准确地轻松自动填充付款表单。" }, "newIdentityNudgeTitle": { - "message": "Simplify creating accounts" + "message": "简化账户的创建" }, "newIdentityNudgeBody": { - "message": "With identities, quickly autofill long registration or contact forms." + "message": "使用身份,快速自动填充冗长的注册或联系表单。" }, "newNoteNudgeTitle": { - "message": "Keep your sensitive data safe" + "message": "保持您的敏感数据的安全" }, "newNoteNudgeBody": { - "message": "With notes, securely store sensitive data like banking or insurance details." + "message": "使用笔记,安全地存储敏感数据,例如银行或保险详细信息。" }, "newSshNudgeTitle": { - "message": "Developer-friendly SSH access" + "message": "开发人员友好的 SSH 访问权限" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "存储您的密钥并与 SSH 代理连接,以进行快速、加密的身份验证。", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "进一步了解 SSH 代理", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "快速创建密码" + }, + "generatorNudgeBodyOne": { + "message": "一键创建强大且唯一的密码", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "帮助您保持登录安全。", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "点击「生成密码」按钮,轻松创建强大且唯一的密码,帮助您保持登录安全。", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "您没有查看此页面的权限。请尝试使用其他账户登录。" } } diff --git a/apps/browser/src/_locales/zh_TW/messages.json b/apps/browser/src/_locales/zh_TW/messages.json index d122f7abab2..ba8b44dc071 100644 --- a/apps/browser/src/_locales/zh_TW/messages.json +++ b/apps/browser/src/_locales/zh_TW/messages.json @@ -189,7 +189,7 @@ "message": "複製備註" }, "copy": { - "message": "Copy", + "message": "複製", "description": "Copy to clipboard" }, "fill": { @@ -541,7 +541,7 @@ "description": "Label for the avoid ambiguous characters checkbox." }, "generatorPolicyInEffect": { - "message": "企業原則之要求已在你的產生器選項中生效", + "message": "企業原則之要求已在您的產生器選項中生效。", "description": "Indicates that a policy limits the credential generator screen." }, "searchVault": { @@ -799,7 +799,7 @@ "message": "您已成功建立新帳號!" }, "youHaveBeenLoggedIn": { - "message": "你已經登入!" + "message": "您已經登入!" }, "youSuccessfullyLoggedIn": { "message": "登入成功" @@ -860,7 +860,7 @@ "message": "已登出" }, "loggedOutDesc": { - "message": "你已經登出了你的帳號。" + "message": "您已經登出了您的帳號。" }, "loginExpired": { "message": "您的登入階段已過期。" @@ -872,7 +872,7 @@ "message": "登入 Bitwarden" }, "enterTheCodeSentToYourEmail": { - "message": "Enter the code sent to your email" + "message": "輸入傳送到您電子郵件信箱的驗證碼" }, "enterTheCodeFromYourAuthenticatorApp": { "message": "Enter the code from your authenticator app" @@ -1071,12 +1071,16 @@ }, "description": "Aria label for the view button in notification bar confirmation message" }, + "notificationNewItemAria": { + "message": "New Item, opens in new window", + "description": "Aria label for the new item button in notification bar confirmation message when error is prompted" + }, "notificationEditTooltip": { "message": "Edit before saving", "description": "Tooltip and Aria label for edit button on cipher item" }, "newNotification": { - "message": "New notification" + "message": "新通知" }, "labelWithNotification": { "message": "$LABEL$: New notification", @@ -1088,24 +1092,26 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, + "selectItemAriaLabel": { + "message": "Select $ITEMTYPE$, $ITEMNAME$", + "description": "Used by screen readers. $1 is the item type (like vault or folder), $2 is the selected item name.", + "placeholders": { + "itemType": { + "content": "$1" + }, + "itemName": { + "content": "$2" + } + } + }, "saveAsNewLoginAction": { "message": "Save as new login", "description": "Button text for saving login details as a new entry." @@ -1114,6 +1120,10 @@ "message": "Update login", "description": "Button text for updating an existing login entry." }, + "unlockToSave": { + "message": "Unlock to save this login", + "description": "User prompt to take action in order to save the login they just entered." + }, "saveLogin": { "message": "Save login", "description": "Prompt asking the user if they want to save their login details." @@ -1477,13 +1487,13 @@ "message": "將您的安全鑰匙插入電腦的 USB 連接埠,然後觸摸其按鈕(如有的話)。" }, "openInNewTab": { - "message": "Open in new tab" + "message": "在新分頁中開啟" }, "webAuthnAuthenticate": { "message": "驗證 WebAuthn" }, "readSecurityKey": { - "message": "Read security key" + "message": "讀取安全金鑰" }, "awaitingSecurityKeyInteraction": { "message": "Awaiting security key interaction..." @@ -1501,7 +1511,7 @@ "message": "兩步驟登入選項" }, "selectTwoStepLoginMethod": { - "message": "Select two-step login method" + "message": "選擇兩步驟登入方法" }, "recoveryCodeDesc": { "message": "無法使用任何雙因素提供程式嗎?請使用您的復原碼以停用您帳戶的所有雙因素提供程式。" @@ -1589,6 +1599,24 @@ "autofillSuggestionsSectionTitle": { "message": "自動填入建議" }, + "autofillSpotlightTitle": { + "message": "Easily find autofill suggestions" + }, + "autofillSpotlightDesc": { + "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden." + }, + "turnOffBrowserAutofill": { + "message": "Turn off $BROWSER$ autofill", + "placeholders": { + "browser": { + "content": "$1", + "example": "Chrome" + } + } + }, + "turnOffAutofill": { + "message": "Turn off autofill" + }, "showInlineMenuLabel": { "message": "在表單欄位上顯示自動填入選單" }, @@ -1605,7 +1633,7 @@ "message": "適用於所有已登入的帳戶。" }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "關閉你的瀏覽器內建密碼管理器設定以避免衝突。" + "message": "關閉您的瀏覽器內建密碼管理器設定以避免衝突。" }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "編輯瀏覽器設定" @@ -1695,7 +1723,7 @@ "message": "透過拖曳來排序" }, "dragToReorder": { - "message": "Drag to reorder" + "message": "拖曳以重新排序" }, "cfTypeText": { "message": "文字型" @@ -2176,6 +2204,9 @@ "useThisPassword": { "message": "使用此密碼" }, + "useThisPassphrase": { + "message": "Use this passphrase" + }, "useThisUsername": { "message": "使用此使用者名稱" }, @@ -2199,15 +2230,6 @@ "vaultTimeoutAction1": { "message": "逾時後動作" }, - "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" - }, - "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" - }, - "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" - }, "lock": { "message": "鎖定", "description": "Verb form: to make secure or inaccessible by" @@ -2655,6 +2677,10 @@ "message": "所有 Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "maxAccessCountReached": { + "message": "Max access count reached", + "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + }, "hideTextByDefault": { "message": "默認隱藏文字" }, @@ -2995,14 +3021,14 @@ "copyCustomFieldNameNotUnique": { "message": "找不到唯一識別碼。" }, - "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ 使用自我裝載金鑰伺服器 SSO。此組織的成員登入時將不再需要主密碼。", - "placeholders": { - "organization": { - "content": "$1", - "example": "My Org Name" - } - } + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator." + }, + "organizationName": { + "message": "Organization name" + }, + "keyConnectorDomain": { + "message": "Key Connector domain" }, "leaveOrganization": { "message": "離開組織" @@ -3564,6 +3590,30 @@ "deviceTrusted": { "message": "裝置已信任" }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "organizationNotTrusted": { + "message": "Organization is not trusted" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "orgTrustWarning1": { + "message": "This organization has an Enterprise policy that will enroll you in account recovery. Enrollment will allow organization administrators to change your password. Only proceed if you recognize this organization and the fingerprint phrase displayed below matches the organization's fingerprint." + }, + "trustUser": { + "message": "Trust user" + }, "sendsNoItemsTitle": { "message": "沒有可用的 Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -3572,6 +3622,14 @@ "message": "使用 Send 可以與任何人安全地共用加密資訊。", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendsTitleNoItems": { + "message": "Send sensitive information safely", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendsBodyNoItems": { + "message": "Share files and data securely with anyone, on any platform. Your information will remain end-to-end encrypted while limiting exposure.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "inputRequired": { "message": "必須輸入內容。" }, @@ -4488,6 +4546,33 @@ } } }, + "downloadBitwarden": { + "message": "Download Bitwarden" + }, + "downloadBitwardenOnAllDevices": { + "message": "Download Bitwarden on all devices" + }, + "getTheMobileApp": { + "message": "Get the mobile app" + }, + "getTheMobileAppDesc": { + "message": "Access your passwords on the go with the Bitwarden mobile app." + }, + "getTheDesktopApp": { + "message": "Get the desktop app" + }, + "getTheDesktopAppDesc": { + "message": "Access your vault without a browser, then set up unlock with biometrics to expedite unlocking in both the desktop app and browser extension." + }, + "downloadFromBitwardenNow": { + "message": "Download from bitwarden.com now" + }, + "getItOnGooglePlay": { + "message": "Get it on Google Play" + }, + "downloadOnTheAppStore": { + "message": "Download on the App Store" + }, "permanentlyDeleteAttachmentConfirmation": { "message": "您確定要永久刪除此附檔嗎?" }, @@ -4949,6 +5034,15 @@ "biometricsStatusHelptextUnavailableReasonUnknown": { "message": "基於不明原因,生物辨識解鎖無法使用。" }, + "unlockVault": { + "message": "Unlock your vault in seconds" + }, + "unlockVaultDesc": { + "message": "You can customize your unlock and timeout settings to more quickly access your vault." + }, + "unlockPinSet": { + "message": "Unlock PIN set" + }, "authenticating": { "message": "驗證中" }, @@ -5111,42 +5205,6 @@ "beta": { "message": "測試版" }, - "importantNotice": { - "message": "重要通知" - }, - "setupTwoStepLogin": { - "message": "啟動兩階段登入" - }, - "newDeviceVerificationNoticeContentPage1": { - "message": "從 2025 年 2 月開始,Bitwarden 會傳送代碼到您的帳號電子郵件中來驗證新裝置的登入。" - }, - "newDeviceVerificationNoticeContentPage2": { - "message": "您可以啟動兩階段認證來保護您的帳號或更改您可以存取的電子郵件位址。" - }, - "remindMeLater": { - "message": "稍後再提醒我" - }, - "newDeviceVerificationNoticePageOneFormContent": { - "message": "您可以存取您的電子郵件位址 $EMAIL$ 嗎?", - "placeholders": { - "email": { - "content": "$1", - "example": "your_name@email.com" - } - } - }, - "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "不,我不行" - }, - "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "是,我可以存取我的電子郵件位址" - }, - "turnOnTwoStepLogin": { - "message": "啟動兩階段登入" - }, - "changeAcctEmail": { - "message": "更改帳號電子郵件位址" - }, "extensionWidth": { "message": "擴充套件寬度" }, @@ -5234,6 +5292,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, @@ -5246,14 +5307,32 @@ "hasItemsVaultNudgeTitle": { "message": "Welcome to your vault!" }, - "hasItemsVaultNudgeBody": { - "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" + "hasItemsVaultNudgeBodyOne": { + "message": "Autofill items for the current page" + }, + "hasItemsVaultNudgeBodyTwo": { + "message": "Favorite items for easy access" + }, + "hasItemsVaultNudgeBodyThree": { + "message": "Search your vault for something else" }, "newLoginNudgeTitle": { "message": "Save time with autofill" }, - "newLoginNudgeBody": { - "message": "Include a Website so this login appears as an autofill suggestion." + "newLoginNudgeBodyOne": { + "message": "Include a", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyBold": { + "message": "Website", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." + }, + "newLoginNudgeBodyTwo": { + "message": "so this login appears as an autofill suggestion.", + "description": "This is in multiple parts to allow for bold text in the middle of the sentence.", + "example": "Include a Website so this login appears as an autofill suggestion." }, "newCardNudgeTitle": { "message": "Seamless online checkout" @@ -5276,7 +5355,34 @@ "newSshNudgeTitle": { "message": "Developer-friendly SSH access" }, - "newSshNudgeBody": { - "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication." + "newSshNudgeBodyOne": { + "message": "Store your keys and connect with the SSH agent for fast, encrypted authentication.", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "newSshNudgeBodyTwo": { + "message": "Learn more about SSH agent", + "description": "Two part message", + "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "generatorNudgeTitle": { + "message": "Quickly create passwords" + }, + "generatorNudgeBodyOne": { + "message": "Easily create strong and unique passwords by clicking on", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyTwo": { + "message": "to help you keep your logins secure.", + "description": "Two part message", + "example": "Easily create strong and unique passwords by clicking on {icon} to help you keep your logins secure." + }, + "generatorNudgeBodyAria": { + "message": "Easily create strong and unique passwords by clicking on the Generate password button to help you keep your logins secure.", + "description": "Aria label for the body content of the generator nudge" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/auth/popup/account-switching/account-switcher.component.html b/apps/browser/src/auth/popup/account-switching/account-switcher.component.html index de8ab4c7b08..b9f9b984c69 100644 --- a/apps/browser/src/auth/popup/account-switching/account-switcher.component.html +++ b/apps/browser/src/auth/popup/account-switching/account-switcher.component.html @@ -57,19 +57,19 @@ [disabled]="currentAccount.status === lockedStatus || !activeUserCanLock" [title]="!activeUserCanLock ? ('unlockMethodNeeded' | i18n) : ''" > - + {{ "lockNow" | i18n }} diff --git a/apps/browser/src/auth/popup/account-switching/account.component.html b/apps/browser/src/auth/popup/account-switching/account.component.html index d2e15d31899..d22ce9c9366 100644 --- a/apps/browser/src/auth/popup/account-switching/account.component.html +++ b/apps/browser/src/auth/popup/account-switching/account.component.html @@ -32,13 +32,13 @@ - + diff --git a/apps/browser/src/auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper.stories.ts b/apps/browser/src/auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper.stories.ts index a0990485d49..78ca577a69d 100644 --- a/apps/browser/src/auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper.stories.ts +++ b/apps/browser/src/auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper.stories.ts @@ -168,18 +168,21 @@ type Story = StoryObj; @Component({ selector: "bit-default-primary-outlet-example-component", template: "

Primary Outlet Example:
your primary component goes here

", + standalone: false, }) class DefaultPrimaryOutletExampleComponent {} @Component({ selector: "bit-default-secondary-outlet-example-component", template: "

Secondary Outlet Example:
your secondary component goes here

", + standalone: false, }) class DefaultSecondaryOutletExampleComponent {} @Component({ selector: "bit-default-env-selector-outlet-example-component", template: "

Env Selector Outlet Example:
your env selector component goes here

", + standalone: false, }) class DefaultEnvSelectorOutletExampleComponent {} @@ -264,6 +267,7 @@ const changedData: ExtensionAnonLayoutWrapperData = { template: ` `, + standalone: false, }) export class DynamicContentExampleComponent { initialData = true; diff --git a/apps/browser/src/auth/popup/set-password.component.ts b/apps/browser/src/auth/popup/set-password.component.ts index accde2e9a09..2a796854531 100644 --- a/apps/browser/src/auth/popup/set-password.component.ts +++ b/apps/browser/src/auth/popup/set-password.component.ts @@ -5,5 +5,6 @@ import { SetPasswordComponent as BaseSetPasswordComponent } from "@bitwarden/ang @Component({ selector: "app-set-password", templateUrl: "set-password.component.html", + standalone: false, }) export class SetPasswordComponent extends BaseSetPasswordComponent {} diff --git a/apps/browser/src/auth/popup/settings/account-security.component.html b/apps/browser/src/auth/popup/settings/account-security.component.html index ebf79af644c..d835497d9be 100644 --- a/apps/browser/src/auth/popup/settings/account-security.component.html +++ b/apps/browser/src/auth/popup/settings/account-security.component.html @@ -5,6 +5,13 @@ +
diff --git a/apps/browser/src/auth/popup/settings/account-security.component.spec.ts b/apps/browser/src/auth/popup/settings/account-security.component.spec.ts index abe642970bb..56b18068778 100644 --- a/apps/browser/src/auth/popup/settings/account-security.component.spec.ts +++ b/apps/browser/src/auth/popup/settings/account-security.component.spec.ts @@ -4,7 +4,10 @@ import { By } from "@angular/platform-browser"; import { mock } from "jest-mock-extended"; import { firstValueFrom, of } from "rxjs"; +import { CollectionService } from "@bitwarden/admin-console/common"; import { PinServiceAbstraction } from "@bitwarden/auth/common"; +import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { PolicyType } from "@bitwarden/common/admin-console/enums"; import { Policy } from "@bitwarden/common/admin-console/models/domain/policy"; @@ -16,14 +19,18 @@ import { VaultTimeoutStringType, VaultTimeoutAction, } from "@bitwarden/common/key-management/vault-timeout"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { MessageSender } from "@bitwarden/common/platform/messaging"; import { Utils } from "@bitwarden/common/platform/misc/utils"; +import { StateProvider } from "@bitwarden/common/platform/state"; import { FakeAccountService, mockAccountServiceWith } from "@bitwarden/common/spec"; import { UserId } from "@bitwarden/common/types/guid"; +import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { DialogService, ToastService } from "@bitwarden/components"; import { BiometricStateService, BiometricsService, KeyService } from "@bitwarden/key-management"; @@ -71,6 +78,13 @@ describe("AccountSecurityComponent", () => { { provide: UserVerificationService, useValue: mock() }, { provide: VaultTimeoutService, useValue: mock() }, { provide: VaultTimeoutSettingsService, useValue: vaultTimeoutSettingsService }, + { provide: StateProvider, useValue: mock() }, + { provide: CipherService, useValue: mock() }, + { provide: ApiService, useValue: mock() }, + { provide: LogService, useValue: mock() }, + { provide: OrganizationService, useValue: mock() }, + { provide: CollectionService, useValue: mock() }, + { provide: ConfigService, useValue: mock() }, ], }) .overrideComponent(AccountSecurityComponent, { diff --git a/apps/browser/src/auth/popup/settings/account-security.component.ts b/apps/browser/src/auth/popup/settings/account-security.component.ts index ede044b21de..26a805b3624 100644 --- a/apps/browser/src/auth/popup/settings/account-security.component.ts +++ b/apps/browser/src/auth/popup/settings/account-security.component.ts @@ -22,6 +22,8 @@ import { } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { NudgesService, NudgeType } from "@bitwarden/angular/vault"; +import { SpotlightComponent } from "@bitwarden/angular/vault/components/spotlight/spotlight.component"; import { FingerprintDialogComponent, VaultTimeoutInputComponent } from "@bitwarden/auth/angular"; import { PinServiceAbstraction } from "@bitwarden/auth/common"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; @@ -96,6 +98,7 @@ import { AwaitDesktopDialogComponent } from "./await-desktop-dialog.component"; SectionComponent, SectionHeaderComponent, SelectModule, + SpotlightComponent, TypographyModule, VaultTimeoutInputComponent, ], @@ -120,6 +123,14 @@ export class AccountSecurityComponent implements OnInit, OnDestroy { enableAutoBiometricsPrompt: true, }); + protected showAccountSecurityNudge$: Observable = + this.accountService.activeAccount$.pipe( + getUserId, + switchMap((userId) => + this.vaultNudgesService.showNudgeSpotlight$(NudgeType.AccountSecurity, userId), + ), + ); + private refreshTimeoutSettings$ = new BehaviorSubject(undefined); private destroy$ = new Subject(); @@ -142,6 +153,7 @@ export class AccountSecurityComponent implements OnInit, OnDestroy { private biometricStateService: BiometricStateService, private toastService: ToastService, private biometricsService: BiometricsService, + private vaultNudgesService: NudgesService, ) {} async ngOnInit() { @@ -402,6 +414,14 @@ export class AccountSecurityComponent implements OnInit, OnDestroy { } } + protected async dismissAccountSecurityNudge() { + const activeAccount = await firstValueFrom(this.accountService.activeAccount$); + if (!activeAccount) { + return; + } + await this.vaultNudgesService.dismissNudge(NudgeType.AccountSecurity, activeAccount.id); + } + async saveVaultTimeoutAction(value: VaultTimeoutAction) { if (value === VaultTimeoutAction.LogOut) { const confirmed = await this.dialogService.openSimpleDialog({ @@ -453,8 +473,15 @@ export class AccountSecurityComponent implements OnInit, OnDestroy { this.form.controls.pin.setValue(userHasPinSet, { emitEvent: false }); const requireReprompt = (await this.pinService.getPinLockType(userId)) == "EPHEMERAL"; this.form.controls.pinLockWithMasterPassword.setValue(requireReprompt, { emitEvent: false }); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("unlockPinSet"), + }); + await this.vaultNudgesService.dismissNudge(NudgeType.AccountSecurity, userId); } else { - await this.vaultTimeoutSettingsService.clear(); + const userId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + await this.vaultTimeoutSettingsService.clear(userId); } } diff --git a/apps/browser/src/auth/popup/settings/vault-timeout-input.component.ts b/apps/browser/src/auth/popup/settings/vault-timeout-input.component.ts index c56e6578a0b..25a4d01333d 100644 --- a/apps/browser/src/auth/popup/settings/vault-timeout-input.component.ts +++ b/apps/browser/src/auth/popup/settings/vault-timeout-input.component.ts @@ -18,5 +18,6 @@ import { VaultTimeoutInputComponent as VaultTimeoutInputComponentBase } from "@b useExisting: VaultTimeoutInputComponent, }, ], + standalone: false, }) export class VaultTimeoutInputComponent extends VaultTimeoutInputComponentBase {} diff --git a/apps/browser/src/auth/popup/update-temp-password.component.ts b/apps/browser/src/auth/popup/update-temp-password.component.ts index 465bc3f7038..e8cf64b7548 100644 --- a/apps/browser/src/auth/popup/update-temp-password.component.ts +++ b/apps/browser/src/auth/popup/update-temp-password.component.ts @@ -8,6 +8,7 @@ import { postLogoutMessageListener$ } from "./utils/post-logout-message-listener @Component({ selector: "app-update-temp-password", templateUrl: "update-temp-password.component.html", + standalone: false, }) export class UpdateTempPasswordComponent extends BaseUpdateTempPasswordComponent { onSuccessfulChangePassword: () => Promise = this.doOnSuccessfulChangePassword.bind(this); diff --git a/apps/browser/src/autofill/background/auto-submit-login.background.spec.ts b/apps/browser/src/autofill/background/auto-submit-login.background.spec.ts index 9f197b02193..373354b4c54 100644 --- a/apps/browser/src/autofill/background/auto-submit-login.background.spec.ts +++ b/apps/browser/src/autofill/background/auto-submit-login.background.spec.ts @@ -5,7 +5,6 @@ import { PolicyService } from "@bitwarden/common/admin-console/abstractions/poli import { Policy } from "@bitwarden/common/admin-console/models/domain/policy"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; -import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; @@ -35,7 +34,6 @@ describe("AutoSubmitLoginBackground", () => { let scriptInjectorService: MockProxy; let authStatus$: BehaviorSubject; let authService: MockProxy; - let configService: MockProxy; let platformUtilsService: MockProxy; let policyDetails: MockProxy; let automaticAppLogInPolicy$: BehaviorSubject; @@ -56,9 +54,6 @@ describe("AutoSubmitLoginBackground", () => { authStatus$ = new BehaviorSubject(AuthenticationStatus.Unlocked); authService = mock(); authService.activeAccountStatus$ = authStatus$; - configService = mock({ - getFeatureFlag: jest.fn().mockResolvedValue(true), - }); platformUtilsService = mock(); policyDetails = mock({ enabled: true, @@ -78,7 +73,6 @@ describe("AutoSubmitLoginBackground", () => { autofillService, scriptInjectorService, authService, - configService, platformUtilsService, policyService, accountService, @@ -89,7 +83,7 @@ describe("AutoSubmitLoginBackground", () => { jest.clearAllMocks(); }); - describe("when the AutoSubmitLoginBackground feature is disabled", () => { + describe("when conditions prevent auto-submit policy activation", () => { it("destroys all event listeners when the AutomaticAppLogIn policy is not enabled", async () => { automaticAppLogInPolicy$.next([mock({ ...policyDetails, enabled: false })]); @@ -115,7 +109,7 @@ describe("AutoSubmitLoginBackground", () => { }); }); - describe("when the AutoSubmitLoginBackground feature is enabled", () => { + describe("when the AutomaticAppLogIn policy is valid and active", () => { let webRequestDetails: chrome.webRequest.WebRequestBodyDetails; describe("starting the auto-submit login workflow", () => { @@ -268,7 +262,6 @@ describe("AutoSubmitLoginBackground", () => { autofillService, scriptInjectorService, authService, - configService, platformUtilsService, policyService, accountService, diff --git a/apps/browser/src/autofill/background/auto-submit-login.background.ts b/apps/browser/src/autofill/background/auto-submit-login.background.ts index bce876e8f82..dcafe21b63c 100644 --- a/apps/browser/src/autofill/background/auto-submit-login.background.ts +++ b/apps/browser/src/autofill/background/auto-submit-login.background.ts @@ -10,8 +10,6 @@ import { AccountService } from "@bitwarden/common/auth/abstractions/account.serv import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; import { getUserId } from "@bitwarden/common/auth/services/account.service"; -import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; -import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; @@ -42,7 +40,6 @@ export class AutoSubmitLoginBackground implements AutoSubmitLoginBackgroundAbstr private autofillService: AutofillService, private scriptInjectorService: ScriptInjectorService, private authService: AuthService, - private configService: ConfigService, private platformUtilsService: PlatformUtilsService, private policyService: PolicyService, private accountService: AccountService, @@ -51,25 +48,19 @@ export class AutoSubmitLoginBackground implements AutoSubmitLoginBackgroundAbstr } /** - * Initializes the auto-submit login policy. Will return early if - * the feature flag is not set. If the policy is not enabled, it + * Initializes the auto-submit login policy. If the policy is not enabled, it * will trigger a removal of any established listeners. */ async init() { - const featureFlagEnabled = await this.configService.getFeatureFlag( - FeatureFlag.IdpAutoSubmitLogin, - ); - if (featureFlagEnabled) { - this.accountService.activeAccount$ - .pipe( - getUserId, - switchMap((userId) => - this.policyService.policiesByType$(PolicyType.AutomaticAppLogIn, userId), - ), - getFirstPolicy, - ) - .subscribe(this.handleAutoSubmitLoginPolicySubscription.bind(this)); - } + this.accountService.activeAccount$ + .pipe( + getUserId, + switchMap((userId) => + this.policyService.policiesByType$(PolicyType.AutomaticAppLogIn, userId), + ), + getFirstPolicy, + ) + .subscribe(this.handleAutoSubmitLoginPolicySubscription.bind(this)); } /** diff --git a/apps/browser/src/autofill/background/notification.background.spec.ts b/apps/browser/src/autofill/background/notification.background.spec.ts index 63ae1193737..b161200215a 100644 --- a/apps/browser/src/autofill/background/notification.background.spec.ts +++ b/apps/browser/src/autofill/background/notification.background.spec.ts @@ -17,6 +17,7 @@ import { MessagingService } from "@bitwarden/common/platform/abstractions/messag import { SelfHostedEnvironment } from "@bitwarden/common/platform/services/default-environment.service"; import { ThemeStateService } from "@bitwarden/common/platform/theming/theme-state.service"; import { UserId } from "@bitwarden/common/types/guid"; +import { CipherRepromptType } from "@bitwarden/common/vault/enums/cipher-reprompt-type"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { FolderView } from "@bitwarden/common/vault/models/view/folder.view"; import { CipherService } from "@bitwarden/common/vault/services/cipher.service"; @@ -68,8 +69,9 @@ describe("NotificationBackground", () => { const accountService = mock(); const organizationService = mock(); + const userId = "testId" as UserId; const activeAccountSubject = new BehaviorSubject<{ id: UserId } & AccountInfo>({ - id: "testId" as UserId, + id: userId, email: "test@example.com", emailVerified: true, name: "Test User", @@ -828,6 +830,7 @@ describe("NotificationBackground", () => { id: "testId", name: "testItemName", login: { username: "testUser" }, + reprompt: CipherRepromptType.None, }); getDecryptedCipherByIdSpy.mockResolvedValueOnce(cipherView); @@ -842,6 +845,7 @@ describe("NotificationBackground", () => { message.edit, sender.tab, "testId", + false, ); expect(updateWithServerSpy).toHaveBeenCalled(); expect(tabSendMessageDataSpy).toHaveBeenCalledWith( @@ -855,6 +859,55 @@ describe("NotificationBackground", () => { ); }); + it("prompts the user for master password entry if the notification message type is for ChangePassword and the cipher reprompt is enabled", async () => { + const tab = createChromeTabMock({ id: 1, url: "https://example.com" }); + const sender = mock({ tab }); + const message: NotificationBackgroundExtensionMessage = { + command: "bgSaveCipher", + edit: false, + folder: "folder-id", + }; + const queueMessage = mock({ + type: NotificationQueueMessageType.ChangePassword, + tab, + domain: "example.com", + newPassword: "newPassword", + }); + notificationBackground["notificationQueue"] = [queueMessage]; + const cipherView = mock({ + id: "testId", + name: "testItemName", + login: { username: "testUser" }, + reprompt: CipherRepromptType.Password, + }); + getDecryptedCipherByIdSpy.mockResolvedValueOnce(cipherView); + + sendMockExtensionMessage(message, sender); + await flushPromises(); + + expect(editItemSpy).not.toHaveBeenCalled(); + expect(autofillService.isPasswordRepromptRequired).toHaveBeenCalled(); + expect(createWithServerSpy).not.toHaveBeenCalled(); + expect(updatePasswordSpy).toHaveBeenCalledWith( + cipherView, + queueMessage.newPassword, + message.edit, + sender.tab, + "testId", + false, + ); + expect(updateWithServerSpy).not.toHaveBeenCalled(); + expect(tabSendMessageDataSpy).not.toHaveBeenCalledWith( + sender.tab, + "saveCipherAttemptCompleted", + { + itemName: "testItemName", + cipherId: cipherView.id, + task: undefined, + }, + ); + }); + it("completes password update notification with a security task notice if any are present for the cipher, and dismisses tasks for the updated cipher", async () => { const mockCipherId = "testId"; const mockOrgId = "testOrgId"; @@ -905,6 +958,7 @@ describe("NotificationBackground", () => { id: mockCipherId, organizationId: mockOrgId, name: "Test Item", + reprompt: CipherRepromptType.None, }); getDecryptedCipherByIdSpy.mockResolvedValueOnce(cipherView); @@ -919,6 +973,7 @@ describe("NotificationBackground", () => { message.edit, sender.tab, mockCipherId, + false, ); expect(updateWithServerSpy).toHaveBeenCalled(); expect(tabSendMessageDataSpy).toHaveBeenCalledWith( @@ -1000,6 +1055,7 @@ describe("NotificationBackground", () => { message.edit, sender.tab, "testId", + false, ); expect(editItemSpy).toHaveBeenCalled(); expect(updateWithServerSpy).not.toHaveBeenCalled(); @@ -1086,8 +1142,11 @@ describe("NotificationBackground", () => { convertAddLoginQueueMessageToCipherViewSpy.mockReturnValueOnce(cipherView); editItemSpy.mockResolvedValueOnce(undefined); cipherEncryptSpy.mockResolvedValueOnce({ - ...cipherView, - id: "testId", + cipher: { + ...cipherView, + id: "testId", + }, + encryptedFor: userId, }); sendMockExtensionMessage(message, sender); @@ -1133,6 +1192,13 @@ describe("NotificationBackground", () => { folderExistsSpy.mockResolvedValueOnce(true); convertAddLoginQueueMessageToCipherViewSpy.mockReturnValueOnce(cipherView); editItemSpy.mockResolvedValueOnce(undefined); + cipherEncryptSpy.mockResolvedValueOnce({ + cipher: { + ...cipherView, + id: "testId", + }, + encryptedFor: userId, + }); const errorMessage = "fetch error"; createWithServerSpy.mockImplementation(() => { throw new Error(errorMessage); @@ -1170,7 +1236,7 @@ describe("NotificationBackground", () => { newPassword: "newPassword", }); notificationBackground["notificationQueue"] = [queueMessage]; - const cipherView = mock(); + const cipherView = mock({ reprompt: CipherRepromptType.None }); getDecryptedCipherByIdSpy.mockResolvedValueOnce(cipherView); const errorMessage = "fetch error"; updateWithServerSpy.mockImplementation(() => { diff --git a/apps/browser/src/autofill/background/notification.background.ts b/apps/browser/src/autofill/background/notification.background.ts index 339b033809d..cb6a67c8137 100644 --- a/apps/browser/src/autofill/background/notification.background.ts +++ b/apps/browser/src/autofill/background/notification.background.ts @@ -14,6 +14,7 @@ import { ExtensionCommand, ExtensionCommandType, NOTIFICATION_BAR_LIFESPAN_MS, + UPDATE_PASSWORD, } from "@bitwarden/common/autofill/constants"; import { DomainSettingsService } from "@bitwarden/common/autofill/services/domain-settings.service"; import { UserNotificationSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/user-notification-settings.service"; @@ -104,6 +105,8 @@ export default class NotificationBackground { this.removeTabFromNotificationQueue(sender.tab), bgReopenUnlockPopout: ({ sender }) => this.openUnlockPopout(sender.tab), bgSaveCipher: ({ message, sender }) => this.handleSaveCipherMessage(message, sender), + bgHandleReprompt: ({ message, sender }: any) => + this.handleCipherUpdateRepromptResponse(message), bgUnlockPopoutOpened: ({ message, sender }) => this.unlockVault(message, sender.tab), checkNotificationQueue: ({ sender }) => this.checkNotificationQueue(sender.tab), collectPageDetailsResponse: ({ message }) => @@ -542,10 +545,15 @@ export default class NotificationBackground { * @param tab - The tab that the message was sent from */ private async unlockVault(message: NotificationBackgroundExtensionMessage, tab: chrome.tabs.Tab) { + const notificationRefreshFlagEnabled = await this.getNotificationFlag(); if (message.data?.skipNotification) { return; } + if (notificationRefreshFlagEnabled) { + return; + } + const currentAuthStatus = await this.getAuthStatus(); if (currentAuthStatus !== AuthenticationStatus.Locked || this.notificationQueue.length) { return; @@ -626,6 +634,17 @@ export default class NotificationBackground { await this.saveOrUpdateCredentials(sender.tab, message.edit, message.folder); } + async handleCipherUpdateRepromptResponse(message: NotificationBackgroundExtensionMessage) { + if (message.success) { + await this.saveOrUpdateCredentials(message.tab, false, undefined, true); + } else { + await BrowserApi.tabSendMessageData(message.tab, "saveCipherAttemptCompleted", { + error: "Password reprompt failed", + }); + return; + } + } + /** * Saves or updates credentials based on the message within the * notification queue that is associated with the specified tab. @@ -634,7 +653,12 @@ export default class NotificationBackground { * @param edit - Identifies if the credentials should be edited or simply added * @param folderId - The folder to add the cipher to */ - private async saveOrUpdateCredentials(tab: chrome.tabs.Tab, edit: boolean, folderId?: string) { + private async saveOrUpdateCredentials( + tab: chrome.tabs.Tab, + edit: boolean, + folderId?: string, + skipReprompt: boolean = false, + ) { for (let i = this.notificationQueue.length - 1; i >= 0; i--) { const queueMessage = this.notificationQueue[i]; if ( @@ -649,18 +673,26 @@ export default class NotificationBackground { continue; } - this.notificationQueue.splice(i, 1); - const activeUserId = await firstValueFrom( this.accountService.activeAccount$.pipe(getOptionalUserId), ); if (queueMessage.type === NotificationQueueMessageType.ChangePassword) { const cipherView = await this.getDecryptedCipherById(queueMessage.cipherId, activeUserId); - await this.updatePassword(cipherView, queueMessage.newPassword, edit, tab, activeUserId); + + await this.updatePassword( + cipherView, + queueMessage.newPassword, + edit, + tab, + activeUserId, + skipReprompt, + ); return; } + this.notificationQueue.splice(i, 1); + // If the vault was locked, check if a cipher needs updating instead of creating a new one if (queueMessage.wasVaultLocked) { const allCiphers = await this.cipherService.getAllDecryptedForUrl( @@ -687,9 +719,10 @@ export default class NotificationBackground { return; } - const cipher = await this.cipherService.encrypt(newCipher, activeUserId); + const encrypted = await this.cipherService.encrypt(newCipher, activeUserId); + const { cipher } = encrypted; try { - await this.cipherService.createWithServer(cipher); + await this.cipherService.createWithServer(encrypted); await BrowserApi.tabSendMessageData(tab, "saveCipherAttemptCompleted", { itemName: newCipher?.name && String(newCipher?.name), cipherId: cipher?.id && String(cipher?.id), @@ -720,6 +753,7 @@ export default class NotificationBackground { edit: boolean, tab: chrome.tabs.Tab, userId: UserId, + skipReprompt: boolean = false, ) { cipherView.login.password = newPassword; @@ -732,8 +766,10 @@ export default class NotificationBackground { const cipher = await this.cipherService.encrypt(cipherView, userId); const shouldGetTasks = await this.getNotificationFlag(); - try { + if (!cipherView.edit) { + throw new Error("You do not have permission to edit this cipher."); + } const tasks = shouldGetTasks ? await this.getSecurityTasks(userId) : []; const updatedCipherTask = tasks.find((task) => task.cipherId === cipherView?.id); const cipherHasTask = !!updatedCipherTask?.id; @@ -751,6 +787,12 @@ export default class NotificationBackground { } : undefined; + if (cipherView.reprompt && !skipReprompt) { + await this.autofillService.isPasswordRepromptRequired(cipherView, tab, UPDATE_PASSWORD); + + return; + } + await this.cipherService.updateWithServer(cipher); await BrowserApi.tabSendMessageData(tab, "saveCipherAttemptCompleted", { @@ -853,9 +895,7 @@ export default class NotificationBackground { private async getDecryptedCipherById(cipherId: string, userId: UserId) { const cipher = await this.cipherService.get(cipherId, userId); if (cipher != null && cipher.type === CipherType.Login) { - return await cipher.decrypt( - await this.cipherService.getKeyForCipherKeyDecryption(cipher, userId), - ); + return await this.cipherService.decrypt(cipher, userId); } return null; } diff --git a/apps/browser/src/autofill/content/components/.lit-storybook/main.ts b/apps/browser/src/autofill/content/components/.lit-storybook/main.ts index 9068bbfc27d..a316d8f5baa 100644 --- a/apps/browser/src/autofill/content/components/.lit-storybook/main.ts +++ b/apps/browser/src/autofill/content/components/.lit-storybook/main.ts @@ -58,6 +58,10 @@ const config: StorybookConfig = { }, ], }); + config.module.rules.push({ + test: /\.scss$/, + use: [require.resolve("css-loader"), require.resolve("sass-loader")], + }); } return config; }, diff --git a/apps/browser/src/autofill/content/components/buttons/action-button.ts b/apps/browser/src/autofill/content/components/buttons/action-button.ts index 881b44b4785..8d8bfacec77 100644 --- a/apps/browser/src/autofill/content/components/buttons/action-button.ts +++ b/apps/browser/src/autofill/content/components/buttons/action-button.ts @@ -5,17 +5,19 @@ import { Theme } from "@bitwarden/common/platform/enums"; import { border, themes, typography, spacing } from "../constants/styles"; +export type ActionButtonProps = { + buttonText: string | TemplateResult; + disabled?: boolean; + theme: Theme; + handleClick: (e: Event) => void; +}; + export function ActionButton({ buttonText, disabled = false, theme, handleClick, -}: { - buttonText: string | TemplateResult; - disabled?: boolean; - theme: Theme; - handleClick: (e: Event) => void; -}) { +}: ActionButtonProps) { const handleButtonClick = (event: Event) => { if (!disabled) { handleClick(event); @@ -62,6 +64,10 @@ const actionButtonStyles = ({ disabled, theme }: { disabled: boolean; theme: The background-color: ${themes[theme].primary["700"]}; color: ${themes[theme].text.contrast}; } + :focus { + outline: 2px solid ${themes[theme].primary["600"]}; + outline-offset: 1px; + } `} svg { diff --git a/apps/browser/src/autofill/content/components/buttons/badge-button.ts b/apps/browser/src/autofill/content/components/buttons/badge-button.ts index 3b3b84f8166..3cdd453ee1a 100644 --- a/apps/browser/src/autofill/content/components/buttons/badge-button.ts +++ b/apps/browser/src/autofill/content/components/buttons/badge-button.ts @@ -5,17 +5,23 @@ import { Theme } from "@bitwarden/common/platform/enums"; import { border, themes, typography, spacing } from "../constants/styles"; +export type BadgeButtonProps = { + buttonAction: (e: Event) => void; + buttonText: string; + itemName: string; + disabled?: boolean; + theme: Theme; + username?: string; +}; + export function BadgeButton({ buttonAction, buttonText, disabled = false, + itemName, theme, -}: { - buttonAction: (e: Event) => void; - buttonText: string; - disabled?: boolean; - theme: Theme; -}) { + username, +}: BadgeButtonProps) { const handleButtonClick = (event: Event) => { if (!disabled) { buttonAction(event); @@ -26,6 +32,7 @@ export function BadgeButton({ `; diff --git a/apps/browser/src/autofill/content/components/buttons/edit-button.ts b/apps/browser/src/autofill/content/components/buttons/edit-button.ts index a0037146db2..ecbb736bb8e 100644 --- a/apps/browser/src/autofill/content/components/buttons/edit-button.ts +++ b/apps/browser/src/autofill/content/components/buttons/edit-button.ts @@ -6,17 +6,14 @@ import { Theme } from "@bitwarden/common/platform/enums"; import { themes, typography, spacing } from "../constants/styles"; import { PencilSquare } from "../icons"; -export function EditButton({ - buttonAction, - buttonText, - disabled = false, - theme, -}: { +export type EditButtonProps = { buttonAction: (e: Event) => void; buttonText: string; disabled?: boolean; theme: Theme; -}) { +}; + +export function EditButton({ buttonAction, buttonText, disabled = false, theme }: EditButtonProps) { return html`
`; diff --git a/apps/browser/src/autofill/content/components/cipher/cipher-item.ts b/apps/browser/src/autofill/content/components/cipher/cipher-item.ts index 8ab29860f3b..ab3b57f535c 100644 --- a/apps/browser/src/autofill/content/components/cipher/cipher-item.ts +++ b/apps/browser/src/autofill/content/components/cipher/cipher-item.ts @@ -8,6 +8,7 @@ import { NotificationType, NotificationTypes, } from "../../../notification/abstractions/notification-bar"; +import { I18n } from "../common-types"; import { CipherAction } from "./cipher-action"; import { CipherIcon } from "./cipher-icon"; @@ -16,27 +17,36 @@ import { NotificationCipherData } from "./types"; const cipherIconWidth = "24px"; +export type CipherItemProps = { + cipher: NotificationCipherData; + handleAction?: (e: Event) => void; + i18n: I18n; + notificationType?: NotificationType; + theme: Theme; +}; + export function CipherItem({ cipher, handleAction, i18n, notificationType, theme = ThemeTypes.Light, -}: { - cipher: NotificationCipherData; - handleAction?: (e: Event) => void; - i18n: { [key: string]: string }; - notificationType?: NotificationType; - theme: Theme; -}) { - const { icon } = cipher; +}: CipherItemProps) { + const { icon, name, login } = cipher; const uri = (icon.imageEnabled && icon.image) || undefined; let cipherActionButton = null; if (notificationType === NotificationTypes.Change || notificationType === NotificationTypes.Add) { cipherActionButton = html`
- ${CipherAction({ handleAction, i18n, notificationType, theme })} + ${CipherAction({ + handleAction, + i18n, + itemName: name, + notificationType, + theme, + username: login?.username, + })}
`; } diff --git a/apps/browser/src/autofill/content/components/common-types.ts b/apps/browser/src/autofill/content/components/common-types.ts index 591c579bae5..5967f6205a9 100644 --- a/apps/browser/src/autofill/content/components/common-types.ts +++ b/apps/browser/src/autofill/content/components/common-types.ts @@ -3,10 +3,15 @@ import { TemplateResult } from "lit"; import { ProductTierType } from "@bitwarden/common/billing/enums"; import { Theme } from "@bitwarden/common/platform/enums"; +export type I18n = { + [key: string]: string; +}; + export type IconProps = { color?: string; disabled?: boolean; theme: Theme; + ariaHidden?: boolean; }; export type Option = { diff --git a/apps/browser/src/autofill/content/components/constants/styles.ts b/apps/browser/src/autofill/content/components/constants/styles.ts index f7c9ffd4d92..08c8671ce14 100644 --- a/apps/browser/src/autofill/content/components/constants/styles.ts +++ b/apps/browser/src/autofill/content/components/constants/styles.ts @@ -144,17 +144,17 @@ export const border = { export const typography = { body1: ` line-height: 24px; - font-family: "DM Sans", sans-serif; + font-family: Roboto, sans-serif; font-size: 16px; `, body2: ` line-height: 20px; - font-family: "DM Sans", sans-serif; + font-family: Roboto, sans-serif; font-size: 14px; `, helperMedium: ` line-height: 16px; - font-family: "DM Sans", sans-serif; + font-family: Roboto, sans-serif; font-size: 12px; `, }; diff --git a/apps/browser/src/autofill/content/components/icons/angle-down.ts b/apps/browser/src/autofill/content/components/icons/angle-down.ts index 27cd5ab81c5..2bd54f7dbee 100644 --- a/apps/browser/src/autofill/content/components/icons/angle-down.ts +++ b/apps/browser/src/autofill/content/components/icons/angle-down.ts @@ -4,11 +4,16 @@ import { html } from "lit"; import { IconProps } from "../common-types"; import { buildIconColorRule, ruleNames, themes } from "../constants/styles"; -export function AngleDown({ color, disabled, theme }: IconProps) { +export function AngleDown({ ariaHidden = true, color, disabled, theme }: IconProps) { const shapeColor = disabled ? themes[theme].secondary["300"] : color || themes[theme].text.main; return html` - + + + + + + + + + + - -## Cipher Icon - -The `CipherIcon` component is a versatile icon renderer designed for secure environments. It -dynamically supports custom icons provided via URIs or displays a default icon (`Globe`) styled -based on the theme and provided properties. - - - - -## Props - -| **Prop** | **Type** | **Required** | **Description** | -| -------- | ------------------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `color` | `string` | Yes | A contextual color override applied when the `uri` is not provided, ensuring consistent styling of the default icon. | -| `size` | `string` | Yes | A valid CSS `width` value representing the width basis of the graphic. The height adjusts to maintain the original aspect ratio of the graphic. | -| `theme` | `Theme` | Yes | The styling theme for the icon, matching the `Theme` enum. | -| `uri` | `string` (optional) | No | A URL to an external graphic. If provided, the component displays this icon. If omitted, a default icon (`Globe`) styled with the provided `color` and `theme`. | - -## Installation and Setup - -1. Ensure the necessary dependencies are installed: - - - `lit`: Renders the component. - - `@emotion/css`: Styles the component. - -2. Pass the necessary props when using the component: - - `color`: Used when no `uri` is provided to style the default icon. - - `size`: Defines the width of the icon. Height maintains aspect ratio. - - `theme`: Specifies the theme for styling. - - `uri` (optional): If provided, this URI is used to display a custom icon. - -## Accessibility (WCAG) Compliance - -The `CipherIcon` component ensures accessible and user-friendly interactions through thoughtful -design: - -### Semantic Rendering - -- When the `uri` is provided, the component renders an `` element, which is semantically - appropriate for external graphics. -- If no `uri` is provided, the default icon is wrapped in a ``, ensuring proper context for - screen readers. - -### Visual Feedback - -- The component visually adjusts based on the `size`, `color`, and `theme`, ensuring the icon - remains clear and legible across different environments. - -### Keyboard and Screen Reader Support - -- Ensure that any container or parent component provides appropriate `alt` text or labeling when - `uri` is used with an `` tag for additional accessibility. - -## Usage Example - -Here's an example of how to integrate the `CipherIcon` component: - -```ts -import { CipherIcon } from "./cipher-icon"; -import { ThemeTypes } from "@bitwarden/common/platform/enums/theme-type.enum"; - -; -``` - -This configuration displays a custom icon from the provided URI with a width of 32px, styled for the -light theme. If the URI is omitted, the Globe icon is used as the fallback, colored in blue. - -### Default Styles - -- The default styles ensure responsive and clean design: - -- Width: Defined by the size prop. -- Height: Automatically adjusts to maintain the aspect ratio. -- Fit Content: Ensures the icon does not overflow or distort its container. - -### Notes - -- Always validate the uri provided to ensure it points to a secure and accessible location. -- Use the color and theme props for consistent fallback styling when uri is not provided. diff --git a/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/cipher-indicator-icon.mdx b/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/cipher-indicator-icon.mdx deleted file mode 100644 index 6c338276c02..00000000000 --- a/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/cipher-indicator-icon.mdx +++ /dev/null @@ -1,81 +0,0 @@ -import { Meta, Controls, Primary } from "@storybook/addon-docs"; - -import * as stories from "./cipher-indicator-icon.lit-stories"; - - - -## Cipher Info Indicator Icons - -The `CipherInfoIndicatorIcons` component displays a set of icons indicating specific attributes -related to cipher information. It supports business and family organization indicators, styled -dynamically based on the provided theme. - - - - -## Props - -| **Prop** | **Type** | **Required** | **Description** | -| ------------------ | --------- | ------------ | ----------------------------------------------------------------------- | -| `showBusinessIcon` | `boolean` | No | Displays the business organization icon when set to `true`. | -| `showFamilyIcon` | `boolean` | No | Displays the family organization icon when set to `true`. | -| `theme` | `Theme` | Yes | Defines the theme used to style the icons. Must match the `Theme` enum. | - -## Installation and Setup - -1. Ensure the necessary dependencies are installed: - - - `lit`: Renders the component. - - `@emotion/css`: Used for styling. - -2. Pass the required props when using the component: - - `showBusinessIcon`: A boolean that, when `true`, displays the business icon. - - `showFamilyIcon`: A boolean that, when `true`, displays the family icon. - - `theme`: Specifies the theme for styling the icons. - -## Accessibility (WCAG) Compliance - -The `CipherInfoIndicatorIcons` component ensures accessibility and usability through its design: - -### Screen Reader Compatibility - -- Icons are rendered as `` elements, and parent components should provide appropriate labeling - or descriptions to convey their meaning to screen readers. - -### Visual Feedback - -- Icons are styled dynamically based on the `theme` to ensure visual clarity and contrast in all - supported themes. -- The size of the icons is fixed at `12px` in height to maintain a consistent visual appearance. - -## Usage Example - -Here's an example of how to integrate the `CipherInfoIndicatorIcons` component: - -```ts -import { CipherInfoIndicatorIcons } from "./cipher-info-indicator-icons"; -import { ThemeTypes } from "@bitwarden/common/platform/enums/theme-type.enum"; - -; -``` - -This example displays the business organization icon, styled for the dark theme, and omits the -family organization icon. - -### Styling Details - -- The component includes the following styles: - -- Icons: Rendered as SVGs with a height of 12px and a width that adjusts to maintain their aspect - ratio. -- Color: Icons are dynamically styled based on the theme, using muted text colors for a subtle - appearance. - -### Notes - -- If neither showBusinessIcon nor showFamilyIcon is set to true, the component renders nothing. This - behavior should be handled by the parent component. diff --git a/apps/browser/src/autofill/content/components/lit-stories/buttons/action-button.lit-stories.ts b/apps/browser/src/autofill/content/components/lit-stories/buttons/action-button.lit-stories.ts index 2aa61c627b7..77769bc67dc 100644 --- a/apps/browser/src/autofill/content/components/lit-stories/buttons/action-button.lit-stories.ts +++ b/apps/browser/src/autofill/content/components/lit-stories/buttons/action-button.lit-stories.ts @@ -1,15 +1,8 @@ import { Meta, StoryObj } from "@storybook/web-components"; -import { Theme, ThemeTypes } from "@bitwarden/common/platform/enums/theme-type.enum"; +import { ThemeTypes } from "@bitwarden/common/platform/enums/theme-type.enum"; -import { ActionButton } from "../../buttons/action-button"; - -type Args = { - buttonText: string; - disabled: boolean; - theme: Theme; - handleClick: (e: Event) => void; -}; +import { ActionButton, ActionButtonProps } from "../../buttons/action-button"; export default { title: "Components/Buttons/Action Button", @@ -31,10 +24,10 @@ export default { url: "https://www.figma.com/design/LEhqLAcBPY8uDKRfU99n9W/Autofill-notification-redesign?node-id=487-14755&t=2O7uCAkwRZCcjumm-4", }, }, -} as Meta; +} as Meta; -const Template = (args: Args) => ActionButton({ ...args }); +const Template = (args: ActionButtonProps) => ActionButton({ ...args }); -export const Default: StoryObj = { +export const Default: StoryObj = { render: Template, }; diff --git a/apps/browser/src/autofill/content/components/lit-stories/buttons/badge-button.lit-stories.ts b/apps/browser/src/autofill/content/components/lit-stories/buttons/badge-button.lit-stories.ts index df44a70278d..95d5060ee90 100644 --- a/apps/browser/src/autofill/content/components/lit-stories/buttons/badge-button.lit-stories.ts +++ b/apps/browser/src/autofill/content/components/lit-stories/buttons/badge-button.lit-stories.ts @@ -1,15 +1,8 @@ import { Meta, StoryObj } from "@storybook/web-components"; -import { Theme, ThemeTypes } from "@bitwarden/common/platform/enums/theme-type.enum"; +import { ThemeTypes } from "@bitwarden/common/platform/enums/theme-type.enum"; -import { BadgeButton } from "../../buttons/badge-button"; - -type Args = { - buttonAction: (e: Event) => void; - buttonText: string; - disabled?: boolean; - theme: Theme; -}; +import { BadgeButton, BadgeButtonProps } from "../../buttons/badge-button"; export default { title: "Components/Buttons/Badge Button", @@ -31,10 +24,10 @@ export default { url: "https://www.figma.com/design/LEhqLAcBPY8uDKRfU99n9W/Autofill-notification-redesign?node-id=502-24973&t=2O7uCAkwRZCcjumm-4", }, }, -} as Meta; +} as Meta; -const Template = (args: Args) => BadgeButton({ ...args }); +const Template = (args: BadgeButtonProps) => BadgeButton({ ...args }); -export const Default: StoryObj = { +export const Default: StoryObj = { render: Template, }; diff --git a/apps/browser/src/autofill/content/components/lit-stories/buttons/close-button.lit-stories.ts b/apps/browser/src/autofill/content/components/lit-stories/buttons/close-button.lit-stories.ts index f622ab8b3ec..886c16c7515 100644 --- a/apps/browser/src/autofill/content/components/lit-stories/buttons/close-button.lit-stories.ts +++ b/apps/browser/src/autofill/content/components/lit-stories/buttons/close-button.lit-stories.ts @@ -1,13 +1,10 @@ import { Meta, StoryObj } from "@storybook/web-components"; -import { Theme, ThemeTypes } from "@bitwarden/common/platform/enums/theme-type.enum"; +import { ThemeTypes } from "@bitwarden/common/platform/enums/theme-type.enum"; -import { CloseButton } from "../../buttons/close-button"; +import { CloseButton, CloseButtonProps } from "../../buttons/close-button"; +import { mockI18n } from "../mock-data"; -type Args = { - handleCloseNotification: (e: Event) => void; - theme: Theme; -}; export default { title: "Components/Buttons/Close Button", argTypes: { @@ -19,6 +16,7 @@ export default { handleCloseNotification: () => { alert("Close button clicked!"); }, + i18n: mockI18n, }, parameters: { design: { @@ -26,10 +24,10 @@ export default { url: "https://www.figma.com/design/LEhqLAcBPY8uDKRfU99n9W/Autofill-notification-redesign?node-id=502-24633&t=2O7uCAkwRZCcjumm-4", }, }, -} as Meta; +} as Meta; -const Template = (args: Args) => CloseButton({ ...args }); +const Template = (args: CloseButtonProps) => CloseButton({ ...args }); -export const Default: StoryObj = { +export const Default: StoryObj = { render: Template, }; diff --git a/apps/browser/src/autofill/content/components/lit-stories/buttons/edit-button.lit-stories.ts b/apps/browser/src/autofill/content/components/lit-stories/buttons/edit-button.lit-stories.ts index 34ecae30dc2..0de98a03004 100644 --- a/apps/browser/src/autofill/content/components/lit-stories/buttons/edit-button.lit-stories.ts +++ b/apps/browser/src/autofill/content/components/lit-stories/buttons/edit-button.lit-stories.ts @@ -1,28 +1,22 @@ import { Meta, StoryObj } from "@storybook/web-components"; -import { Theme, ThemeTypes } from "@bitwarden/common/platform/enums/theme-type.enum"; +import { ThemeTypes } from "@bitwarden/common/platform/enums/theme-type.enum"; -import { EditButton } from "../../buttons/edit-button"; +import { EditButton, EditButtonProps } from "../../buttons/edit-button"; -type Args = { - buttonAction: (e: Event) => void; - buttonText: string; - disabled?: boolean; - theme: Theme; -}; export default { title: "Components/Buttons/Edit Button", argTypes: { + buttonAction: { control: false }, buttonText: { control: "text" }, disabled: { control: "boolean" }, theme: { control: "select", options: [...Object.values(ThemeTypes)] }, - buttonAction: { control: false }, }, args: { + buttonAction: () => alert("Clicked"), buttonText: "Click Me", disabled: false, theme: ThemeTypes.Light, - buttonAction: () => alert("Clicked"), }, parameters: { design: { @@ -30,10 +24,10 @@ export default { url: "https://www.figma.com/design/LEhqLAcBPY8uDKRfU99n9W/Autofill-notification-redesign?node-id=502-24633&t=2O7uCAkwRZCcjumm-4", }, }, -} as Meta; +} as Meta; -const Template = (args: Args) => EditButton({ ...args }); +const Template = (args: EditButtonProps) => EditButton({ ...args }); -export const Default: StoryObj = { +export const Default: StoryObj = { render: Template, }; diff --git a/apps/browser/src/autofill/content/components/lit-stories/buttons/option-selection-button.lit-stories.ts b/apps/browser/src/autofill/content/components/lit-stories/buttons/option-selection-button.lit-stories.ts new file mode 100644 index 00000000000..e51aa92626f --- /dev/null +++ b/apps/browser/src/autofill/content/components/lit-stories/buttons/option-selection-button.lit-stories.ts @@ -0,0 +1,40 @@ +import { Meta, StoryObj } from "@storybook/web-components"; + +import { ThemeTypes } from "@bitwarden/common/platform/enums/theme-type.enum"; + +import { + OptionSelectionButton, + OptionSelectionButtonProps, +} from "../../buttons/option-selection-button"; + +export default { + title: "Components/Buttons/Option Selection Button", + argTypes: { + disabled: { control: "boolean" }, + handleButtonClick: { control: false }, + id: { control: "text" }, + text: { control: "text" }, + theme: { control: "select", options: [...Object.values(ThemeTypes)] }, + toggledOn: { control: "boolean" }, + }, + args: { + disabled: false, + handleButtonClick: () => alert("Clicked"), + id: "example-id", + text: "Click Me", + theme: ThemeTypes.Light, + toggledOn: false, + }, + parameters: { + design: { + type: "figma", + url: "https://www.figma.com/design/LEhqLAcBPY8uDKRfU99n9W/Autofill-notification-redesign?node-id=502-24633&t=2O7uCAkwRZCcjumm-4", + }, + }, +} as Meta; + +const Template = (args: OptionSelectionButtonProps) => OptionSelectionButton({ ...args }); + +export const Default: StoryObj = { + render: Template, +}; diff --git a/apps/browser/src/autofill/content/components/lit-stories/ciphers/cipher-action.lit-stories.ts b/apps/browser/src/autofill/content/components/lit-stories/ciphers/cipher-action.lit-stories.ts deleted file mode 100644 index dd1ff816f06..00000000000 --- a/apps/browser/src/autofill/content/components/lit-stories/ciphers/cipher-action.lit-stories.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Meta, StoryObj } from "@storybook/web-components"; - -import { Theme, ThemeTypes } from "@bitwarden/common/platform/enums/theme-type.enum"; - -import { NotificationTypes } from "../../../../notification/abstractions/notification-bar"; -import { CipherAction } from "../../cipher/cipher-action"; - -type Args = { - handleAction?: (e: Event) => void; - i18n: { [key: string]: string }; - notificationType: typeof NotificationTypes.Change | typeof NotificationTypes.Add; - theme: Theme; -}; -export default { - title: "Components/Ciphers/Cipher Action", - argTypes: { - theme: { control: "select", options: [...Object.values(ThemeTypes)] }, - notificationType: { - control: "select", - options: [NotificationTypes.Change, NotificationTypes.Add], - }, - handleAction: { control: false }, - }, - args: { - theme: ThemeTypes.Light, - notificationType: NotificationTypes.Change, - handleAction: () => { - alert("Action triggered!"); - }, - }, -} as Meta; - -const Template = (args: Args) => CipherAction({ ...args }); - -export const Default: StoryObj = { - render: Template, -}; diff --git a/apps/browser/src/autofill/content/components/lit-stories/ciphers/cipher-icon.lit-stories.ts b/apps/browser/src/autofill/content/components/lit-stories/ciphers/cipher-icon.lit-stories.ts deleted file mode 100644 index a8884f063de..00000000000 --- a/apps/browser/src/autofill/content/components/lit-stories/ciphers/cipher-icon.lit-stories.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Meta, StoryObj } from "@storybook/web-components"; -import { html } from "lit"; - -import { Theme, ThemeTypes } from "@bitwarden/common/platform/enums/theme-type.enum"; - -import { CipherIcon } from "../../cipher/cipher-icon"; - -type Args = { - color: string; - size: string; - theme: Theme; - uri?: string; -}; - -export default { - title: "Components/Ciphers/Cipher Icon", - argTypes: { - color: { control: "color" }, - size: { control: "text" }, - theme: { control: "select", options: [...Object.values(ThemeTypes)] }, - uri: { control: "text" }, - }, - args: { - size: "50px", - theme: ThemeTypes.Light, - uri: "", - }, -} as Meta; - -const Template = (args: Args) => { - return html` -
- ${CipherIcon({ ...args })} -
- `; -}; - -export const Default: StoryObj = { - render: Template, -}; diff --git a/apps/browser/src/autofill/content/components/lit-stories/ciphers/cipher-indicator-icons.lit-stories.ts b/apps/browser/src/autofill/content/components/lit-stories/ciphers/cipher-indicator-icons.lit-stories.ts deleted file mode 100644 index 08530452730..00000000000 --- a/apps/browser/src/autofill/content/components/lit-stories/ciphers/cipher-indicator-icons.lit-stories.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Meta, StoryObj } from "@storybook/web-components"; -import { html } from "lit"; - -import { Theme, ThemeTypes } from "@bitwarden/common/platform/enums/theme-type.enum"; - -import { CipherInfoIndicatorIcons } from "../../cipher/cipher-indicator-icons"; - -type Args = { - showBusinessIcon?: boolean; - showFamilyIcon?: boolean; - theme: Theme; -}; - -export default { - title: "Components/Ciphers/Cipher Indicator Icons", - argTypes: { - showBusinessIcon: { control: "boolean" }, - showFamilyIcon: { control: "boolean" }, - theme: { control: "select", options: [...Object.values(ThemeTypes)] }, - }, - args: { - theme: ThemeTypes.Light, - showBusinessIcon: true, - showFamilyIcon: false, - }, -} as Meta; - -const Template: StoryObj["render"] = (args) => - html`
${CipherInfoIndicatorIcons({ ...args })}
`; - -export const Default: StoryObj = { - render: Template, -}; diff --git a/apps/browser/src/autofill/content/components/lit-stories/icons/icons.lit-stories.ts b/apps/browser/src/autofill/content/components/lit-stories/icons/icons.lit-stories.ts index c74895e1dea..3741ccbcb69 100644 --- a/apps/browser/src/autofill/content/components/lit-stories/icons/icons.lit-stories.ts +++ b/apps/browser/src/autofill/content/components/lit-stories/icons/icons.lit-stories.ts @@ -1,14 +1,12 @@ import { Meta, StoryObj } from "@storybook/web-components"; import { html } from "lit"; -import { Theme, ThemeTypes } from "@bitwarden/common/platform/enums/theme-type.enum"; +import { ThemeTypes } from "@bitwarden/common/platform/enums/theme-type.enum"; +import { IconProps } from "../../common-types"; import * as Icons from "../../icons"; -type Args = { - color?: string; - disabled?: boolean; - theme: Theme; +type Args = IconProps & { size: number; iconLink: URL; }; @@ -16,21 +14,19 @@ type Args = { export default { title: "Components/Icons", argTypes: { - iconLink: { control: "text" }, color: { control: "color" }, disabled: { control: "boolean" }, theme: { control: "select", options: [...Object.values(ThemeTypes)] }, size: { control: "number", min: 10, max: 100, step: 1 }, }, args: { - iconLink: new URL("https://bitwarden.com"), disabled: false, theme: ThemeTypes.Light, size: 50, }, } as Meta; -const Template = (args: Args, IconComponent: (props: Args) => ReturnType) => html` +const Template = (args: Args, IconComponent: (props: IconProps) => ReturnType) => html`
diff --git a/apps/browser/src/autofill/content/components/lit-stories/illustrations/illustrations.lit-stories.ts b/apps/browser/src/autofill/content/components/lit-stories/illustrations/illustrations.lit-stories.ts index 86d55f2f795..a64d6cc1aea 100644 --- a/apps/browser/src/autofill/content/components/lit-stories/illustrations/illustrations.lit-stories.ts +++ b/apps/browser/src/autofill/content/components/lit-stories/illustrations/illustrations.lit-stories.ts @@ -1,12 +1,12 @@ import { Meta, StoryObj } from "@storybook/web-components"; import { html } from "lit"; -import { Theme, ThemeTypes } from "@bitwarden/common/platform/enums/theme-type.enum"; +import { ThemeTypes } from "@bitwarden/common/platform/enums/theme-type.enum"; +import { IconProps } from "../../common-types"; import * as Illustrations from "../../illustrations"; -type Args = { - theme: Theme; +type Args = IconProps & { size: number; }; @@ -24,7 +24,7 @@ export default { const Template = ( args: Args, - IllustrationComponent: (props: Args) => ReturnType, + IllustrationComponent: (props: IconProps) => ReturnType, ) => html`
{ + // Replace first found match each iteration, in order + return builtString.replace(/\$[A-Z_]+\$/, substitution); + }, mockI18n[messageName] || ""); + + return resolvedString; + } + + return mockI18n[messageName]; +} diff --git a/apps/browser/src/autofill/content/components/lit-stories/notification/body.lit-stories.ts b/apps/browser/src/autofill/content/components/lit-stories/notification/body.lit-stories.ts index 13e2322a9f2..3f19c897b92 100644 --- a/apps/browser/src/autofill/content/components/lit-stories/notification/body.lit-stories.ts +++ b/apps/browser/src/autofill/content/components/lit-stories/notification/body.lit-stories.ts @@ -1,50 +1,27 @@ import { Meta, StoryObj } from "@storybook/web-components"; -import { Theme, ThemeTypes } from "@bitwarden/common/platform/enums/theme-type.enum"; -import { CipherType } from "@bitwarden/common/vault/enums"; -import { CipherRepromptType } from "@bitwarden/common/vault/enums/cipher-reprompt-type"; +import { ThemeTypes } from "@bitwarden/common/platform/enums/theme-type.enum"; -import { NotificationType } from "../../../../notification/abstractions/notification-bar"; -import { NotificationCipherData } from "../../cipher/types"; -import { NotificationBody } from "../../notification/body"; - -type Args = { - ciphers: NotificationCipherData[]; - i18n: { [key: string]: string }; - notificationType: NotificationType; - theme: Theme; - handleEditOrUpdateAction: (e: Event) => void; -}; +import { NotificationTypes } from "../../../../notification/abstractions/notification-bar"; +import { NotificationBody, NotificationBodyProps } from "../../notification/body"; +import { mockCiphers, mockI18n } from "../mock-data"; export default { title: "Components/Notifications/Body", argTypes: { - ciphers: { control: "object" }, theme: { control: "select", options: [...Object.values(ThemeTypes)] }, notificationType: { control: "select", - options: ["add", "change", "unlock", "fileless-import"], + options: [...Object.values(NotificationTypes)], }, + handleEditOrUpdateAction: { control: false }, }, args: { - ciphers: [ - { - id: "1", - name: "Example Cipher", - type: CipherType.Login, - favorite: false, - reprompt: CipherRepromptType.None, - icon: { - imageEnabled: true, - image: "", - fallbackImage: "https://example.com/fallback.png", - icon: "icon-class", - }, - login: { username: "user@example.com" }, - }, - ], + ciphers: mockCiphers, + notificationType: NotificationTypes.Change, theme: ThemeTypes.Light, - notificationType: "change", + handleEditOrUpdateAction: () => window.alert("clicked!"), + i18n: mockI18n, }, parameters: { design: { @@ -52,10 +29,10 @@ export default { url: "https://www.figma.com/design/LEhqLAcBPY8uDKRfU99n9W/Autofill-notification-redesign?node-id=217-6841&m=dev", }, }, -} as Meta; +} as Meta; -const Template = (args: Args) => NotificationBody({ ...args }); +const Template = (args: NotificationBodyProps) => NotificationBody({ ...args }); -export const Default: StoryObj = { +export const Default: StoryObj = { render: Template, }; diff --git a/apps/browser/src/autofill/content/components/lit-stories/notification/confirmation/body.lit-stories.ts b/apps/browser/src/autofill/content/components/lit-stories/notification/confirmation/body.lit-stories.ts index 4d9be06fd7e..4f392afea8e 100644 --- a/apps/browser/src/autofill/content/components/lit-stories/notification/confirmation/body.lit-stories.ts +++ b/apps/browser/src/autofill/content/components/lit-stories/notification/confirmation/body.lit-stories.ts @@ -11,6 +11,7 @@ export default { title: "Components/Notifications/Confirmation/Body", argTypes: { error: { control: "text" }, + buttonAria: { control: "text" }, buttonText: { control: "text" }, confirmationMessage: { control: "text" }, messageDetails: { control: "text" }, @@ -18,9 +19,12 @@ export default { }, args: { error: "", + buttonAria: "View", buttonText: "View", confirmationMessage: "[item name] updated in Bitwarden.", messageDetails: "You can view it in your vault.", + tasksAreComplete: false, + handleOpenVault: () => window.alert("Link was clicked!"), theme: ThemeTypes.Light, }, parameters: { diff --git a/apps/browser/src/autofill/content/components/lit-stories/notification/confirmation/container.lit-stories.ts b/apps/browser/src/autofill/content/components/lit-stories/notification/confirmation/container.lit-stories.ts index ec7194004d8..55c0a456732 100644 --- a/apps/browser/src/autofill/content/components/lit-stories/notification/confirmation/container.lit-stories.ts +++ b/apps/browser/src/autofill/content/components/lit-stories/notification/confirmation/container.lit-stories.ts @@ -3,10 +3,15 @@ import { Meta, StoryObj } from "@storybook/web-components"; import { ThemeTypes } from "@bitwarden/common/platform/enums"; import { NotificationTypes } from "../../../../../notification/abstractions/notification-bar"; +import { + getConfirmationHeaderMessage, + getNotificationTestId, +} from "../../../../../notification/bar"; import { NotificationConfirmationContainer, NotificationConfirmationContainerProps, } from "../../../notification/confirmation/container"; +import { mockI18n, mockCiphers, mockBrowserI18nGetMessage, mockTasks } from "../../mock-data"; export default { title: "Components/Notifications/Confirmation", @@ -17,27 +22,14 @@ export default { }, args: { error: "", - task: { - orgName: "Acme, Inc.", - remainingTasksCount: 0, - }, - handleCloseNotification: () => alert("Close notification action triggered"), - handleOpenTasks: () => alert("Open tasks action triggered"), - i18n: { - loginSaveSuccess: "Login saved", - loginUpdateSuccess: "Login updated", - loginUpdateTaskSuccessAdditional: - "Thank you for making your organization more secure. You have 3 more passwords to update.", - loginUpdateTaskSuccess: - "Great job! You took the steps to make you and your organization more secure.", - nextSecurityTaskAction: "Change next password", - saveFailure: "Error saving", - saveFailureDetails: "Oh no! We couldn't save this. Try entering the details manually.", - view: "View", - }, + task: mockTasks[0], + itemName: mockCiphers[0].name, type: NotificationTypes.Change, - username: "Acme, Inc. Login", theme: ThemeTypes.Light, + handleCloseNotification: () => alert("Close notification action triggered"), + handleOpenVault: () => alert("Open vault action triggered"), + handleOpenTasks: () => alert("Open tasks action triggered"), + i18n: mockI18n, }, parameters: { design: { @@ -47,9 +39,19 @@ export default { }, } as Meta; -const Template = (args: NotificationConfirmationContainerProps) => - NotificationConfirmationContainer({ ...args }); +const Template = (args: NotificationConfirmationContainerProps) => { + const headerMessage = getConfirmationHeaderMessage(args.i18n, args.type, args.error); + const notificationTestId = getNotificationTestId(args.type, true); + return NotificationConfirmationContainer({ ...args, headerMessage, notificationTestId }); +}; export const Default: StoryObj = { render: Template, }; + +window.chrome = { + ...window.chrome, + i18n: { + getMessage: mockBrowserI18nGetMessage, + }, +} as typeof chrome; diff --git a/apps/browser/src/autofill/content/components/lit-stories/notification/confirmation/footer.lit-stories.ts b/apps/browser/src/autofill/content/components/lit-stories/notification/confirmation/footer.lit-stories.ts index 953fb90d067..713b405528e 100644 --- a/apps/browser/src/autofill/content/components/lit-stories/notification/confirmation/footer.lit-stories.ts +++ b/apps/browser/src/autofill/content/components/lit-stories/notification/confirmation/footer.lit-stories.ts @@ -7,6 +7,7 @@ import { NotificationConfirmationFooter, NotificationConfirmationFooterProps, } from "../../../notification/confirmation/footer"; +import { mockI18n } from "../../mock-data"; export default { title: "Components/Notifications/Confirmation/Footer", @@ -14,11 +15,9 @@ export default { theme: { control: "select", options: [...Object.values(ThemeTypes)] }, }, args: { - handleButtonClick: () => alert("Action button triggered"), - i18n: { - nextSecurityTaskAction: "Change next password", - }, theme: ThemeTypes.Light, + handleButtonClick: () => alert("Action button triggered"), + i18n: mockI18n, }, parameters: { design: { diff --git a/apps/browser/src/autofill/content/components/lit-stories/notification/confirmation/message.lit-stories.ts b/apps/browser/src/autofill/content/components/lit-stories/notification/confirmation/message.lit-stories.ts index f01503b331f..c8d19e91da9 100644 --- a/apps/browser/src/autofill/content/components/lit-stories/notification/confirmation/message.lit-stories.ts +++ b/apps/browser/src/autofill/content/components/lit-stories/notification/confirmation/message.lit-stories.ts @@ -10,6 +10,7 @@ import { export default { title: "Components/Notifications/Confirmation/Message", argTypes: { + buttonAria: { control: "text" }, buttonText: { control: "text" }, message: { control: "text" }, messageDetails: { control: "text" }, @@ -19,6 +20,7 @@ export default { buttonText: "View", message: "[item name] updated in Bitwarden.", messageDetails: "It was added to your vault.", + handleClick: () => window.alert("link was clicked!"), theme: ThemeTypes.Light, }, parameters: { diff --git a/apps/browser/src/autofill/content/components/lit-stories/notification/container.lit-stories.ts b/apps/browser/src/autofill/content/components/lit-stories/notification/container.lit-stories.ts index 351c971ec0e..d09bc76c834 100644 --- a/apps/browser/src/autofill/content/components/lit-stories/notification/container.lit-stories.ts +++ b/apps/browser/src/autofill/content/components/lit-stories/notification/container.lit-stories.ts @@ -5,7 +5,9 @@ import { CipherType } from "@bitwarden/common/vault/enums"; import { CipherRepromptType } from "@bitwarden/common/vault/enums/cipher-reprompt-type"; import { NotificationTypes } from "../../../../notification/abstractions/notification-bar"; +import { getNotificationHeaderMessage, getNotificationTestId } from "../../../../notification/bar"; import { NotificationContainer, NotificationContainerProps } from "../../notification/container"; +import { mockBrowserI18nGetMessage, mockI18n } from "../mock-data"; export default { title: "Components/Notifications", @@ -32,19 +34,10 @@ export default { login: { username: "user@example.com" }, }, ], - i18n: { - loginSaveSuccess: "Login saved", - loginUpdateSuccess: "Login updated", - saveAction: "Save", - saveAsNewLoginAction: "Save as new login", - saveFailure: "Error saving", - saveFailureDetails: "Oh no! We couldn't save this. Try entering the details manually.", - updateLoginPrompt: "Update existing login?", - view: "View", - }, type: NotificationTypes.Change, username: "mockUsername", theme: ThemeTypes.Light, + i18n: mockI18n, }, parameters: { design: { @@ -54,8 +47,19 @@ export default { }, } as Meta; -const Template = (args: NotificationContainerProps) => NotificationContainer({ ...args }); +const Template = (args: NotificationContainerProps) => { + const headerMessage = getNotificationHeaderMessage(args.i18n, args.type); + const notificationTestId = getNotificationTestId(args.type); + return NotificationContainer({ ...args, headerMessage, notificationTestId }); +}; export const Default: StoryObj = { render: Template, }; + +window.chrome = { + ...window.chrome, + i18n: { + getMessage: mockBrowserI18nGetMessage, + }, +} as typeof chrome; diff --git a/apps/browser/src/autofill/content/components/lit-stories/notification/footer.lit-stories.ts b/apps/browser/src/autofill/content/components/lit-stories/notification/footer.lit-stories.ts index 29d9955ec64..bc5b864d1ca 100644 --- a/apps/browser/src/autofill/content/components/lit-stories/notification/footer.lit-stories.ts +++ b/apps/browser/src/autofill/content/components/lit-stories/notification/footer.lit-stories.ts @@ -3,28 +3,27 @@ import { html } from "lit"; import { ThemeTypes } from "@bitwarden/common/platform/enums/theme-type.enum"; +import { NotificationTypes } from "../../../../notification/abstractions/notification-bar"; import { NotificationFooter, NotificationFooterProps } from "../../notification/footer"; -import { mockFolderData, mockOrganizationData } from "../mock-data"; +import { mockCollections, mockI18n, mockFolders, mockOrganizations } from "../mock-data"; export default { title: "Components/Notifications/Footer", argTypes: { notificationType: { control: "select", - options: ["add", "change", "unlock", "fileless-import"], + options: [...Object.values(NotificationTypes)], }, theme: { control: "select", options: [...Object.values(ThemeTypes)] }, }, args: { - folders: mockFolderData, - i18n: { - saveAction: "Save", - saveAsNewLoginAction: "Save as New Login", - }, - notificationType: "add", - organizations: mockOrganizationData, + collections: mockCollections, + folders: mockFolders, + notificationType: NotificationTypes.Add, + organizations: mockOrganizations, theme: ThemeTypes.Light, handleSaveAction: () => alert("Save action triggered"), + i18n: mockI18n, }, parameters: { design: { diff --git a/apps/browser/src/autofill/content/components/lit-stories/notification/header.lit-stories.ts b/apps/browser/src/autofill/content/components/lit-stories/notification/header.lit-stories.ts index 0857c99130e..ecc56bd5bd9 100644 --- a/apps/browser/src/autofill/content/components/lit-stories/notification/header.lit-stories.ts +++ b/apps/browser/src/autofill/content/components/lit-stories/notification/header.lit-stories.ts @@ -1,15 +1,10 @@ import { Meta, StoryObj } from "@storybook/web-components"; +import { html } from "lit"; -import { Theme, ThemeTypes } from "@bitwarden/common/platform/enums/theme-type.enum"; +import { ThemeTypes } from "@bitwarden/common/platform/enums/theme-type.enum"; -import { NotificationHeader } from "../../notification/header"; - -type Args = { - message: string; - standalone: boolean; - theme: Theme; - handleCloseNotification: (e: Event) => void; -}; +import { NotificationHeader, NotificationHeaderProps } from "../../notification/header"; +import { mockI18n } from "../mock-data"; export default { title: "Components/Notifications/Header", @@ -23,6 +18,7 @@ export default { standalone: true, theme: ThemeTypes.Light, handleCloseNotification: () => alert("Close Clicked"), + i18n: mockI18n, }, parameters: { design: { @@ -30,10 +26,11 @@ export default { url: "https://www.figma.com/design/LEhqLAcBPY8uDKRfU99n9W/Autofill-notification-redesign?node-id=32-3461&m=dev", }, }, -} as Meta; +} as Meta; -const Template = (args: Args) => NotificationHeader({ ...args }); +const Template = (args: NotificationHeaderProps) => + html`
${NotificationHeader({ ...args })}
`; -export const Default: StoryObj = { +export const Default: StoryObj = { render: Template, }; diff --git a/apps/browser/src/autofill/content/components/lit-stories/options-selection/option-selection.lit-stories.ts b/apps/browser/src/autofill/content/components/lit-stories/options-selection/option-selection.lit-stories.ts index 2e8b1653546..e2684be1ed3 100644 --- a/apps/browser/src/autofill/content/components/lit-stories/options-selection/option-selection.lit-stories.ts +++ b/apps/browser/src/autofill/content/components/lit-stories/options-selection/option-selection.lit-stories.ts @@ -7,15 +7,16 @@ import { Option } from "../../common-types"; import { themes } from "../../constants/styles"; import { User, Business } from "../../icons"; import "../../option-selection/option-selection"; -import { mockOrganizationData } from "../mock-data"; +import { mockOrganizations } from "../mock-data"; const mockOptions: Option[] = [ { icon: User, text: "My Vault", value: "0" }, - ...mockOrganizationData.map(({ id, name }) => ({ icon: Business, text: name, value: id })), + ...mockOrganizations.map(({ id, name }) => ({ icon: Business, text: name, value: id })), ]; type ComponentProps = { disabled?: boolean; + id: string; label?: string; options: Option[]; theme: Theme; @@ -31,16 +32,18 @@ export default { }, args: { disabled: false, + id: "example-id", label: undefined, options: mockOptions, theme: ThemeTypes.Light, }, } as Meta; -const BaseComponent = ({ disabled, label, options, theme }: ComponentProps) => { +const BaseComponent = ({ disabled, id, label, options, theme }: ComponentProps) => { return html` void; - theme: Theme; -}; +import { ActionRow, ActionRowProps } from "../../rows/action-row"; export default { title: "Components/Rows/Action Row", @@ -22,10 +16,10 @@ export default { theme: ThemeTypes.Light, handleAction: () => alert("Action triggered"), }, -} as Meta; +} as Meta; -const Template = (args: Args) => ActionRow({ ...args }); +const Template = (args: ActionRowProps) => ActionRow({ ...args }); -export const Default: StoryObj = { +export const Default: StoryObj = { render: Template, }; diff --git a/apps/browser/src/autofill/content/components/lit-stories/rows/button-row.lit-stories.ts b/apps/browser/src/autofill/content/components/lit-stories/rows/button-row.lit-stories.ts index 83b498df7cb..343f36d5e11 100644 --- a/apps/browser/src/autofill/content/components/lit-stories/rows/button-row.lit-stories.ts +++ b/apps/browser/src/autofill/content/components/lit-stories/rows/button-row.lit-stories.ts @@ -4,6 +4,7 @@ import { ThemeTypes } from "@bitwarden/common/platform/enums/theme-type.enum"; import { themes } from "../../constants/styles"; import { ButtonRow, ButtonRowProps } from "../../rows/button-row"; +import { mockBrowserI18nGetMessage } from "../mock-data"; export default { title: "Components/Rows/Button Row", @@ -15,6 +16,49 @@ export default { window.alert("Button clicked!"); }, }, + selectButtons: [ + { + id: "select-1", + label: "select 1", + options: [ + { + text: "item 1", + value: 1, + }, + { + default: true, + text: "item 2", + value: 2, + }, + { + text: "item 3", + value: 3, + }, + ], + }, + { + id: "select-2", + label: "select 2", + options: [ + { + text: "item a", + value: "a", + }, + { + text: "item b", + value: "b", + }, + { + text: "item c", + value: "c", + }, + { + text: "item d", + value: "d", + }, + ], + }, + ], }, } as Meta; @@ -51,3 +95,10 @@ export const Dark: StoryObj = { }, }, }; + +window.chrome = { + ...window.chrome, + i18n: { + getMessage: mockBrowserI18nGetMessage, + }, +} as typeof chrome; diff --git a/apps/browser/src/autofill/content/components/lit-stories/rows/cipher-item-row.lit-stories.ts b/apps/browser/src/autofill/content/components/lit-stories/rows/cipher-item-row.lit-stories.ts new file mode 100644 index 00000000000..59c38c56745 --- /dev/null +++ b/apps/browser/src/autofill/content/components/lit-stories/rows/cipher-item-row.lit-stories.ts @@ -0,0 +1,32 @@ +import { Meta, StoryObj } from "@storybook/web-components"; + +import { ThemeTypes } from "@bitwarden/common/platform/enums/theme-type.enum"; + +import { NotificationTypes } from "../../../../notification/abstractions/notification-bar"; +import { CipherItemRow, CipherItemRowProps } from "../../rows/cipher-item-row"; +import { mockCiphers, mockI18n } from "../mock-data"; + +export default { + title: "Components/Rows/Cipher Item Row", + argTypes: { + theme: { control: "select", options: [...Object.values(ThemeTypes)] }, + notificationType: { + control: "select", + options: [...Object.values(NotificationTypes)], + }, + handleAction: { control: false }, + }, + args: { + cipher: mockCiphers[0], + i18n: mockI18n, + notificationType: NotificationTypes.Change, + theme: ThemeTypes.Light, + handleAction: () => window.alert("clicked!"), + }, +} as Meta; + +const Template = (props: CipherItemRowProps) => CipherItemRow({ ...props }); + +export const Default: StoryObj = { + render: Template, +}; diff --git a/apps/browser/src/autofill/content/components/lit-stories/rows/item-row.lit-stories.ts b/apps/browser/src/autofill/content/components/lit-stories/rows/item-row.lit-stories.ts deleted file mode 100644 index fbb65201986..00000000000 --- a/apps/browser/src/autofill/content/components/lit-stories/rows/item-row.lit-stories.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Meta, StoryObj } from "@storybook/web-components"; -import { TemplateResult } from "lit"; - -import { Theme, ThemeTypes } from "@bitwarden/common/platform/enums/theme-type.enum"; - -import { ItemRow } from "../../rows/item-row"; - -type Args = { - theme: Theme; - children: TemplateResult | TemplateResult[]; -}; - -export default { - title: "Components/Rows/Item Row", - argTypes: { - theme: { control: "select", options: [...Object.values(ThemeTypes)] }, - children: { control: "object" }, - }, - args: { - theme: ThemeTypes.Light, - }, -} as Meta; - -const Template = (args: Args) => ItemRow({ ...args }); - -export const Default: StoryObj = { - render: Template, -}; diff --git a/apps/browser/src/autofill/content/components/notification/body.ts b/apps/browser/src/autofill/content/components/notification/body.ts index cc0fa359303..b1ce7cdba63 100644 --- a/apps/browser/src/autofill/content/components/notification/body.ts +++ b/apps/browser/src/autofill/content/components/notification/body.ts @@ -4,10 +4,10 @@ import { html } from "lit"; import { Theme, ThemeTypes } from "@bitwarden/common/platform/enums"; import { NotificationType } from "../../../notification/abstractions/notification-bar"; -import { CipherItem } from "../cipher"; import { NotificationCipherData } from "../cipher/types"; +import { I18n } from "../common-types"; import { scrollbarStyles, spacing, themes, typography } from "../constants/styles"; -import { ItemRow } from "../rows/item-row"; +import { CipherItemRow } from "../rows/cipher-item-row"; export const componentClassPrefix = "notification-body"; @@ -15,35 +15,33 @@ const { css } = createEmotion({ key: componentClassPrefix, }); +export type NotificationBodyProps = { + ciphers?: NotificationCipherData[]; + i18n: I18n; + notificationType?: NotificationType; + theme: Theme; + handleEditOrUpdateAction: (e: Event) => void; +}; + export function NotificationBody({ ciphers = [], i18n, notificationType, theme = ThemeTypes.Light, handleEditOrUpdateAction, -}: { - ciphers?: NotificationCipherData[]; - customClasses?: string[]; - i18n: { [key: string]: string }; - notificationType?: NotificationType; - theme: Theme; - handleEditOrUpdateAction: (e: Event) => void; -}) { +}: NotificationBodyProps) { // @TODO get client vendor from context const isSafari = false; return html`
${ciphers.map((cipher) => - ItemRow({ + CipherItemRow({ + cipher, theme, - children: CipherItem({ - cipher, - i18n, - notificationType, - theme, - handleAction: handleEditOrUpdateAction, - }), + i18n, + notificationType, + handleAction: handleEditOrUpdateAction, }), )}
diff --git a/apps/browser/src/autofill/content/components/notification/button-row.ts b/apps/browser/src/autofill/content/components/notification/button-row.ts index f9cd9ed5e7a..470147cb469 100644 --- a/apps/browser/src/autofill/content/components/notification/button-row.ts +++ b/apps/browser/src/autofill/content/components/notification/button-row.ts @@ -3,7 +3,7 @@ import { html } from "lit"; import { ProductTierType } from "@bitwarden/common/billing/enums"; import { Theme } from "@bitwarden/common/platform/enums"; -import { Option, OrgView, FolderView, CollectionView } from "../common-types"; +import { Option, OrgView, FolderView, I18n, CollectionView } from "../common-types"; import { Business, Family, Folder, User, CollectionShared } from "../icons"; import { ButtonRow } from "../rows/button-row"; import { selectedCollection as selectedCollectionSignal } from "../signals/selected-collection"; @@ -30,7 +30,7 @@ const defaultNoneSelectValue = "0"; export type NotificationButtonRowProps = { collections?: CollectionView[]; folders?: FolderView[]; - i18n: { [key: string]: string }; + i18n: I18n; organizations?: OrgView[]; primaryButton: { text: string; @@ -148,7 +148,7 @@ export function NotificationButtonRow({ ? [ { id: "collection", - label: "Collection", // @TODO localize + label: i18n.collection, options: collectionOptions, selectedSignal: selectedCollectionSignal, }, diff --git a/apps/browser/src/autofill/content/components/notification/confirmation/body.ts b/apps/browser/src/autofill/content/components/notification/confirmation/body.ts index 0508991c5da..6bb94cab2c6 100644 --- a/apps/browser/src/autofill/content/components/notification/confirmation/body.ts +++ b/apps/browser/src/autofill/content/components/notification/confirmation/body.ts @@ -3,7 +3,7 @@ import { html, nothing } from "lit"; import { Theme } from "@bitwarden/common/platform/enums"; -import { themes } from "../../constants/styles"; +import { spacing, themes } from "../../constants/styles"; import { Celebrate, Keyhole, Warning } from "../../illustrations"; import { NotificationConfirmationMessage } from "./message"; @@ -15,27 +15,29 @@ const { css } = createEmotion({ }); export type NotificationConfirmationBodyProps = { + buttonAria: string; buttonText: string; - itemName: string; confirmationMessage: string; error?: string; + itemName?: string; messageDetails?: string; tasksAreComplete?: boolean; theme: Theme; - handleOpenVault: () => void; + handleOpenVault: (e: Event) => void; }; export function NotificationConfirmationBody({ + buttonAria, buttonText, - itemName, confirmationMessage, error, + itemName, messageDetails, tasksAreComplete, theme, handleOpenVault, }: NotificationConfirmationBodyProps) { - const IconComponent = tasksAreComplete ? Keyhole : !error ? Celebrate : Warning; + const IconComponent = error ? Warning : tasksAreComplete ? Celebrate : Keyhole; const showConfirmationMessage = confirmationMessage || buttonText || messageDetails; @@ -44,8 +46,9 @@ export function NotificationConfirmationBody({
${IconComponent({ theme })}
${showConfirmationMessage ? NotificationConfirmationMessage({ + buttonAria, buttonText, - itemName, + itemName: error ? undefined : itemName, message: confirmationMessage, messageDetails, theme, @@ -59,11 +62,11 @@ export function NotificationConfirmationBody({ const iconContainerStyles = (error?: string) => css` > svg { width: ${!error ? "50px" : "40px"}; - height: fit-content; + height: auto; } `; const notificationConfirmationBodyStyles = ({ theme }: { theme: Theme }) => css` - gap: 16px; + gap: ${spacing[4]}; display: flex; align-items: center; justify-content: flex-start; diff --git a/apps/browser/src/autofill/content/components/notification/confirmation/container.ts b/apps/browser/src/autofill/content/components/notification/confirmation/container.ts index 5cc977cf4cb..b6f76ba8330 100644 --- a/apps/browser/src/autofill/content/components/notification/confirmation/container.ts +++ b/apps/browser/src/autofill/content/components/notification/confirmation/container.ts @@ -9,6 +9,7 @@ import { NotificationType, NotificationTypes, } from "../../../../notification/abstractions/notification-bar"; +import { I18n } from "../../common-types"; import { themes, spacing } from "../../constants/styles"; import { NotificationHeader, @@ -20,12 +21,14 @@ import { NotificationConfirmationFooter } from "./footer"; export type NotificationConfirmationContainerProps = NotificationBarIframeInitData & { handleCloseNotification: (e: Event) => void; - handleOpenVault: () => void; + handleOpenVault: (e: Event) => void; handleOpenTasks: (e: Event) => void; } & { error?: string; - i18n: { [key: string]: string }; + headerMessage?: string; + i18n: I18n; itemName: string; + notificationTestId: string; task?: NotificationTaskInfo; type: NotificationType; }; @@ -35,21 +38,25 @@ export function NotificationConfirmationContainer({ handleCloseNotification, handleOpenVault, handleOpenTasks, + headerMessage, i18n, itemName, + notificationTestId, task, theme = ThemeTypes.Light, type, }: NotificationConfirmationContainerProps) { - const headerMessage = getHeaderMessage(i18n, type, error); - const confirmationMessage = getConfirmationMessage(i18n, itemName, type, error); + const confirmationMessage = getConfirmationMessage(i18n, type, error); const buttonText = error ? i18n.newItem : i18n.view; + const buttonAria = error + ? i18n.notificationNewItemAria + : chrome.i18n.getMessage("notificationViewAria", [itemName]); let messageDetails: string | undefined; let remainingTasksCount: number | undefined; - let tasksAreComplete: boolean = false; + let tasksAreComplete: boolean = true; - if (task) { + if (task && !error) { remainingTasksCount = task.remainingTasksCount || 0; tasksAreComplete = remainingTasksCount === 0; @@ -63,22 +70,25 @@ export function NotificationConfirmationContainer({ } return html` -
+
${NotificationHeader({ handleCloseNotification, + i18n, message: headerMessage, theme, })} ${NotificationConfirmationBody({ + buttonAria, buttonText, - itemName, confirmationMessage, - tasksAreComplete, + error, + itemName, messageDetails, + tasksAreComplete, theme, handleOpenVault, })} - ${remainingTasksCount + ${!error && remainingTasksCount ? NotificationConfirmationFooter({ i18n, theme, @@ -105,38 +115,16 @@ const notificationContainerStyles = (theme: Theme) => css` } `; -function getConfirmationMessage( - i18n: { [key: string]: string }, - itemName: string, - type?: NotificationType, - error?: string, -) { - const loginSaveConfirmation = chrome.i18n.getMessage("loginSaveConfirmation", [itemName]); - const loginUpdatedConfirmation = chrome.i18n.getMessage("loginUpdatedConfirmation", [itemName]); - +function getConfirmationMessage(i18n: I18n, type?: NotificationType, error?: string) { if (error) { return i18n.saveFailureDetails; } - return type === "add" ? loginSaveConfirmation : loginUpdatedConfirmation; -} -function getHeaderMessage( - i18n: { [key: string]: string }, - type?: NotificationType, - error?: string, -) { - if (error) { - return i18n.saveFailure; - } - - switch (type) { - case NotificationTypes.Add: - return i18n.loginSaveSuccess; - case NotificationTypes.Change: - return i18n.loginUpdateSuccess; - case NotificationTypes.Unlock: - return ""; - default: - return undefined; - } + /* @TODO This partial string return and later concatenation with the cipher name is needed + * to handle cipher name overflow cases, but is risky for i18n concerns. Fix concatenation + * with cipher name overflow when a tag replacement solution is available. + */ + return type === NotificationTypes.Add + ? i18n.notificationLoginSaveConfirmation + : i18n.notificationLoginUpdatedConfirmation; } diff --git a/apps/browser/src/autofill/content/components/notification/confirmation/footer.ts b/apps/browser/src/autofill/content/components/notification/confirmation/footer.ts index e245d22c8e8..ba01efe5a53 100644 --- a/apps/browser/src/autofill/content/components/notification/confirmation/footer.ts +++ b/apps/browser/src/autofill/content/components/notification/confirmation/footer.ts @@ -4,11 +4,12 @@ import { html } from "lit"; import { Theme } from "@bitwarden/common/platform/enums"; import { ActionButton } from "../../buttons/action-button"; +import { I18n } from "../../common-types"; import { spacing, themes } from "../../constants/styles"; import { ExternalLink } from "../../icons"; export type NotificationConfirmationFooterProps = { - i18n: { [key: string]: string }; + i18n: I18n; theme: Theme; handleButtonClick: (event: Event) => void; }; diff --git a/apps/browser/src/autofill/content/components/notification/confirmation/message.ts b/apps/browser/src/autofill/content/components/notification/confirmation/message.ts index 3707e628370..7f15d882297 100644 --- a/apps/browser/src/autofill/content/components/notification/confirmation/message.ts +++ b/apps/browser/src/autofill/content/components/notification/confirmation/message.ts @@ -3,18 +3,20 @@ import { html, nothing } from "lit"; import { Theme } from "@bitwarden/common/platform/enums"; -import { themes, typography } from "../../constants/styles"; +import { spacing, themes, typography } from "../../constants/styles"; export type NotificationConfirmationMessageProps = { + buttonAria?: string; buttonText?: string; - itemName: string; + itemName?: string; message?: string; messageDetails?: string; - handleClick: () => void; + handleClick: (e: Event) => void; theme: Theme; }; export function NotificationConfirmationMessage({ + buttonAria, buttonText, itemName, message, @@ -22,33 +24,39 @@ export function NotificationConfirmationMessage({ handleClick, theme, }: NotificationConfirmationMessageProps) { - const buttonAria = chrome.i18n.getMessage("notificationViewAria", [itemName]); - return html` -
+
${message || buttonText ? html` - - ${message || nothing} - ${buttonText + ` : nothing} ${messageDetails @@ -58,13 +66,25 @@ export function NotificationConfirmationMessage({ `; } +const containerStyles = css` + display: flex; + flex-direction: column; + gap: ${spacing[1]}; + width: 100%; +`; + +const singleLineWrapperStyles = css` + display: inline; + white-space: normal; + word-break: break-word; +`; + const baseTextStyles = css` - flex-grow: 1; overflow-x: hidden; text-align: left; text-overflow: ellipsis; line-height: 24px; - font-family: "DM Sans", sans-serif; + font-family: Roboto, sans-serif; font-size: 16px; `; @@ -73,6 +93,22 @@ const notificationConfirmationMessageStyles = (theme: Theme) => css` color: ${themes[theme].text.main}; font-weight: 400; + white-space: normal; + word-break: break-word; + display: inline; +`; + +const itemNameStyles = (theme: Theme) => css` + ${baseTextStyles} + + color: ${themes[theme].text.main}; + font-weight: 400; + white-space: nowrap; + max-width: 300px; + overflow: hidden; + text-overflow: ellipsis; + display: inline-block; + vertical-align: bottom; `; const notificationConfirmationButtonTextStyles = (theme: Theme) => css` diff --git a/apps/browser/src/autofill/content/components/notification/container.ts b/apps/browser/src/autofill/content/components/notification/container.ts index b21a05696c1..cc7f0fc72c0 100644 --- a/apps/browser/src/autofill/content/components/notification/container.ts +++ b/apps/browser/src/autofill/content/components/notification/container.ts @@ -1,5 +1,5 @@ import { css } from "@emotion/css"; -import { html } from "lit"; +import { html, nothing } from "lit"; import { Theme, ThemeTypes } from "@bitwarden/common/platform/enums"; @@ -9,7 +9,7 @@ import { NotificationType, } from "../../../notification/abstractions/notification-bar"; import { NotificationCipherData } from "../cipher/types"; -import { CollectionView, FolderView, OrgView } from "../common-types"; +import { CollectionView, FolderView, I18n, OrgView } from "../common-types"; import { themes, spacing } from "../constants/styles"; import { NotificationBody, componentClassPrefix as notificationBodyClassPrefix } from "./body"; @@ -27,9 +27,11 @@ export type NotificationContainerProps = NotificationBarIframeInitData & { ciphers?: NotificationCipherData[]; collections?: CollectionView[]; folders?: FolderView[]; - i18n: { [key: string]: string }; + headerMessage?: string; + i18n: I18n; organizations?: OrgView[]; personalVaultIsAllowed?: boolean; + notificationTestId: string; type: NotificationType; // @TODO typing override for generic `NotificationBarIframeInitData.type` }; @@ -40,21 +42,22 @@ export function NotificationContainer({ ciphers, collections, folders, + headerMessage, i18n, organizations, personalVaultIsAllowed = true, + notificationTestId, theme = ThemeTypes.Light, type, }: NotificationContainerProps) { - const headerMessage = getHeaderMessage(i18n, type); - const showBody = true; + const showBody = type !== NotificationTypes.Unlock; return html` -
+
${NotificationHeader({ handleCloseNotification, + i18n, message: headerMessage, - standalone: showBody, theme, })} ${showBody @@ -65,7 +68,7 @@ export function NotificationContainer({ theme, i18n, }) - : null} + : nothing} ${NotificationFooter({ handleSaveAction, collections, @@ -94,20 +97,7 @@ const notificationContainerStyles = (theme: Theme) => css` } [class*="${notificationBodyClassPrefix}-"] { - margin: ${spacing["3"]} 0 ${spacing["1.5"]} ${spacing["3"]}; + margin: ${spacing["3"]} 0 0 ${spacing["3"]}; padding-right: ${spacing["3"]}; } `; - -function getHeaderMessage(i18n: { [key: string]: string }, type?: NotificationType) { - switch (type) { - case NotificationTypes.Add: - return i18n.saveLogin; - case NotificationTypes.Change: - return i18n.updateLogin; - case NotificationTypes.Unlock: - return ""; - default: - return undefined; - } -} diff --git a/apps/browser/src/autofill/content/components/notification/footer.ts b/apps/browser/src/autofill/content/components/notification/footer.ts index baa1a2ecffc..b47dd5cc094 100644 --- a/apps/browser/src/autofill/content/components/notification/footer.ts +++ b/apps/browser/src/autofill/content/components/notification/footer.ts @@ -7,15 +7,15 @@ import { NotificationType, NotificationTypes, } from "../../../notification/abstractions/notification-bar"; -import { OrgView, FolderView, CollectionView } from "../common-types"; -import { spacing, themes } from "../constants/styles"; +import { OrgView, FolderView, I18n, CollectionView } from "../common-types"; +import { spacing } from "../constants/styles"; import { NotificationButtonRow } from "./button-row"; export type NotificationFooterProps = { collections?: CollectionView[]; folders?: FolderView[]; - i18n: { [key: string]: string }; + i18n: I18n; notificationType?: NotificationType; organizations?: OrgView[]; personalVaultIsAllowed: boolean; @@ -34,10 +34,16 @@ export function NotificationFooter({ handleSaveAction, }: NotificationFooterProps) { const isChangeNotification = notificationType === NotificationTypes.Change; - const primaryButtonText = i18n.saveAction; + const isUnlockNotification = notificationType === NotificationTypes.Unlock; + + let primaryButtonText = i18n.saveAction; + + if (isUnlockNotification) { + primaryButtonText = i18n.notificationUnlock; + } return html` -
+
${!isChangeNotification ? NotificationButtonRow({ collections, @@ -56,13 +62,16 @@ export function NotificationFooter({ `; } -const notificationFooterStyles = ({ theme }: { theme: Theme }) => css` +const notificationFooterStyles = ({ + isChangeNotification, +}: { + isChangeNotification: boolean; +}) => css` display: flex; - background-color: ${themes[theme].background.alt}; - padding: 0 ${spacing[3]} ${spacing[3]} ${spacing[3]}; + padding: ${spacing[2]} ${spacing[4]} ${isChangeNotification ? spacing[1] : spacing[4]} + ${spacing[4]}; :last-child { border-radius: 0 0 ${spacing["4"]} ${spacing["4"]}; - padding-bottom: ${spacing[4]}; } `; diff --git a/apps/browser/src/autofill/content/components/notification/header-message.ts b/apps/browser/src/autofill/content/components/notification/header-message.ts index ccfa58b8970..47fe8cd2828 100644 --- a/apps/browser/src/autofill/content/components/notification/header-message.ts +++ b/apps/browser/src/autofill/content/components/notification/header-message.ts @@ -19,7 +19,7 @@ const notificationHeaderMessageStyles = (theme: Theme) => css` line-height: 28px; white-space: nowrap; color: ${themes[theme].text.main}; - font-family: "DM Sans", sans-serif; + font-family: Roboto, sans-serif; font-size: 18px; font-weight: 600; `; diff --git a/apps/browser/src/autofill/content/components/notification/header.ts b/apps/browser/src/autofill/content/components/notification/header.ts index d6cedf6a85a..3d657b77ecd 100644 --- a/apps/browser/src/autofill/content/components/notification/header.ts +++ b/apps/browser/src/autofill/content/components/notification/header.ts @@ -4,7 +4,8 @@ import { html } from "lit"; import { Theme, ThemeTypes } from "@bitwarden/common/platform/enums"; import { CloseButton } from "../buttons/close-button"; -import { themes } from "../constants/styles"; +import { I18n } from "../common-types"; +import { spacing, themes } from "../constants/styles"; import { BrandIconContainer } from "../icons/brand-icon-container"; import { NotificationHeaderMessage } from "./header-message"; @@ -15,17 +16,21 @@ const { css } = createEmotion({ key: componentClassPrefix, }); -export function NotificationHeader({ - message, - standalone = false, - theme = ThemeTypes.Light, - handleCloseNotification, -}: { +export type NotificationHeaderProps = { + i18n: I18n; message?: string; standalone?: boolean; theme: Theme; handleCloseNotification: (e: Event) => void; -}) { +}; + +export function NotificationHeader({ + i18n, + message, + standalone = false, + theme = ThemeTypes.Light, + handleCloseNotification, +}: NotificationHeaderProps) { const showIcon = true; const isDismissable = true; @@ -33,7 +38,7 @@ export function NotificationHeader({
${showIcon ? BrandIconContainer({ theme }) : null} ${message ? NotificationHeaderMessage({ message, theme }) : null} - ${isDismissable ? CloseButton({ handleCloseNotification, theme }) : null} + ${isDismissable ? CloseButton({ handleCloseNotification, i18n, theme }) : null}
`; } @@ -45,7 +50,7 @@ const notificationHeaderStyles = ({ standalone: boolean; theme: Theme; }) => css` - gap: 8px; + gap: ${spacing[2]}; display: flex; align-items: center; justify-content: flex-start; @@ -54,8 +59,8 @@ const notificationHeaderStyles = ({ white-space: nowrap; ${standalone - ? css` + ? css`` + : css` border-bottom: 0.5px solid ${themes[theme].secondary["300"]}; - ` - : css``} + `} `; diff --git a/apps/browser/src/autofill/content/components/option-selection/option-item.ts b/apps/browser/src/autofill/content/components/option-selection/option-item.ts index e8a293e2c3f..6af6a2d6538 100644 --- a/apps/browser/src/autofill/content/components/option-selection/option-item.ts +++ b/apps/browser/src/autofill/content/components/option-selection/option-item.ts @@ -12,16 +12,22 @@ const { css } = createEmotion({ key: optionItemTagName, }); -export function OptionItem({ - icon, - text, - value, - theme, - handleSelection, -}: Option & { +export type OptionItemProps = Option & { + id: string; + contextLabel?: string; theme: Theme; handleSelection: () => void; -}) { +}; + +export function OptionItem({ + contextLabel, + id, + icon, + text, + theme, + value, + handleSelection, +}: OptionItemProps) { const handleSelectionKeyUpProxy = (event: KeyboardEvent) => { const listenedForKeys = new Set(["Enter", "Space"]); if (listenedForKeys.has(event.code) && event.target instanceof Element) { @@ -33,12 +39,19 @@ export function OptionItem({ const iconProps: IconProps = { color: themes[theme].text.main, theme }; const itemIcon = icon?.(iconProps); + const ariaLabel = + contextLabel && text + ? chrome.i18n.getMessage("selectItemAriaLabel", [contextLabel, text]) + : text; return html`
diff --git a/apps/browser/src/autofill/content/components/option-selection/option-items.ts b/apps/browser/src/autofill/content/components/option-selection/option-items.ts index b87eea2a3a5..ceb72905357 100644 --- a/apps/browser/src/autofill/content/components/option-selection/option-items.ts +++ b/apps/browser/src/autofill/content/components/option-selection/option-items.ts @@ -14,34 +14,63 @@ const { css } = createEmotion({ key: optionItemsTagName, }); -export function OptionItems({ - theme, - topOffset, - label, - options, - handleOptionSelection, -}: { +export type OptionItemsProps = { + id: string; theme: Theme; topOffset: number; label?: string; options: Option[]; handleOptionSelection: (selectedOption: Option) => void; -}) { +}; + +export function OptionItems({ + id, + theme, + topOffset, + label, + options, + handleOptionSelection, +}: OptionItemsProps) { // @TODO get client vendor from context const isSafari = false; return html` -
+
handleMenuKeyUp(e)} + > ${label ? html`
${label}
` : nothing}
${options.map((option) => - OptionItem({ ...option, theme, handleSelection: () => handleOptionSelection(option) }), + OptionItem({ + id, + ...option, + theme, + contextLabel: label, + handleSelection: () => handleOptionSelection(option), + }), )}
`; } +function handleMenuKeyUp(event: KeyboardEvent) { + const items = [ + ...(event.currentTarget as HTMLElement).querySelectorAll('[tabindex="0"]'), + ]; + const index = items.indexOf(document.activeElement as HTMLElement); + const direction = event.key === "ArrowDown" ? 1 : event.key === "ArrowUp" ? -1 : 0; + + if (index === -1 || direction === 0) { + return; + } + + event.preventDefault(); + items[(index + direction + items.length) % items.length]?.focus(); +} + const optionsStyles = ({ theme, topOffset }: { theme: Theme; topOffset: number }) => css` ${typography.body1} diff --git a/apps/browser/src/autofill/content/components/option-selection/option-selection.ts b/apps/browser/src/autofill/content/components/option-selection/option-selection.ts index 49b51852a39..ee711456e9c 100644 --- a/apps/browser/src/autofill/content/components/option-selection/option-selection.ts +++ b/apps/browser/src/autofill/content/components/option-selection/option-selection.ts @@ -20,6 +20,9 @@ export class OptionSelection extends LitElement { @property() disabled: boolean = false; + @property() + id: string = ""; + @property() label?: string; @@ -48,10 +51,18 @@ export class OptionSelection extends LitElement { @state() private selection?: Option; - private handleButtonClick = (event: Event) => { + private static currentOpenInstance: OptionSelection | null = null; + + private handleButtonClick = async (event: Event) => { if (!this.disabled) { - // Menu is about to be shown - if (!this.showMenu) { + const isOpening = !this.showMenu; + + if (isOpening) { + if (OptionSelection.currentOpenInstance && OptionSelection.currentOpenInstance !== this) { + OptionSelection.currentOpenInstance.showMenu = false; + } + OptionSelection.currentOpenInstance = this; + this.menuTopOffset = this.offsetTop; // Distance from right edge of button to left edge of the viewport @@ -71,9 +82,29 @@ export class OptionSelection extends LitElement { optionsMenuItemMaxWidth + optionItemIconWidth + 2 + 8 + 12 * 2; this.menuIsEndJustified = distanceFromViewportRightEdge < maxDifferenceThreshold; + } else { + if (OptionSelection.currentOpenInstance === this) { + OptionSelection.currentOpenInstance = null; + } } - this.showMenu = !this.showMenu; + this.showMenu = isOpening; + + if (this.showMenu) { + await this.updateComplete; + const firstItem = this.querySelector('#option-menu [tabindex="0"]') as HTMLElement; + firstItem?.focus(); + } + } + }; + + private handleFocusOut = (event: FocusEvent) => { + const relatedTarget = event.relatedTarget; + if (!(relatedTarget instanceof Node) || !this.contains(relatedTarget)) { + this.showMenu = false; + if (OptionSelection.currentOpenInstance === this) { + OptionSelection.currentOpenInstance = null; + } } }; @@ -95,10 +126,14 @@ export class OptionSelection extends LitElement { } return html` -
+
${OptionSelectionButton({ disabled: this.disabled, icon: this.selection?.icon, + id: this.id, text: this.selection?.text, theme: this.theme, toggledOn: this.showMenu, @@ -106,6 +141,7 @@ export class OptionSelection extends LitElement { })} ${this.showMenu ? OptionItems({ + id: this.id, label: this.label, options: this.options, theme: this.theme, diff --git a/apps/browser/src/autofill/content/components/rows/action-row.ts b/apps/browser/src/autofill/content/components/rows/action-row.ts index ad58411baf4..0380f91012a 100644 --- a/apps/browser/src/autofill/content/components/rows/action-row.ts +++ b/apps/browser/src/autofill/content/components/rows/action-row.ts @@ -5,15 +5,13 @@ import { Theme, ThemeTypes } from "@bitwarden/common/platform/enums"; import { spacing, themes, typography } from "../../../content/components/constants/styles"; -export function ActionRow({ - handleAction, - itemText, - theme = ThemeTypes.Light, -}: { +export type ActionRowProps = { itemText: string; handleAction?: (e: Event) => void; theme: Theme; -}) { +}; + +export function ActionRow({ handleAction, itemText, theme = ThemeTypes.Light }: ActionRowProps) { return html`
@@ -88,30 +73,15 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the inline menu with
@@ -139,30 +109,15 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the inline menu with
@@ -190,30 +145,15 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the inline menu with
@@ -248,13 +188,19 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f aria-hidden="true" fill="none" height="24" - viewBox="0 0 23 24" - width="23" + viewBox="0 0 24 24" + width="24" xmlns="http://www.w3.org/2000/svg" > + @@ -283,29 +229,23 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f
@@ -323,30 +263,15 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f
@@ -404,29 +329,23 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f
@@ -473,29 +392,23 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f
@@ -528,29 +441,23 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f
@@ -575,15 +482,15 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f @@ -613,29 +520,23 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f
@@ -683,29 +584,23 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f
@@ -753,29 +648,23 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f
@@ -876,29 +765,23 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f
@@ -958,29 +841,23 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f
@@ -1027,29 +904,23 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f @@ -1082,29 +953,23 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f @@ -1129,15 +994,15 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f @@ -1167,29 +1032,23 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f @@ -1237,29 +1096,23 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f @@ -1307,29 +1160,23 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f @@ -1389,29 +1236,23 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f @@ -1458,29 +1299,23 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f @@ -1513,29 +1348,23 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f @@ -1560,15 +1389,15 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f @@ -1598,29 +1427,23 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f @@ -1668,29 +1491,23 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f @@ -1738,29 +1555,23 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f @@ -1814,19 +1625,15 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f @@ -1842,29 +1649,23 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f @@ -1903,19 +1704,15 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f @@ -1931,29 +1728,23 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f @@ -1992,19 +1783,15 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f @@ -2026,29 +1813,23 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f @@ -2099,29 +1880,23 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f @@ -2169,29 +1944,23 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f @@ -2239,29 +2008,23 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f @@ -2287,10 +2050,10 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f > @@ -2407,29 +2170,23 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f @@ -2525,29 +2282,23 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f @@ -2578,29 +2329,21 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the locked inline men unlockAccount @@ -2623,17 +2366,22 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the password generato
diff --git a/apps/browser/src/autofill/popup/fido2/fido2-cipher-row.component.ts b/apps/browser/src/autofill/popup/fido2/fido2-cipher-row.component.ts index 98e73d2174c..074e23d642d 100644 --- a/apps/browser/src/autofill/popup/fido2/fido2-cipher-row.component.ts +++ b/apps/browser/src/autofill/popup/fido2/fido2-cipher-row.component.ts @@ -10,8 +10,6 @@ import { ButtonModule, IconButtonModule, ItemModule, - SectionComponent, - SectionHeaderComponent, TypographyModule, } from "@bitwarden/components"; @@ -19,7 +17,6 @@ import { selector: "app-fido2-cipher-row", templateUrl: "fido2-cipher-row.component.html", changeDetection: ChangeDetectionStrategy.OnPush, - standalone: true, imports: [ BadgeModule, ButtonModule, @@ -27,8 +24,6 @@ import { IconButtonModule, ItemModule, JslibModule, - SectionComponent, - SectionHeaderComponent, TypographyModule, ], }) diff --git a/apps/browser/src/autofill/popup/fido2/fido2-use-browser-link.component.ts b/apps/browser/src/autofill/popup/fido2/fido2-use-browser-link.component.ts index 91d97ac96dc..27fe88130de 100644 --- a/apps/browser/src/autofill/popup/fido2/fido2-use-browser-link.component.ts +++ b/apps/browser/src/autofill/popup/fido2/fido2-use-browser-link.component.ts @@ -20,7 +20,6 @@ import { BrowserFido2UserInterfaceSession } from "../../fido2/services/browser-f @Component({ selector: "app-fido2-use-browser-link", templateUrl: "fido2-use-browser-link.component.html", - standalone: true, imports: [A11yModule, CdkConnectedOverlay, CdkOverlayOrigin, CommonModule, JslibModule], animations: [ trigger("transformPanel", [ diff --git a/apps/browser/src/autofill/popup/fido2/fido2.component.html b/apps/browser/src/autofill/popup/fido2/fido2.component.html index 80ea6726cb9..8d8394641e9 100644 --- a/apps/browser/src/autofill/popup/fido2/fido2.component.html +++ b/apps/browser/src/autofill/popup/fido2/fido2.component.html @@ -14,7 +14,7 @@ (click)="addCipher()" slot="end" > - + {{ "new" | i18n }} diff --git a/apps/browser/src/autofill/popup/fido2/fido2.component.ts b/apps/browser/src/autofill/popup/fido2/fido2.component.ts index 2bd16bf8a2e..eb268f4e6a7 100644 --- a/apps/browser/src/autofill/popup/fido2/fido2.component.ts +++ b/apps/browser/src/autofill/popup/fido2/fido2.component.ts @@ -75,7 +75,6 @@ interface ViewData { @Component({ selector: "app-fido2", templateUrl: "fido2.component.html", - standalone: true, imports: [ ButtonModule, CommonModule, @@ -217,9 +216,7 @@ export class Fido2Component implements OnInit, OnDestroy { this.ciphers = await Promise.all( message.cipherIds.map(async (cipherId) => { const cipher = await this.cipherService.get(cipherId, activeUserId); - return cipher.decrypt( - await this.cipherService.getKeyForCipherKeyDecryption(cipher, activeUserId), - ); + return this.cipherService.decrypt(cipher, activeUserId); }), ); @@ -238,9 +235,7 @@ export class Fido2Component implements OnInit, OnDestroy { this.ciphers = await Promise.all( message.existingCipherIds.map(async (cipherId) => { const cipher = await this.cipherService.get(cipherId, activeUserId); - return cipher.decrypt( - await this.cipherService.getKeyForCipherKeyDecryption(cipher, activeUserId), - ); + return this.cipherService.decrypt(cipher, activeUserId); }), ); @@ -447,10 +442,10 @@ export class Fido2Component implements OnInit, OnDestroy { ); this.buildCipher(name, username); - const cipher = await this.cipherService.encrypt(this.cipher, activeUserId); + const encrypted = await this.cipherService.encrypt(this.cipher, activeUserId); try { - await this.cipherService.createWithServer(cipher); - this.cipher.id = cipher.id; + await this.cipherService.createWithServer(encrypted); + this.cipher.id = encrypted.cipher.id; } catch (e) { this.logService.error(e); } diff --git a/apps/browser/src/autofill/popup/settings/autofill.component.html b/apps/browser/src/autofill/popup/settings/autofill.component.html index 4fd85ddce33..264b04b039b 100644 --- a/apps/browser/src/autofill/popup/settings/autofill.component.html +++ b/apps/browser/src/autofill/popup/settings/autofill.component.html @@ -6,6 +6,16 @@
+
+ +

{{ "autofillSuggestionsSectionTitle" | i18n }}

diff --git a/apps/browser/src/autofill/popup/settings/autofill.component.ts b/apps/browser/src/autofill/popup/settings/autofill.component.ts index c30f150e71d..9e83c3fc2c5 100644 --- a/apps/browser/src/autofill/popup/settings/autofill.component.ts +++ b/apps/browser/src/autofill/popup/settings/autofill.component.ts @@ -4,16 +4,20 @@ import { CommonModule } from "@angular/common"; import { Component, DestroyRef, OnInit } from "@angular/core"; import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; import { + FormBuilder, + FormControl, + FormGroup, FormsModule, ReactiveFormsModule, - FormBuilder, - FormGroup, - FormControl, } from "@angular/forms"; import { RouterModule } from "@angular/router"; -import { firstValueFrom } from "rxjs"; +import { filter, firstValueFrom, Observable, switchMap } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { NudgesService, NudgeType } from "@bitwarden/angular/vault"; +import { SpotlightComponent } from "@bitwarden/angular/vault/components/spotlight/spotlight.component"; +import { Account, AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { AutofillOverlayVisibility, BrowserClientVendors, @@ -54,6 +58,7 @@ import { TypographyModule, } from "@bitwarden/components"; +import { AutofillBrowserSettingsService } from "../../../autofill/services/autofill-browser-settings.service"; import { BrowserApi } from "../../../platform/browser/browser-api"; import { PopOutComponent } from "../../../platform/popup/components/pop-out.component"; import { PopupHeaderComponent } from "../../../platform/popup/layout/popup-header.component"; @@ -61,7 +66,6 @@ import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.co @Component({ templateUrl: "autofill.component.html", - standalone: true, imports: [ CardComponent, CheckboxModule, @@ -81,6 +85,7 @@ import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.co SelectModule, TypographyModule, ReactiveFormsModule, + SpotlightComponent, ], }) export class AutofillComponent implements OnInit { @@ -100,6 +105,12 @@ export class AutofillComponent implements OnInit { protected browserClientIsUnknown: boolean; protected autofillOnPageLoadFromPolicy$ = this.autofillSettingsService.activateAutofillOnPageLoadFromPolicy$; + protected showSpotlightNudge$: Observable = this.accountService.activeAccount$.pipe( + filter((account): account is Account => account !== null), + switchMap((account) => + this.nudgesService.showNudgeSpotlight$(NudgeType.AutofillNudge, account.id), + ), + ); protected autofillOnPageLoadForm = new FormGroup({ autofillOnPageLoad: new FormControl(), @@ -142,6 +153,9 @@ export class AutofillComponent implements OnInit { private configService: ConfigService, private formBuilder: FormBuilder, private destroyRef: DestroyRef, + private nudgesService: NudgesService, + private accountService: AccountService, + private autofillBrowserSettingsService: AutofillBrowserSettingsService, ) { this.autofillOnPageLoadOptions = [ { name: this.i18nService.t("autoFillOnPageLoadYes"), value: true }, @@ -165,7 +179,7 @@ export class AutofillComponent implements OnInit { { name: i18nService.t("never"), value: UriMatchStrategy.Never }, ]; - this.browserClientVendor = this.getBrowserClientVendor(); + this.browserClientVendor = BrowserApi.getBrowserClientVendor(window); this.disablePasswordManagerURI = DisablePasswordManagerUris[this.browserClientVendor]; this.browserShortcutsURI = BrowserShortcutsUris[this.browserClientVendor]; this.browserClientIsUnknown = this.browserClientVendor === BrowserClientVendors.Unknown; @@ -173,7 +187,11 @@ export class AutofillComponent implements OnInit { async ngOnInit() { this.canOverrideBrowserAutofillSetting = !this.browserClientIsUnknown; - this.defaultBrowserAutofillDisabled = await this.browserAutofillSettingCurrentlyOverridden(); + + this.defaultBrowserAutofillDisabled = + await this.autofillBrowserSettingsService.isBrowserAutofillSettingOverridden( + this.browserClientVendor, + ); this.inlineMenuVisibility = await firstValueFrom( this.autofillSettingsService.inlineMenuVisibility$, @@ -308,6 +326,40 @@ export class AutofillComponent implements OnInit { ); } + get spotlightButtonIcon() { + if (this.browserClientVendor === BrowserClientVendors.Unknown) { + return "bwi-external-link"; + } + return null; + } + + get browserClientVendorExtended() { + if (this.browserClientVendor !== BrowserClientVendors.Unknown) { + return this.browserClientVendor; + } + if (this.platformUtilsService.isFirefox()) { + return "Firefox"; + } + if (this.platformUtilsService.isSafari()) { + return "Safari"; + } + return BrowserClientVendors.Unknown; + } + + get spotlightButtonText() { + if (this.browserClientVendorExtended === BrowserClientVendors.Unknown) { + return this.i18nService.t("turnOffAutofill"); + } + return this.i18nService.t("turnOffBrowserAutofill", this.browserClientVendorExtended); + } + + async dismissSpotlight() { + await this.nudgesService.dismissNudge( + NudgeType.AutofillNudge, + await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)), + ); + } + async updateInlineMenuVisibility() { if (!this.enableInlineMenu) { this.enableInlineMenuOnIconSelect = false; @@ -346,26 +398,6 @@ export class AutofillComponent implements OnInit { } } - private getBrowserClientVendor(): BrowserClientVendor { - if (this.platformUtilsService.isChrome()) { - return BrowserClientVendors.Chrome; - } - - if (this.platformUtilsService.isOpera()) { - return BrowserClientVendors.Opera; - } - - if (this.platformUtilsService.isEdge()) { - return BrowserClientVendors.Edge; - } - - if (this.platformUtilsService.isVivaldi()) { - return BrowserClientVendors.Vivaldi; - } - - return BrowserClientVendors.Unknown; - } - protected async openURI(event: Event, uri: BrowserShortcutsUri | DisablePasswordManagerUri) { event.preventDefault(); @@ -422,7 +454,7 @@ export class AutofillComponent implements OnInit { if ( this.inlineMenuVisibility === AutofillOverlayVisibility.Off || !this.canOverrideBrowserAutofillSetting || - (await this.browserAutofillSettingCurrentlyOverridden()) + this.defaultBrowserAutofillDisabled ) { return; } @@ -460,6 +492,9 @@ export class AutofillComponent implements OnInit { } await BrowserApi.updateDefaultBrowserAutofillSettings(!this.defaultBrowserAutofillDisabled); + this.autofillBrowserSettingsService.setDefaultBrowserAutofillDisabled( + this.defaultBrowserAutofillDisabled, + ); } private handleOverrideDialogAccept = async () => { @@ -467,18 +502,6 @@ export class AutofillComponent implements OnInit { await this.updateDefaultBrowserAutofillDisabled(); }; - async browserAutofillSettingCurrentlyOverridden() { - if (!this.canOverrideBrowserAutofillSetting) { - return false; - } - - if (!(await this.privacyPermissionGranted())) { - return false; - } - - return await BrowserApi.browserAutofillSettingsOverridden(); - } - async privacyPermissionGranted(): Promise { return await BrowserApi.permissionsGranted(["privacy"]); } diff --git a/apps/browser/src/autofill/popup/settings/blocked-domains.component.ts b/apps/browser/src/autofill/popup/settings/blocked-domains.component.ts index c59ce24c7c4..15379eff436 100644 --- a/apps/browser/src/autofill/popup/settings/blocked-domains.component.ts +++ b/apps/browser/src/autofill/popup/settings/blocked-domains.component.ts @@ -44,7 +44,6 @@ import { PopupRouterCacheService } from "../../../platform/popup/view-cache/popu @Component({ selector: "app-blocked-domains", templateUrl: "blocked-domains.component.html", - standalone: true, imports: [ ButtonModule, CardComponent, diff --git a/apps/browser/src/autofill/popup/settings/excluded-domains.component.ts b/apps/browser/src/autofill/popup/settings/excluded-domains.component.ts index 504d2dbfc17..a5bfad726f5 100644 --- a/apps/browser/src/autofill/popup/settings/excluded-domains.component.ts +++ b/apps/browser/src/autofill/popup/settings/excluded-domains.component.ts @@ -45,7 +45,6 @@ import { PopupRouterCacheService } from "../../../platform/popup/view-cache/popu @Component({ selector: "app-excluded-domains", templateUrl: "excluded-domains.component.html", - standalone: true, imports: [ ButtonModule, CardComponent, diff --git a/apps/browser/src/autofill/popup/settings/notifications.component.ts b/apps/browser/src/autofill/popup/settings/notifications.component.ts index be447e3f885..cb10dec620b 100644 --- a/apps/browser/src/autofill/popup/settings/notifications.component.ts +++ b/apps/browser/src/autofill/popup/settings/notifications.component.ts @@ -18,20 +18,17 @@ import { } from "@bitwarden/components"; import { PopOutComponent } from "../../../platform/popup/components/pop-out.component"; -import { PopupFooterComponent } from "../../../platform/popup/layout/popup-footer.component"; import { PopupHeaderComponent } from "../../../platform/popup/layout/popup-header.component"; import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.component"; @Component({ templateUrl: "notifications.component.html", - standalone: true, imports: [ CommonModule, JslibModule, RouterModule, PopupPageComponent, PopupHeaderComponent, - PopupFooterComponent, PopOutComponent, ItemModule, CardComponent, diff --git a/apps/browser/src/autofill/services/abstractions/autofill.service.ts b/apps/browser/src/autofill/services/abstractions/autofill.service.ts index 5b1b4b3b8bb..daafd871789 100644 --- a/apps/browser/src/autofill/services/abstractions/autofill.service.ts +++ b/apps/browser/src/autofill/services/abstractions/autofill.service.ts @@ -87,5 +87,9 @@ export abstract class AutofillService { cipherType?: CipherType, ) => Promise; setAutoFillOnPageLoadOrgPolicy: () => Promise; - isPasswordRepromptRequired: (cipher: CipherView, tab: chrome.tabs.Tab) => Promise; + isPasswordRepromptRequired: ( + cipher: CipherView, + tab: chrome.tabs.Tab, + action?: string, + ) => Promise; } diff --git a/apps/browser/src/autofill/services/autofill-browser-settings.service.ts b/apps/browser/src/autofill/services/autofill-browser-settings.service.ts new file mode 100644 index 00000000000..ba59a655b77 --- /dev/null +++ b/apps/browser/src/autofill/services/autofill-browser-settings.service.ts @@ -0,0 +1,31 @@ +import { Injectable } from "@angular/core"; +import { BehaviorSubject, Observable } from "rxjs"; + +import { BrowserClientVendors } from "@bitwarden/common/autofill/constants"; +import { BrowserClientVendor } from "@bitwarden/common/autofill/types"; + +import { BrowserApi } from "../../platform/browser/browser-api"; + +/** + * Service class for various Autofill-related browser API operations. + */ +@Injectable({ + providedIn: "root", +}) +export class AutofillBrowserSettingsService { + async isBrowserAutofillSettingOverridden(browserClient: BrowserClientVendor) { + return ( + browserClient !== BrowserClientVendors.Unknown && + (await BrowserApi.browserAutofillSettingsOverridden()) + ); + } + + private _defaultBrowserAutofillDisabled$ = new BehaviorSubject(false); + + defaultBrowserAutofillDisabled$: Observable = + this._defaultBrowserAutofillDisabled$.asObservable(); + + setDefaultBrowserAutofillDisabled(value: boolean) { + this._defaultBrowserAutofillDisabled$.next(value); + } +} diff --git a/apps/browser/src/autofill/services/autofill.service.ts b/apps/browser/src/autofill/services/autofill.service.ts index da46ceb0864..fdd881c2760 100644 --- a/apps/browser/src/autofill/services/autofill.service.ts +++ b/apps/browser/src/autofill/services/autofill.service.ts @@ -593,15 +593,20 @@ export default class AutofillService implements AutofillServiceInterface { * * @param cipher - The cipher to autofill * @param tab - The tab to autofill + * @param action - override for default action once reprompt is completed successfully */ - async isPasswordRepromptRequired(cipher: CipherView, tab: chrome.tabs.Tab): Promise { + async isPasswordRepromptRequired( + cipher: CipherView, + tab: chrome.tabs.Tab, + action?: string, + ): Promise { const userHasMasterPasswordAndKeyHash = await this.userVerificationService.hasMasterPasswordAndMasterKeyHash(); if (cipher.reprompt === CipherRepromptType.Password && userHasMasterPasswordAndKeyHash) { if (!this.isDebouncingPasswordRepromptPopout()) { await this.openVaultItemPasswordRepromptPopout(tab, { cipherId: cipher.id, - action: "autofill", + action: action ?? "autofill", }); } @@ -1574,252 +1579,6 @@ export default class AutofillService implements AutofillServiceInterface { return [expectedDateFormat, dateFormatPatterns]; } - /** - * Generates the autofill script for the specified page details and identify cipher item. - * @param {AutofillScript} fillScript - * @param {AutofillPageDetails} pageDetails - * @param {{[p: string]: AutofillField}} filledFields - * @param {GenerateFillScriptOptions} options - * @returns {AutofillScript} - * @private - */ - private async generateIdentityFillScript( - fillScript: AutofillScript, - pageDetails: AutofillPageDetails, - filledFields: { [id: string]: AutofillField }, - options: GenerateFillScriptOptions, - ): Promise { - if (await this.configService.getFeatureFlag(FeatureFlag.GenerateIdentityFillScriptRefactor)) { - return this._generateIdentityFillScript(fillScript, pageDetails, filledFields, options); - } - - if (!options.cipher.identity) { - return null; - } - - const fillFields: { [id: string]: AutofillField } = {}; - - pageDetails.fields.forEach((f) => { - if ( - AutofillService.isExcludedFieldType(f, AutoFillConstants.ExcludedAutofillTypes) || - ["current-password", "new-password"].includes(f.autoCompleteType) - ) { - return; - } - - for (let i = 0; i < IdentityAutoFillConstants.IdentityAttributes.length; i++) { - const attr = IdentityAutoFillConstants.IdentityAttributes[i]; - // eslint-disable-next-line - if (!f.hasOwnProperty(attr) || !f[attr] || !f.viewable) { - continue; - } - - // ref https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill - // ref https://developers.google.com/web/fundamentals/design-and-ux/input/forms/ - if ( - !fillFields.name && - AutofillService.isFieldMatch( - f[attr], - IdentityAutoFillConstants.FullNameFieldNames, - IdentityAutoFillConstants.FullNameFieldNameValues, - ) - ) { - fillFields.name = f; - break; - } else if ( - !fillFields.firstName && - AutofillService.isFieldMatch(f[attr], IdentityAutoFillConstants.FirstnameFieldNames) - ) { - fillFields.firstName = f; - break; - } else if ( - !fillFields.middleName && - AutofillService.isFieldMatch(f[attr], IdentityAutoFillConstants.MiddlenameFieldNames) - ) { - fillFields.middleName = f; - break; - } else if ( - !fillFields.lastName && - AutofillService.isFieldMatch(f[attr], IdentityAutoFillConstants.LastnameFieldNames) - ) { - fillFields.lastName = f; - break; - } else if ( - !fillFields.title && - AutofillService.isFieldMatch(f[attr], IdentityAutoFillConstants.TitleFieldNames) - ) { - fillFields.title = f; - break; - } else if ( - !fillFields.email && - AutofillService.isFieldMatch(f[attr], IdentityAutoFillConstants.EmailFieldNames) - ) { - fillFields.email = f; - break; - } else if ( - !fillFields.address1 && - AutofillService.isFieldMatch(f[attr], IdentityAutoFillConstants.Address1FieldNames) - ) { - fillFields.address1 = f; - break; - } else if ( - !fillFields.address2 && - AutofillService.isFieldMatch(f[attr], IdentityAutoFillConstants.Address2FieldNames) - ) { - fillFields.address2 = f; - break; - } else if ( - !fillFields.address3 && - AutofillService.isFieldMatch(f[attr], IdentityAutoFillConstants.Address3FieldNames) - ) { - fillFields.address3 = f; - break; - } else if ( - !fillFields.address && - AutofillService.isFieldMatch( - f[attr], - IdentityAutoFillConstants.AddressFieldNames, - IdentityAutoFillConstants.AddressFieldNameValues, - ) - ) { - fillFields.address = f; - break; - } else if ( - !fillFields.postalCode && - AutofillService.isFieldMatch(f[attr], IdentityAutoFillConstants.PostalCodeFieldNames) - ) { - fillFields.postalCode = f; - break; - } else if ( - !fillFields.city && - AutofillService.isFieldMatch(f[attr], IdentityAutoFillConstants.CityFieldNames) - ) { - fillFields.city = f; - break; - } else if ( - !fillFields.state && - AutofillService.isFieldMatch(f[attr], IdentityAutoFillConstants.StateFieldNames) - ) { - fillFields.state = f; - break; - } else if ( - !fillFields.country && - AutofillService.isFieldMatch(f[attr], IdentityAutoFillConstants.CountryFieldNames) - ) { - fillFields.country = f; - break; - } else if ( - !fillFields.phone && - AutofillService.isFieldMatch(f[attr], IdentityAutoFillConstants.PhoneFieldNames) - ) { - fillFields.phone = f; - break; - } else if ( - !fillFields.username && - AutofillService.isFieldMatch(f[attr], IdentityAutoFillConstants.UserNameFieldNames) - ) { - fillFields.username = f; - break; - } else if ( - !fillFields.company && - AutofillService.isFieldMatch(f[attr], IdentityAutoFillConstants.CompanyFieldNames) - ) { - fillFields.company = f; - break; - } - } - }); - - const identity = options.cipher.identity; - this.makeScriptAction(fillScript, identity, fillFields, filledFields, "title"); - this.makeScriptAction(fillScript, identity, fillFields, filledFields, "firstName"); - this.makeScriptAction(fillScript, identity, fillFields, filledFields, "middleName"); - this.makeScriptAction(fillScript, identity, fillFields, filledFields, "lastName"); - this.makeScriptAction(fillScript, identity, fillFields, filledFields, "address1"); - this.makeScriptAction(fillScript, identity, fillFields, filledFields, "address2"); - this.makeScriptAction(fillScript, identity, fillFields, filledFields, "address3"); - this.makeScriptAction(fillScript, identity, fillFields, filledFields, "city"); - this.makeScriptAction(fillScript, identity, fillFields, filledFields, "postalCode"); - this.makeScriptAction(fillScript, identity, fillFields, filledFields, "company"); - this.makeScriptAction(fillScript, identity, fillFields, filledFields, "email"); - this.makeScriptAction(fillScript, identity, fillFields, filledFields, "phone"); - this.makeScriptAction(fillScript, identity, fillFields, filledFields, "username"); - - let filledState = false; - if (fillFields.state && identity.state && identity.state.length > 2) { - const stateLower = identity.state.toLowerCase(); - const isoState = - IdentityAutoFillConstants.IsoStates[stateLower] || - IdentityAutoFillConstants.IsoProvinces[stateLower]; - if (isoState) { - filledState = true; - this.makeScriptActionWithValue(fillScript, isoState, fillFields.state, filledFields); - } - } - - if (!filledState) { - this.makeScriptAction(fillScript, identity, fillFields, filledFields, "state"); - } - - let filledCountry = false; - if (fillFields.country && identity.country && identity.country.length > 2) { - const countryLower = identity.country.toLowerCase(); - const isoCountry = IdentityAutoFillConstants.IsoCountries[countryLower]; - if (isoCountry) { - filledCountry = true; - this.makeScriptActionWithValue(fillScript, isoCountry, fillFields.country, filledFields); - } - } - - if (!filledCountry) { - this.makeScriptAction(fillScript, identity, fillFields, filledFields, "country"); - } - - if (fillFields.name && (identity.firstName || identity.lastName)) { - let fullName = ""; - if (AutofillService.hasValue(identity.firstName)) { - fullName = identity.firstName; - } - if (AutofillService.hasValue(identity.middleName)) { - if (fullName !== "") { - fullName += " "; - } - fullName += identity.middleName; - } - if (AutofillService.hasValue(identity.lastName)) { - if (fullName !== "") { - fullName += " "; - } - fullName += identity.lastName; - } - - this.makeScriptActionWithValue(fillScript, fullName, fillFields.name, filledFields); - } - - if (fillFields.address && AutofillService.hasValue(identity.address1)) { - let address = ""; - if (AutofillService.hasValue(identity.address1)) { - address = identity.address1; - } - if (AutofillService.hasValue(identity.address2)) { - if (address !== "") { - address += ", "; - } - address += identity.address2; - } - if (AutofillService.hasValue(identity.address3)) { - if (address !== "") { - address += ", "; - } - address += identity.address3; - } - - this.makeScriptActionWithValue(fillScript, address, fillFields.address, filledFields); - } - - return fillScript; - } - /** * Generates the autofill script for the specified page details and identity cipher item. * @@ -1828,7 +1587,7 @@ export default class AutofillService implements AutofillServiceInterface { * @param filledFields - The fields that have already been filled, passed between method references * @param options - Contains data used to fill cipher items */ - private _generateIdentityFillScript( + private generateIdentityFillScript( fillScript: AutofillScript, pageDetails: AutofillPageDetails, filledFields: { [id: string]: AutofillField }, diff --git a/apps/browser/src/autofill/shared/styles/variables.scss b/apps/browser/src/autofill/shared/styles/variables.scss index ae6a060798a..1e804ed8fd2 100644 --- a/apps/browser/src/autofill/shared/styles/variables.scss +++ b/apps/browser/src/autofill/shared/styles/variables.scss @@ -1,6 +1,6 @@ $dark-icon-themes: "theme_dark"; -$font-family-sans-serif: "DM Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; +$font-family-sans-serif: Roboto, "Helvetica Neue", Helvetica, Arial, sans-serif; $font-family-source-code-pro: "Source Code Pro", monospace; $font-size-base: 14px; diff --git a/apps/browser/src/autofill/utils/svg-icons.ts b/apps/browser/src/autofill/utils/svg-icons.ts index b04d18608ec..343acc00b06 100644 --- a/apps/browser/src/autofill/utils/svg-icons.ts +++ b/apps/browser/src/autofill/utils/svg-icons.ts @@ -5,34 +5,34 @@ export const logoLockedIcon = ''; export const globeIcon = - ''; + ''; export const creditCardIcon = - ''; + ''; export const idCardIcon = - ''; + ''; export const lockIcon = - ''; + ''; export const plusIcon = - ''; + ''; export const viewCipherIcon = - ''; + ''; export const passkeyIcon = - ''; + ''; export const circleCheckIcon = - ''; + ''; export const spinnerIcon = - ''; + ''; export const keyIcon = - ''; + ''; export const refreshIcon = - ''; + ''; diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index da47542ee6b..5225ebc0fb1 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -39,7 +39,6 @@ import { TokenService as TokenServiceAbstraction } from "@bitwarden/common/auth/ import { UserVerificationApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/user-verification/user-verification-api.service.abstraction"; import { UserVerificationService as UserVerificationServiceAbstraction } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; -import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason"; 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"; @@ -184,6 +183,7 @@ import { SendStateProvider } from "@bitwarden/common/tools/send/services/send-st import { SendService } from "@bitwarden/common/tools/send/services/send.service"; import { InternalSendService as InternalSendServiceAbstraction } from "@bitwarden/common/tools/send/services/send.service.abstraction"; import { UserId } from "@bitwarden/common/types/guid"; +import { CipherEncryptionService } from "@bitwarden/common/vault/abstractions/cipher-encryption.service"; import { CipherService as CipherServiceAbstraction } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CipherFileUploadService as CipherFileUploadServiceAbstraction } from "@bitwarden/common/vault/abstractions/file-upload/cipher-file-upload.service"; import { FolderApiServiceAbstraction } from "@bitwarden/common/vault/abstractions/folder/folder-api.service.abstraction"; @@ -200,6 +200,7 @@ import { DefaultCipherAuthorizationService, } from "@bitwarden/common/vault/services/cipher-authorization.service"; import { CipherService } from "@bitwarden/common/vault/services/cipher.service"; +import { DefaultCipherEncryptionService } from "@bitwarden/common/vault/services/default-cipher-encryption.service"; import { CipherFileUploadService } from "@bitwarden/common/vault/services/file-upload/cipher-file-upload.service"; import { FolderApiService } from "@bitwarden/common/vault/services/folder/folder-api.service"; import { FolderService } from "@bitwarden/common/vault/services/folder/folder.service"; @@ -409,6 +410,7 @@ export default class MainBackground { endUserNotificationService: EndUserNotificationService; inlineMenuFieldQualificationService: InlineMenuFieldQualificationService; taskService: TaskService; + cipherEncryptionService: CipherEncryptionService; ipcContentScriptManagerService: IpcContentScriptManagerService; ipcService: IpcService; @@ -721,6 +723,7 @@ export default class MainBackground { this.logService, (logoutReason: LogoutReason, userId?: UserId) => this.logout(logoutReason, userId), this.vaultTimeoutSettingsService, + { createRequest: (url, request) => new Request(url, request) }, ); this.fileUploadService = new FileUploadService(this.logService, this.apiService); @@ -856,6 +859,11 @@ export default class MainBackground { this.bulkEncryptService = new FallbackBulkEncryptService(this.encryptService); + this.cipherEncryptionService = new DefaultCipherEncryptionService( + this.sdkService, + this.logService, + ); + this.cipherService = new CipherService( this.keyService, this.domainSettingsService, @@ -871,6 +879,7 @@ export default class MainBackground { this.stateProvider, this.accountService, this.logService, + this.cipherEncryptionService, ); this.folderService = new FolderService( this.keyService, @@ -1147,7 +1156,6 @@ export default class MainBackground { this.fido2ClientService, this.vaultSettingsService, this.scriptInjectorService, - this.configService, this.authService, ); @@ -1230,7 +1238,6 @@ export default class MainBackground { this.autofillService, this.scriptInjectorService, this.authService, - this.configService, this.platformUtilsService, this.policyService, this.accountService, @@ -1511,9 +1518,6 @@ export default class MainBackground { } nextAccountStatus = await this.authService.getAuthStatus(userId); - const forcePasswordReset = - (await firstValueFrom(this.masterPasswordService.forceSetPasswordReason$(userId))) != - ForceSetPasswordReason.None; await this.systemService.clearPendingClipboard(); @@ -1521,8 +1525,6 @@ export default class MainBackground { this.messagingService.send("goHome"); } else if (nextAccountStatus === AuthenticationStatus.Locked) { this.messagingService.send("locked", { userId: userId }); - } else if (forcePasswordReset) { - this.messagingService.send("update-temp-password", { userId: userId }); } else { this.messagingService.send("unlocked", { userId: userId }); await this.refreshBadge(); diff --git a/apps/browser/src/background/nativeMessaging.background.ts b/apps/browser/src/background/nativeMessaging.background.ts index d92826765db..7172b98d727 100644 --- a/apps/browser/src/background/nativeMessaging.background.ts +++ b/apps/browser/src/background/nativeMessaging.background.ts @@ -357,7 +357,7 @@ export class NativeMessagingBackground { await this.secureCommunication(); } - return await this.encryptService.encrypt( + return await this.encryptService.encryptString( JSON.stringify(message), this.secureChannel!.sharedSecret!, ); @@ -401,10 +401,9 @@ export class NativeMessagingBackground { return; } message = JSON.parse( - await this.encryptService.decryptToUtf8( + await this.encryptService.decryptString( rawMessage as EncString, this.secureChannel.sharedSecret, - "ipc-desktop-ipc-channel-key", ), ); } else { diff --git a/apps/browser/src/billing/popup/settings/premium-v2.component.ts b/apps/browser/src/billing/popup/settings/premium-v2.component.ts index ff0e8efd646..fde44688349 100644 --- a/apps/browser/src/billing/popup/settings/premium-v2.component.ts +++ b/apps/browser/src/billing/popup/settings/premium-v2.component.ts @@ -29,7 +29,6 @@ import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.co @Component({ selector: "app-premium", templateUrl: "premium-v2.component.html", - standalone: true, imports: [ ButtonModule, CardComponent, diff --git a/apps/browser/src/images/app-store.png b/apps/browser/src/images/app-store.png new file mode 100644 index 00000000000..7b3c9759ef9 Binary files /dev/null and b/apps/browser/src/images/app-store.png differ diff --git a/apps/browser/src/images/download-qr.png b/apps/browser/src/images/download-qr.png new file mode 100644 index 00000000000..4362c1616f4 Binary files /dev/null and b/apps/browser/src/images/download-qr.png differ diff --git a/apps/browser/src/images/google-play.png b/apps/browser/src/images/google-play.png new file mode 100644 index 00000000000..3ff87a25d5c Binary files /dev/null and b/apps/browser/src/images/google-play.png differ diff --git a/apps/browser/src/key-management/key-connector/remove-password.component.html b/apps/browser/src/key-management/key-connector/remove-password.component.html index 793bcff3e09..56baf0de2a0 100644 --- a/apps/browser/src/key-management/key-connector/remove-password.component.html +++ b/apps/browser/src/key-management/key-connector/remove-password.component.html @@ -8,17 +8,21 @@
-
+
+
+ +
+
+
-

{{ "convertOrganizationEncryptionDesc" | i18n: organization.name }}

+

{{ "removeMasterPasswordForOrganizationUserKeyConnector" | i18n }}

+

{{ "organizationName" | i18n }}:

+

{{ organization.name }}

+

{{ "keyConnectorDomain" | i18n }}:

+

{{ organization.keyConnectorUrl }}

-
`, - standalone: true, }) class ExtensionContainerComponent {} @@ -70,7 +70,6 @@ class ExtensionContainerComponent {} `, - standalone: true, imports: [CommonModule, ItemModule, BadgeModule, IconButtonModule, SectionComponent], }) class VaultComponent { @@ -81,11 +80,10 @@ class VaultComponent { selector: "mock-add-button", template: ` `, - standalone: true, imports: [ButtonModule], }) class MockAddButtonComponent {} @@ -101,7 +99,6 @@ class MockAddButtonComponent {} aria-label="Pop out" > `, - standalone: true, imports: [IconButtonModule], }) class MockPopoutButtonComponent {} @@ -113,7 +110,6 @@ class MockPopoutButtonComponent {} `, - standalone: true, imports: [AvatarModule], }) class MockCurrentAccountComponent {} @@ -121,7 +117,6 @@ class MockCurrentAccountComponent {} @Component({ selector: "mock-search", template: ` `, - standalone: true, imports: [SearchModule], }) class MockSearchComponent {} @@ -133,7 +128,6 @@ class MockSearchComponent {} This is an important note about these ciphers `, - standalone: true, imports: [BannerModule], }) class MockBannerComponent {} @@ -153,7 +147,6 @@ class MockBannerComponent {} `, - standalone: true, imports: [ PopupPageComponent, PopupHeaderComponent, @@ -179,12 +172,10 @@ class MockVaultPageComponent {} `, - standalone: true, imports: [ PopupPageComponent, PopupHeaderComponent, MockAddButtonComponent, - MockPopoutButtonComponent, MockCurrentAccountComponent, VaultComponent, ], @@ -205,7 +196,6 @@ class MockVaultPagePoppedComponent {}
Generator content here
`, - standalone: true, imports: [ PopupPageComponent, PopupHeaderComponent, @@ -230,7 +220,6 @@ class MockGeneratorPageComponent {}
Send content here
`, - standalone: true, imports: [ PopupPageComponent, PopupHeaderComponent, @@ -255,7 +244,6 @@ class MockSendPageComponent {}
Settings content here
`, - standalone: true, imports: [ PopupPageComponent, PopupHeaderComponent, @@ -283,15 +271,12 @@ class MockSettingsPageComponent {} `, - standalone: true, imports: [ PopupPageComponent, PopupHeaderComponent, PopupFooterComponent, ButtonModule, - MockAddButtonComponent, MockPopoutButtonComponent, - MockCurrentAccountComponent, VaultComponent, IconButtonModule, ], @@ -405,26 +390,26 @@ const navButtons = (showBerry = false) => [ { label: "vault", page: "/tabs/vault", - iconKey: "lock", - iconKeyActive: "lock-f", + icon: Icons.VaultInactive, + iconActive: Icons.VaultActive, }, { label: "generator", page: "/tabs/generator", - iconKey: "generate", - iconKeyActive: "generate-f", + icon: Icons.GeneratorInactive, + iconActive: Icons.GeneratorActive, }, { label: "send", page: "/tabs/send", - iconKey: "send", - iconKeyActive: "send-f", + icon: Icons.SendInactive, + iconActive: Icons.SendActive, }, { label: "settings", page: "/tabs/settings", - iconKey: "cog", - iconKeyActive: "cog-f", + icon: Icons.SettingsInactive, + iconActive: Icons.SettingsActive, showBerry: showBerry, }, ]; diff --git a/apps/browser/src/platform/popup/layout/popup-page.component.ts b/apps/browser/src/platform/popup/layout/popup-page.component.ts index ca019c16bd7..12bd000ca55 100644 --- a/apps/browser/src/platform/popup/layout/popup-page.component.ts +++ b/apps/browser/src/platform/popup/layout/popup-page.component.ts @@ -6,7 +6,6 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic @Component({ selector: "popup-page", templateUrl: "popup-page.component.html", - standalone: true, host: { class: "tw-h-full tw-flex tw-flex-col tw-overflow-y-hidden", }, diff --git a/apps/browser/src/platform/popup/layout/popup-size.service.ts b/apps/browser/src/platform/popup/layout/popup-size.service.ts index 3ae9a633cab..69d3102d24e 100644 --- a/apps/browser/src/platform/popup/layout/popup-size.service.ts +++ b/apps/browser/src/platform/popup/layout/popup-size.service.ts @@ -50,17 +50,40 @@ export class PopupSizeService { PopupSizeService.setStyle(width); localStorage.setItem(PopupSizeService.LocalStorageKey, width); }); + } + async setHeight() { const isInChromeTab = await BrowserPopupUtils.isInTab(); + /** + * To support both browser default zoom and system default zoom, we need to take into account + * the full screen height. When system default zoom is >100%, window.innerHeight still outputs + * a height equivalent to what it would be at 100%, which can cause the extension window to + * render as too tall. So if the screen height is smaller than the max possible extension height, + * we should use that to set our extension height. Otherwise, we want to use the window.innerHeight + * to support browser zoom. + * + * This is basically a workaround for what we consider a bug with browsers reporting the wrong + * available innerHeight when system zoom is turned on. If that gets fixed, we can remove the code + * checking the screen height. + */ + const MAX_EXT_HEIGHT = 600; + const extensionInnerHeight = window.innerHeight; + // Use a 100px offset when calculating screen height to account for browser container elements + const screenAvailHeight = window.screen.availHeight - 100; + const availHeight = + screenAvailHeight < MAX_EXT_HEIGHT ? screenAvailHeight : extensionInnerHeight; + if (!BrowserPopupUtils.inPopup(window) || isInChromeTab) { - window.document.body.classList.add("body-full"); - } else if (window.innerHeight < 400) { - window.document.body.classList.add("body-xxs"); - } else if (window.innerHeight < 500) { - window.document.body.classList.add("body-xs"); - } else if (window.innerHeight < 600) { - window.document.body.classList.add("body-sm"); + window.document.documentElement.classList.add("body-full"); + } else if (availHeight < 300) { + window.document.documentElement.classList.add("body-3xs"); + } else if (availHeight < 400) { + window.document.documentElement.classList.add("body-xxs"); + } else if (availHeight < 500) { + window.document.documentElement.classList.add("body-xs"); + } else if (availHeight < 600) { + window.document.documentElement.classList.add("body-sm"); } } diff --git a/apps/browser/src/platform/popup/layout/popup-tab-navigation.component.html b/apps/browser/src/platform/popup/layout/popup-tab-navigation.component.html index 27b546738c3..1170725a4b7 100644 --- a/apps/browser/src/platform/popup/layout/popup-tab-navigation.component.html +++ b/apps/browser/src/platform/popup/layout/popup-tab-navigation.component.html @@ -7,7 +7,7 @@
  • diff --git a/apps/browser/src/platform/popup/layout/popup-tab-navigation.component.ts b/apps/browser/src/platform/popup/layout/popup-tab-navigation.component.ts index f4b82dc56fc..8a897e2e21b 100644 --- a/apps/browser/src/platform/popup/layout/popup-tab-navigation.component.ts +++ b/apps/browser/src/platform/popup/layout/popup-tab-navigation.component.ts @@ -4,21 +4,20 @@ import { RouterModule } from "@angular/router"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { LinkModule } from "@bitwarden/components"; +import { Icon, IconModule, LinkModule } from "@bitwarden/components"; export type NavButton = { label: string; page: string; - iconKey: string; - iconKeyActive: string; + icon: Icon; + iconActive: Icon; showBerry?: boolean; }; @Component({ selector: "popup-tab-navigation", templateUrl: "popup-tab-navigation.component.html", - standalone: true, - imports: [CommonModule, LinkModule, RouterModule, JslibModule], + imports: [CommonModule, LinkModule, RouterModule, JslibModule, IconModule], host: { class: "tw-block tw-h-full tw-w-full tw-flex tw-flex-col", }, diff --git a/apps/browser/src/platform/popup/services/browser-router.service.ts b/apps/browser/src/platform/popup/services/browser-router.service.ts index 413bde5fcad..2d449b8a0f2 100644 --- a/apps/browser/src/platform/popup/services/browser-router.service.ts +++ b/apps/browser/src/platform/popup/services/browser-router.service.ts @@ -21,6 +21,8 @@ export class BrowserRouterService { child = child.firstChild; } + // TODO: Eslint upgrade. Please resolve this since the ?? does nothing + // eslint-disable-next-line no-constant-binary-expression const updateUrl = !child?.data?.doNotSaveUrl ?? true; if (updateUrl) { diff --git a/apps/browser/src/platform/popup/view-cache/popup-router-cache.service.ts b/apps/browser/src/platform/popup/view-cache/popup-router-cache.service.ts index 3215893c634..5fc508ac2a6 100644 --- a/apps/browser/src/platform/popup/view-cache/popup-router-cache.service.ts +++ b/apps/browser/src/platform/popup/view-cache/popup-router-cache.service.ts @@ -8,8 +8,9 @@ import { NavigationEnd, Router, UrlSerializer, + UrlTree, } from "@angular/router"; -import { filter, first, firstValueFrom, map, Observable, switchMap, tap } from "rxjs"; +import { filter, first, firstValueFrom, map, Observable, of, switchMap, tap } from "rxjs"; import { GlobalStateProvider } from "@bitwarden/common/platform/state"; @@ -31,6 +32,11 @@ export class PopupRouterCacheService { private hasNavigated = false; + private _hasRestoredCache = false; + get hasRestoredCache() { + return this._hasRestoredCache; + } + constructor() { // init history with existing state this.history$() @@ -56,6 +62,8 @@ export class PopupRouterCacheService { child = child.firstChild; } + // TODO: Eslint upgrade. Please resolve this since the ?? does nothing + // eslint-disable-next-line no-constant-binary-expression return !child?.data?.doNotSaveUrl ?? true; }), switchMap((event) => this.push(event.url)), @@ -107,21 +115,34 @@ export class PopupRouterCacheService { // if no history is present, fallback to vault page await this.router.navigate([""]); } + + /** + * Mark the cache as restored to prevent the router `popupRouterCacheGuard` from + * redirecting to the last visited route again this session. + */ + markCacheRestored() { + this._hasRestoredCache = true; + } } /** * Redirect to the last visited route. Should be applied to root route. **/ -export const popupRouterCacheGuard = (() => { +export const popupRouterCacheGuard = ((): Observable => { const popupHistoryService = inject(PopupRouterCacheService); const urlSerializer = inject(UrlSerializer); + if (popupHistoryService.hasRestoredCache) { + return of(true); + } + return popupHistoryService.last$().pipe( map((url: string) => { if (!url) { return true; } + popupHistoryService.markCacheRestored(); return urlSerializer.parse(url); }), ); diff --git a/apps/browser/src/platform/popup/view-cache/popup-router-cache.spec.ts b/apps/browser/src/platform/popup/view-cache/popup-router-cache.spec.ts index 465a6e6c69c..22fb7bf99b9 100644 --- a/apps/browser/src/platform/popup/view-cache/popup-router-cache.spec.ts +++ b/apps/browser/src/platform/popup/view-cache/popup-router-cache.spec.ts @@ -13,7 +13,10 @@ import { PopupRouterCacheService, popupRouterCacheGuard } from "./popup-router-c const flushPromises = async () => await new Promise(process.nextTick); -@Component({ template: "" }) +@Component({ + template: "", + standalone: false, +}) export class EmptyComponent {} describe("Popup router cache guard", () => { diff --git a/apps/browser/src/platform/popup/view-cache/popup-view-cache.service.ts b/apps/browser/src/platform/popup/view-cache/popup-view-cache.service.ts index 6fc3e11493c..83d6edbc141 100644 --- a/apps/browser/src/platform/popup/view-cache/popup-view-cache.service.ts +++ b/apps/browser/src/platform/popup/view-cache/popup-view-cache.service.ts @@ -19,7 +19,7 @@ import { FormCacheOptions, SignalCacheOptions, ViewCacheService, -} from "@bitwarden/angular/platform/abstractions/view-cache.service"; +} from "@bitwarden/angular/platform/view-cache"; import { MessageSender } from "@bitwarden/common/platform/messaging"; import { GlobalStateProvider } from "@bitwarden/common/platform/state"; @@ -81,14 +81,16 @@ export class PopupViewCacheService implements ViewCacheService { injector = inject(Injector), initialValue, persistNavigation, + clearOnTabChange, } = options; - const cachedValue = this.cache[key] + const cachedValue = this.cache[key]?.value ? deserializer(JSON.parse(this.cache[key].value)) : initialValue; const _signal = signal(cachedValue); const viewCacheOptions = { ...(persistNavigation && { persistNavigation }), + ...(clearOnTabChange && { clearOnTabChange }), }; effect( diff --git a/apps/browser/src/platform/popup/view-cache/popup-view-cache.spec.ts b/apps/browser/src/platform/popup/view-cache/popup-view-cache.spec.ts index 2ec75791d1b..60baf94eeae 100644 --- a/apps/browser/src/platform/popup/view-cache/popup-view-cache.spec.ts +++ b/apps/browser/src/platform/popup/view-cache/popup-view-cache.spec.ts @@ -19,10 +19,16 @@ import { import { PopupViewCacheService } from "./popup-view-cache.service"; -@Component({ template: "" }) +@Component({ + template: "", + standalone: false, +}) export class EmptyComponent {} -@Component({ template: "" }) +@Component({ + template: "", + standalone: false, +}) export class TestComponent { private viewCacheService = inject(PopupViewCacheService); diff --git a/apps/browser/src/platform/services/local-backed-session-storage.service.spec.ts b/apps/browser/src/platform/services/local-backed-session-storage.service.spec.ts index 1b93e33a94e..1b4665b3222 100644 --- a/apps/browser/src/platform/services/local-backed-session-storage.service.spec.ts +++ b/apps/browser/src/platform/services/local-backed-session-storage.service.spec.ts @@ -46,22 +46,18 @@ describe("LocalBackedSessionStorage", () => { it("returns a decrypted value when one is stored in local storage", async () => { const encrypted = makeEncString("encrypted"); localStorage.internalStore["session_test"] = encrypted.encryptedString; - encryptService.decryptToUtf8.mockResolvedValue(JSON.stringify("decrypted")); + encryptService.decryptString.mockResolvedValue(JSON.stringify("decrypted")); const result = await sut.get("test"); // FIXME: Remove when updating file. Eslint update // eslint-disable-next-line @typescript-eslint/no-unused-expressions - expect(encryptService.decryptToUtf8).toHaveBeenCalledWith( - encrypted, - sessionKey, - "browser-session-key", - ), + expect(encryptService.decryptString).toHaveBeenCalledWith(encrypted, sessionKey), expect(result).toEqual("decrypted"); }); it("caches the decrypted value when one is stored in local storage", async () => { const encrypted = makeEncString("encrypted"); localStorage.internalStore["session_test"] = encrypted.encryptedString; - encryptService.decryptToUtf8.mockResolvedValue(JSON.stringify("decrypted")); + encryptService.decryptString.mockResolvedValue(JSON.stringify("decrypted")); await sut.get("test"); expect(sut["cache"]["test"]).toEqual("decrypted"); }); @@ -69,22 +65,18 @@ describe("LocalBackedSessionStorage", () => { it("returns a decrypted value when one is stored in local storage", async () => { const encrypted = makeEncString("encrypted"); localStorage.internalStore["session_test"] = encrypted.encryptedString; - encryptService.decryptToUtf8.mockResolvedValue(JSON.stringify("decrypted")); + encryptService.decryptString.mockResolvedValue(JSON.stringify("decrypted")); const result = await sut.get("test"); // FIXME: Remove when updating file. Eslint update // eslint-disable-next-line @typescript-eslint/no-unused-expressions - expect(encryptService.decryptToUtf8).toHaveBeenCalledWith( - encrypted, - sessionKey, - "browser-session-key", - ), + expect(encryptService.decryptString).toHaveBeenCalledWith(encrypted, sessionKey), expect(result).toEqual("decrypted"); }); it("caches the decrypted value when one is stored in local storage", async () => { const encrypted = makeEncString("encrypted"); localStorage.internalStore["session_test"] = encrypted.encryptedString; - encryptService.decryptToUtf8.mockResolvedValue(JSON.stringify("decrypted")); + encryptService.decryptString.mockResolvedValue(JSON.stringify("decrypted")); await sut.get("test"); expect(sut["cache"]["test"]).toEqual("decrypted"); }); @@ -104,7 +96,7 @@ describe("LocalBackedSessionStorage", () => { it("returns true when the key is in local storage", async () => { localStorage.internalStore["session_test"] = makeEncString("encrypted").encryptedString; - encryptService.decryptToUtf8.mockResolvedValue(JSON.stringify("decrypted")); + encryptService.decryptString.mockResolvedValue(JSON.stringify("decrypted")); const result = await sut.has("test"); expect(result).toBe(true); }); @@ -119,7 +111,7 @@ describe("LocalBackedSessionStorage", () => { async (nullish) => { localStorage.internalStore["session_test"] = nullish; await expect(sut.has("test")).resolves.toBe(false); - expect(encryptService.decryptToUtf8).not.toHaveBeenCalled(); + expect(encryptService.decryptString).not.toHaveBeenCalled(); }, ); }); @@ -127,7 +119,7 @@ describe("LocalBackedSessionStorage", () => { describe("save", () => { const encString = makeEncString("encrypted"); beforeEach(() => { - encryptService.encrypt.mockResolvedValue(encString); + encryptService.encryptString.mockResolvedValue(encString); }); it("logs a warning when saving the same value twice and in a dev environment", async () => { @@ -157,7 +149,10 @@ describe("LocalBackedSessionStorage", () => { it("encrypts and saves the value to local storage", async () => { await sut.save("test", "value"); - expect(encryptService.encrypt).toHaveBeenCalledWith(JSON.stringify("value"), sessionKey); + expect(encryptService.encryptString).toHaveBeenCalledWith( + JSON.stringify("value"), + sessionKey, + ); expect(localStorage.internalStore["session_test"]).toEqual(encString.encryptedString); }); 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 0e6922e3083..1507bf20c48 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 @@ -118,11 +118,7 @@ export class LocalBackedSessionStorageService return null; } - const valueJson = await this.encryptService.decryptToUtf8( - new EncString(local), - encKey, - "browser-session-key", - ); + const valueJson = await this.encryptService.decryptString(new EncString(local), encKey); if (valueJson == null) { // error with decryption, value is lost, delete state and start over await this.localStorage.remove(this.sessionStorageKey(key)); @@ -139,7 +135,10 @@ export class LocalBackedSessionStorageService } const valueJson = JSON.stringify(value); - const encValue = await this.encryptService.encrypt(valueJson, await this.sessionKey.get()); + const encValue = await this.encryptService.encryptString( + valueJson, + await this.sessionKey.get(), + ); await this.localStorage.save(this.sessionStorageKey(key), encValue.encryptedString); } diff --git a/apps/browser/src/platform/services/platform-utils/browser-platform-utils.service.spec.ts b/apps/browser/src/platform/services/platform-utils/browser-platform-utils.service.spec.ts index 38166d10a08..f75e9cc29a5 100644 --- a/apps/browser/src/platform/services/platform-utils/browser-platform-utils.service.spec.ts +++ b/apps/browser/src/platform/services/platform-utils/browser-platform-utils.service.spec.ts @@ -126,12 +126,11 @@ describe("Browser Utils Service", () => { configurable: true, value: "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:58.0) Gecko/20100101 Firefox/58.0", }); - jest.spyOn(BrowserPlatformUtilsService, "isFirefox"); browserPlatformUtilsService.getDevice(); expect(browserPlatformUtilsService.getDevice()).toBe(DeviceType.FirefoxExtension); - expect(BrowserPlatformUtilsService.isFirefox).toHaveBeenCalledTimes(1); + expect(browserPlatformUtilsService.isFirefox()).toBe(true); }); }); diff --git a/apps/browser/src/platform/services/platform-utils/browser-platform-utils.service.ts b/apps/browser/src/platform/services/platform-utils/browser-platform-utils.service.ts index c9200ecc1a4..4ae412fbda6 100644 --- a/apps/browser/src/platform/services/platform-utils/browser-platform-utils.service.ts +++ b/apps/browser/src/platform/services/platform-utils/browser-platform-utils.service.ts @@ -26,6 +26,10 @@ export abstract class BrowserPlatformUtilsService implements PlatformUtilsServic return this.deviceCache; } + // ORDERING MATTERS HERE + // Ordered from most specific to least specific. We try to discern the greatest detail + // for the type of extension the user is on by checking specific cases first and as we go down + // the list we hope to catch all by the most generic clients they could be on. if (BrowserPlatformUtilsService.isFirefox()) { this.deviceCache = DeviceType.FirefoxExtension; } else if (BrowserPlatformUtilsService.isOpera(globalContext)) { @@ -56,10 +60,7 @@ export abstract class BrowserPlatformUtilsService implements PlatformUtilsServic return ClientType.Browser; } - /** - * @deprecated Do not call this directly, use getDevice() instead - */ - static isFirefox(): boolean { + private static isFirefox(): boolean { return ( navigator.userAgent.indexOf(" Firefox/") !== -1 || navigator.userAgent.indexOf(" Gecko/") !== -1 @@ -70,9 +71,6 @@ export abstract class BrowserPlatformUtilsService implements PlatformUtilsServic return this.getDevice() === DeviceType.FirefoxExtension; } - /** - * @deprecated Do not call this directly, use getDevice() instead - */ private static isChrome(globalContext: Window | ServiceWorkerGlobalScope): boolean { return globalContext.chrome && navigator.userAgent.indexOf(" Chrome/") !== -1; } @@ -81,9 +79,6 @@ export abstract class BrowserPlatformUtilsService implements PlatformUtilsServic return this.getDevice() === DeviceType.ChromeExtension; } - /** - * @deprecated Do not call this directly, use getDevice() instead - */ private static isEdge(): boolean { return navigator.userAgent.indexOf(" Edg/") !== -1; } @@ -92,9 +87,6 @@ export abstract class BrowserPlatformUtilsService implements PlatformUtilsServic return this.getDevice() === DeviceType.EdgeExtension; } - /** - * @deprecated Do not call this directly, use getDevice() instead - */ private static isOpera(globalContext: Window | ServiceWorkerGlobalScope): boolean { return ( !!globalContext.opr?.addons || @@ -107,9 +99,6 @@ export abstract class BrowserPlatformUtilsService implements PlatformUtilsServic return this.getDevice() === DeviceType.OperaExtension; } - /** - * @deprecated Do not call this directly, use getDevice() instead - */ private static isVivaldi(): boolean { return navigator.userAgent.indexOf(" Vivaldi/") !== -1; } @@ -118,10 +107,7 @@ export abstract class BrowserPlatformUtilsService implements PlatformUtilsServic return this.getDevice() === DeviceType.VivaldiExtension; } - /** - * @deprecated Do not call this directly, use getDevice() instead - */ - static isSafari(globalContext: Window | ServiceWorkerGlobalScope): boolean { + private static isSafari(globalContext: Window | ServiceWorkerGlobalScope): boolean { // Opera masquerades as Safari, so make sure we're not there first return ( !BrowserPlatformUtilsService.isOpera(globalContext) && @@ -133,6 +119,10 @@ export abstract class BrowserPlatformUtilsService implements PlatformUtilsServic return navigator.userAgent.match("Version/([0-9.]*)")?.[1]; } + isSafari(): boolean { + return this.getDevice() === DeviceType.SafariExtension; + } + /** * Safari previous to version 16.1 had a bug which caused artifacts on hover in large extension popups. * https://bugs.webkit.org/show_bug.cgi?id=218704 @@ -147,10 +137,6 @@ export abstract class BrowserPlatformUtilsService implements PlatformUtilsServic return parts?.[0] < 16 || (parts?.[0] === 16 && parts?.[1] === 0); } - isSafari(): boolean { - return this.getDevice() === DeviceType.SafariExtension; - } - isIE(): boolean { return false; } diff --git a/apps/browser/src/platform/services/popup-view-cache-background.service.ts b/apps/browser/src/platform/services/popup-view-cache-background.service.ts index 79c04e90aad..49eae15fbbd 100644 --- a/apps/browser/src/platform/services/popup-view-cache-background.service.ts +++ b/apps/browser/src/platform/services/popup-view-cache-background.service.ts @@ -1,4 +1,4 @@ -import { switchMap, delay, filter, concatMap } from "rxjs"; +import { switchMap, delay, filter, concatMap, map, first, of } from "rxjs"; import { CommandDefinition, MessageListener } from "@bitwarden/common/platform/messaging"; import { @@ -12,6 +12,7 @@ import { GlobalStateProvider, } from "@bitwarden/common/platform/state"; +import { BrowserApi } from "../browser/browser-api"; import { fromChromeEvent } from "../browser/from-chrome-event"; const popupClosedPortName = "new_popup"; @@ -21,6 +22,12 @@ export type ViewCacheOptions = { * Optional flag to persist the cached value between navigation events. */ persistNavigation?: boolean; + + /** + * When set, the cached value will be cleared when the user changes tabs. + * @optional + */ + clearOnTabChange?: true; }; export type ViewCacheState = { @@ -129,6 +136,37 @@ export class PopupViewCacheBackgroundService { ), ) .subscribe(); + + // On tab changed, excluding extension tabs + fromChromeEvent(chrome.tabs.onActivated) + .pipe( + switchMap((tabs) => BrowserApi.getTab(tabs[0].tabId)!), + switchMap((tab) => { + // FireFox sets the `url` to "about:blank" and won't populate the `url` until the `onUpdated` event + if (tab.url !== "about:blank") { + return of(tab); + } + + return fromChromeEvent(chrome.tabs.onUpdated).pipe( + first(), + switchMap(([tabId]) => BrowserApi.getTab(tabId)!), + ); + }), + map((tab) => tab.url || tab.pendingUrl), + filter((url) => !url?.startsWith(chrome.runtime.getURL(""))), + switchMap(() => + this.popupViewCacheState.update((state) => { + if (!state) { + return null; + } + // Only remove keys that are marked with `clearOnTabChange` + return Object.fromEntries( + Object.entries(state).filter(([, { options }]) => !options?.clearOnTabChange), + ); + }), + ), + ) + .subscribe(); } async clearState() { diff --git a/apps/browser/src/platform/sync/foreground-sync.service.ts b/apps/browser/src/platform/sync/foreground-sync.service.ts index ce776f53685..2ac75bbec2c 100644 --- a/apps/browser/src/platform/sync/foreground-sync.service.ts +++ b/apps/browser/src/platform/sync/foreground-sync.service.ts @@ -13,6 +13,8 @@ import { } from "@bitwarden/common/platform/messaging"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { StateProvider } from "@bitwarden/common/platform/state"; +// This import has been flagged as unallowed for this class. It may be involved in a circular dependency loop. +// eslint-disable-next-line no-restricted-imports import { CoreSyncService } from "@bitwarden/common/platform/sync/internal"; import { SyncOptions } from "@bitwarden/common/platform/sync/sync.service"; import { SendApiService } from "@bitwarden/common/tools/send/services/send-api.service.abstraction"; diff --git a/apps/browser/src/platform/sync/sync-service.listener.spec.ts b/apps/browser/src/platform/sync/sync-service.listener.spec.ts index 9682e2cdb57..dc0674a7ae5 100644 --- a/apps/browser/src/platform/sync/sync-service.listener.spec.ts +++ b/apps/browser/src/platform/sync/sync-service.listener.spec.ts @@ -3,6 +3,8 @@ import { Subject, firstValueFrom } from "rxjs"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { MessageListener, MessageSender } from "@bitwarden/common/platform/messaging"; +// This import has been flagged as unallowed for this class. It may be involved in a circular dependency loop. +// eslint-disable-next-line no-restricted-imports import { tagAsExternal } from "@bitwarden/common/platform/messaging/helpers"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; diff --git a/apps/browser/src/platform/utils/from-chrome-runtime-messaging.ts b/apps/browser/src/platform/utils/from-chrome-runtime-messaging.ts index ebc01ad86fa..9489c5f2a4e 100644 --- a/apps/browser/src/platform/utils/from-chrome-runtime-messaging.ts +++ b/apps/browser/src/platform/utils/from-chrome-runtime-messaging.ts @@ -1,6 +1,8 @@ import { map, share } from "rxjs"; import { Message } from "@bitwarden/common/platform/messaging"; +// This import has been flagged as unallowed for this class. It may be involved in a circular dependency loop. +// eslint-disable-next-line no-restricted-imports import { tagAsExternal } from "@bitwarden/common/platform/messaging/internal"; import { fromChromeEvent } from "../browser/from-chrome-event"; diff --git a/apps/browser/src/popup/app-routing.module.ts b/apps/browser/src/popup/app-routing.module.ts index 45955506b91..3dde9f15fdb 100644 --- a/apps/browser/src/popup/app-routing.module.ts +++ b/apps/browser/src/popup/app-routing.module.ts @@ -15,7 +15,6 @@ import { tdeDecryptionRequiredGuard, unauthGuardFn, } from "@bitwarden/angular/auth/guards"; -import { NewDeviceVerificationNoticeGuard } from "@bitwarden/angular/vault/guards"; import { AnonLayoutWrapperComponent, AnonLayoutWrapperData, @@ -43,11 +42,6 @@ import { VaultIcon, } from "@bitwarden/auth/angular"; import { LockComponent } from "@bitwarden/key-management-ui"; -import { - NewDeviceVerificationNoticePageOneComponent, - NewDeviceVerificationNoticePageTwoComponent, - VaultIcons, -} from "@bitwarden/vault"; import { fido2AuthGuard } from "../auth/guards/fido2-auth.guard"; import { AccountSwitcherComponent } from "../auth/popup/account-switching/account-switcher.component"; @@ -73,7 +67,6 @@ import { SendAddEditComponent as SendAddEditV2Component } from "../tools/popup/s import { SendCreatedComponent } from "../tools/popup/send-v2/send-created/send-created.component"; import { SendV2Component } from "../tools/popup/send-v2/send-v2.component"; import { AboutPageV2Component } from "../tools/popup/settings/about-page/about-page-v2.component"; -import { MoreFromBitwardenPageV2Component } from "../tools/popup/settings/about-page/more-from-bitwarden-page-v2.component"; import { ExportBrowserV2Component } from "../tools/popup/settings/export/export-browser-v2.component"; import { ImportBrowserV2Component } from "../tools/popup/settings/import/import-browser-v2.component"; import { SettingsV2Component } from "../tools/popup/settings/settings-v2.component"; @@ -89,7 +82,9 @@ import { PasswordHistoryV2Component } from "../vault/popup/components/vault-v2/v import { VaultV2Component } from "../vault/popup/components/vault-v2/vault-v2.component"; import { ViewV2Component } from "../vault/popup/components/vault-v2/view-v2/view-v2.component"; import { AppearanceV2Component } from "../vault/popup/settings/appearance-v2.component"; +import { DownloadBitwardenComponent } from "../vault/popup/settings/download-bitwarden.component"; import { FoldersV2Component } from "../vault/popup/settings/folders-v2.component"; +import { MoreFromBitwardenPageV2Component } from "../vault/popup/settings/more-from-bitwarden-page-v2.component"; import { TrashComponent } from "../vault/popup/settings/trash.component"; import { VaultSettingsV2Component } from "../vault/popup/settings/vault-settings-v2.component"; @@ -589,6 +584,12 @@ const routes: Routes = [ canActivate: [authGuard], data: { elevation: 2 } satisfies RouteDataProperties, }, + { + path: "download-bitwarden", + component: DownloadBitwardenComponent, + canActivate: [authGuard], + data: { elevation: 2 } satisfies RouteDataProperties, + }, { path: "intro-carousel", component: ExtensionAnonLayoutWrapperComponent, @@ -605,34 +606,6 @@ const routes: Routes = [ }, ], }, - { - path: "new-device-notice", - component: ExtensionAnonLayoutWrapperComponent, - canActivate: [], - children: [ - { - path: "", - component: NewDeviceVerificationNoticePageOneComponent, - data: { - pageIcon: VaultIcons.ExclamationTriangle, - pageTitle: { - key: "importantNotice", - }, - hideFooter: true, - }, - }, - { - path: "setup", - component: NewDeviceVerificationNoticePageTwoComponent, - data: { - pageIcon: VaultIcons.UserLock, - pageTitle: { - key: "setupTwoStepLogin", - }, - }, - }, - ], - }, { path: "tabs", component: TabsV2Component, @@ -650,7 +623,7 @@ const routes: Routes = [ { path: "vault", component: VaultV2Component, - canActivate: [authGuard, NewDeviceVerificationNoticeGuard], + canActivate: [authGuard], canDeactivate: [clearVaultStateGuard], data: { elevation: 0 } satisfies RouteDataProperties, }, diff --git a/apps/browser/src/popup/app.component.ts b/apps/browser/src/popup/app.component.ts index 6a08bf007bb..5f7fbc1fad7 100644 --- a/apps/browser/src/popup/app.component.ts +++ b/apps/browser/src/popup/app.component.ts @@ -26,6 +26,7 @@ import { import { BiometricsService, BiometricStateService } from "@bitwarden/key-management"; import { PopupCompactModeService } from "../platform/popup/layout/popup-compact-mode.service"; +import { PopupSizeService } from "../platform/popup/layout/popup-size.service"; import { initPopupClosedListener } from "../platform/services/popup-view-cache-background.service"; import { VaultBrowserStateService } from "../vault/services/vault-browser-state.service"; @@ -42,6 +43,7 @@ import { DesktopSyncVerificationDialogComponent } from "./components/desktop-syn
`, + standalone: false, }) export class AppComponent implements OnInit, OnDestroy { private compactModeService = inject(PopupCompactModeService); @@ -71,6 +73,7 @@ export class AppComponent implements OnInit, OnDestroy { private biometricStateService: BiometricStateService, private biometricsService: BiometricsService, private deviceTrustToastService: DeviceTrustToastService, + private popupSizeService: PopupSizeService, ) { this.deviceTrustToastService.setupListeners$.pipe(takeUntilDestroyed()).subscribe(); } @@ -79,6 +82,7 @@ export class AppComponent implements OnInit, OnDestroy { initPopupClosedListener(); this.compactModeService.init(); + await this.popupSizeService.setHeight(); // Component states must not persist between closing and reopening the popup, otherwise they become dead objects // Clear them aggressively to make sure this doesn't occur @@ -160,10 +164,6 @@ export class AppComponent implements OnInit, OnDestroy { // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. // eslint-disable-next-line @typescript-eslint/no-floating-promises this.router.navigate(["/remove-password"]); - } else if (msg.command == "update-temp-password") { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["/update-temp-password"]); } }), takeUntil(this.destroy$), diff --git a/apps/browser/src/popup/components/desktop-sync-verification-dialog.component.ts b/apps/browser/src/popup/components/desktop-sync-verification-dialog.component.ts index 5003bbdc936..2ca24da6c75 100644 --- a/apps/browser/src/popup/components/desktop-sync-verification-dialog.component.ts +++ b/apps/browser/src/popup/components/desktop-sync-verification-dialog.component.ts @@ -17,7 +17,6 @@ export type DesktopSyncVerificationDialogParams = { @Component({ templateUrl: "desktop-sync-verification-dialog.component.html", - standalone: true, imports: [JslibModule, ButtonModule, DialogModule], }) export class DesktopSyncVerificationDialogComponent implements OnDestroy, OnInit { diff --git a/apps/browser/src/popup/components/user-verification.component.ts b/apps/browser/src/popup/components/user-verification.component.ts index 6befc8973b0..f6cb6cdff12 100644 --- a/apps/browser/src/popup/components/user-verification.component.ts +++ b/apps/browser/src/popup/components/user-verification.component.ts @@ -22,5 +22,6 @@ import { UserVerificationComponent as BaseComponent } from "@bitwarden/angular/a transition(":enter", [style({ opacity: 0 }), animate("100ms", style({ opacity: 1 }))]), ]), ], + standalone: false, }) export class UserVerificationComponent extends BaseComponent {} diff --git a/apps/browser/src/popup/images/loading.svg b/apps/browser/src/popup/images/loading.svg index 3f2033303db..5f4102a5921 100644 --- a/apps/browser/src/popup/images/loading.svg +++ b/apps/browser/src/popup/images/loading.svg @@ -1,5 +1,5 @@  - Loading... diff --git a/apps/browser/src/popup/scss/base.scss b/apps/browser/src/popup/scss/base.scss index 59893b5050d..80ada61f868 100644 --- a/apps/browser/src/popup/scss/base.scss +++ b/apps/browser/src/popup/scss/base.scss @@ -8,6 +8,34 @@ html { overflow: hidden; + min-height: 600px; + height: 100%; + + &.body-sm { + min-height: 500px; + } + + &.body-xs { + min-height: 400px; + } + + &.body-xxs { + min-height: 300px; + } + + &.body-3xs { + min-height: 240px; + } + + &.body-full { + min-height: unset; + width: 100%; + height: 100%; + + & body { + width: 100%; + } + } } html, @@ -20,9 +48,9 @@ body { body { width: 380px; - height: 600px; + height: 100%; position: relative; - min-height: 100vh; + min-height: inherit; overflow: hidden; color: $text-color; background-color: $background-color; @@ -31,23 +59,6 @@ body { color: themed("textColor"); background-color: themed("backgroundColor"); } - - &.body-sm { - height: 500px; - } - - &.body-xs { - height: 400px; - } - - &.body-xxs { - height: 300px; - } - - &.body-full { - width: 100%; - height: 100%; - } } h1, diff --git a/apps/browser/src/popup/scss/misc.scss b/apps/browser/src/popup/scss/misc.scss index 8aace90d0a6..006e1d35f6a 100644 --- a/apps/browser/src/popup/scss/misc.scss +++ b/apps/browser/src/popup/scss/misc.scss @@ -211,12 +211,6 @@ p.lead { } } -#hcaptcha_iframe { - width: 100%; - border: none; - transition: height 0.25s linear; -} - body.linux-webauthn { width: 485px !important; #web-authn-frame { diff --git a/apps/browser/src/popup/scss/variables.scss b/apps/browser/src/popup/scss/variables.scss index b78f06f2f3f..aea69e26436 100644 --- a/apps/browser/src/popup/scss/variables.scss +++ b/apps/browser/src/popup/scss/variables.scss @@ -1,6 +1,6 @@ $dark-icon-themes: "theme_dark"; -$font-family-sans-serif: "DM Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; +$font-family-sans-serif: Roboto, "Helvetica Neue", Helvetica, Arial, sans-serif; $font-family-monospace: Menlo, Monaco, Consolas, "Courier New", monospace; $font-size-base: 16px; $font-size-large: 18px; diff --git a/apps/browser/src/popup/services/services.module.ts b/apps/browser/src/popup/services/services.module.ts index 00b8ae81cf9..6ede88dfc13 100644 --- a/apps/browser/src/popup/services/services.module.ts +++ b/apps/browser/src/popup/services/services.module.ts @@ -5,9 +5,9 @@ import { Router } from "@angular/router"; import { merge, of, Subject } from "rxjs"; import { CollectionService } from "@bitwarden/admin-console/common"; -import { ViewCacheService } from "@bitwarden/angular/platform/abstractions/view-cache.service"; import { AngularThemingService } from "@bitwarden/angular/platform/services/theming/angular-theming.service"; import { SafeProvider, safeProvider } from "@bitwarden/angular/platform/utils/safe-provider"; +import { ViewCacheService } from "@bitwarden/angular/platform/view-cache"; import { CLIENT_TYPE, DEFAULT_VAULT_TIMEOUT, diff --git a/apps/browser/src/popup/tabs-v2.component.ts b/apps/browser/src/popup/tabs-v2.component.ts index 24ce9d8cb12..3d93f5d4e04 100644 --- a/apps/browser/src/popup/tabs-v2.component.ts +++ b/apps/browser/src/popup/tabs-v2.component.ts @@ -1,53 +1,62 @@ import { Component } from "@angular/core"; -import { combineLatest, map } from "rxjs"; +import { combineLatest, map, Observable, startWith, switchMap } from "rxjs"; +import { NudgesService } from "@bitwarden/angular/vault"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; -import { HasNudgeService } from "@bitwarden/vault"; +import { Icons } from "@bitwarden/components"; + +import { NavButton } from "../platform/popup/layout/popup-tab-navigation.component"; @Component({ selector: "app-tabs-v2", templateUrl: "./tabs-v2.component.html", - providers: [HasNudgeService], + standalone: false, }) export class TabsV2Component { - constructor( - private readonly hasNudgeService: HasNudgeService, - private readonly configService: ConfigService, - ) {} - - protected navButtons$ = combineLatest([ + private hasActiveBadges$ = this.accountService.activeAccount$ + .pipe(getUserId) + .pipe(switchMap((userId) => this.nudgesService.hasActiveBadges$(userId))); + protected navButtons$: Observable = combineLatest([ this.configService.getFeatureFlag$(FeatureFlag.PM8851_BrowserOnboardingNudge), - this.hasNudgeService.nudgeStatus$(), + this.hasActiveBadges$, ]).pipe( - map(([onboardingFeatureEnabled, nudgeStatus]) => { + startWith([false, false]), + map(([onboardingFeatureEnabled, hasBadges]) => { return [ { label: "vault", page: "/tabs/vault", - iconKey: "lock", - iconKeyActive: "lock-f", + icon: Icons.VaultInactive, + iconActive: Icons.VaultActive, }, { label: "generator", page: "/tabs/generator", - iconKey: "generate", - iconKeyActive: "generate-f", + icon: Icons.GeneratorInactive, + iconActive: Icons.GeneratorActive, }, { label: "send", page: "/tabs/send", - iconKey: "send", - iconKeyActive: "send-f", + icon: Icons.SendInactive, + iconActive: Icons.SendActive, }, { label: "settings", page: "/tabs/settings", - iconKey: "cog", - iconKeyActive: "cog-f", - showBerry: onboardingFeatureEnabled && !nudgeStatus.hasSpotlightDismissed, + icon: Icons.SettingsInactive, + iconActive: Icons.SettingsActive, + showBerry: onboardingFeatureEnabled && hasBadges, }, ]; }), ); + constructor( + private nudgesService: NudgesService, + private accountService: AccountService, + private readonly configService: ConfigService, + ) {} } diff --git a/apps/browser/src/tools/popup/components/file-popout-callout.component.ts b/apps/browser/src/tools/popup/components/file-popout-callout.component.ts index 491e33c5738..e30fbf58321 100644 --- a/apps/browser/src/tools/popup/components/file-popout-callout.component.ts +++ b/apps/browser/src/tools/popup/components/file-popout-callout.component.ts @@ -12,7 +12,6 @@ import { FilePopoutUtilsService } from "../services/file-popout-utils.service"; @Component({ selector: "tools-file-popout-callout", templateUrl: "file-popout-callout.component.html", - standalone: true, imports: [CommonModule, JslibModule, CalloutModule], }) export class FilePopoutCalloutComponent implements OnInit { diff --git a/apps/browser/src/tools/popup/generator/credential-generator-history.component.ts b/apps/browser/src/tools/popup/generator/credential-generator-history.component.ts index 2bf290b3223..441e5d6e4c6 100644 --- a/apps/browser/src/tools/popup/generator/credential-generator-history.component.ts +++ b/apps/browser/src/tools/popup/generator/credential-generator-history.component.ts @@ -28,7 +28,6 @@ import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.co @Component({ selector: "app-credential-generator-history", templateUrl: "credential-generator-history.component.html", - standalone: true, imports: [ ButtonModule, CommonModule, diff --git a/apps/browser/src/tools/popup/generator/credential-generator.component.ts b/apps/browser/src/tools/popup/generator/credential-generator.component.ts index 9c1af07efdd..b34c829b006 100644 --- a/apps/browser/src/tools/popup/generator/credential-generator.component.ts +++ b/apps/browser/src/tools/popup/generator/credential-generator.component.ts @@ -7,12 +7,10 @@ import { GeneratorModule } from "@bitwarden/generator-components"; import { CurrentAccountComponent } from "../../../auth/popup/account-switching/current-account.component"; import { PopOutComponent } from "../../../platform/popup/components/pop-out.component"; -import { PopupFooterComponent } from "../../../platform/popup/layout/popup-footer.component"; import { PopupHeaderComponent } from "../../../platform/popup/layout/popup-header.component"; import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.component"; @Component({ - standalone: true, selector: "credential-generator", templateUrl: "credential-generator.component.html", imports: [ @@ -22,7 +20,6 @@ import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.co PopOutComponent, PopupHeaderComponent, PopupPageComponent, - PopupFooterComponent, RouterModule, ItemModule, ], diff --git a/apps/browser/src/tools/popup/send-v2/add-edit/send-add-edit.component.ts b/apps/browser/src/tools/popup/send-v2/add-edit/send-add-edit.component.ts index 0962dec3dcf..b6957248d75 100644 --- a/apps/browser/src/tools/popup/send-v2/add-edit/send-add-edit.component.ts +++ b/apps/browser/src/tools/popup/send-v2/add-edit/send-add-edit.component.ts @@ -63,7 +63,6 @@ export type AddEditQueryParams = Partial>; @Component({ selector: "tools-send-add-edit", templateUrl: "send-add-edit.component.html", - standalone: true, providers: [{ provide: SendFormConfigService, useClass: DefaultSendFormConfigService }], imports: [ CommonModule, diff --git a/apps/browser/src/tools/popup/send-v2/send-created/send-created.component.ts b/apps/browser/src/tools/popup/send-v2/send-created/send-created.component.ts index 7191040ac6f..89d1ad5e809 100644 --- a/apps/browser/src/tools/popup/send-v2/send-created/send-created.component.ts +++ b/apps/browser/src/tools/popup/send-v2/send-created/send-created.component.ts @@ -3,7 +3,7 @@ import { CommonModule } from "@angular/common"; import { Component } from "@angular/core"; import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; -import { ActivatedRoute, Router, RouterLink, RouterModule } from "@angular/router"; +import { ActivatedRoute, Router, RouterModule } from "@angular/router"; import { firstValueFrom } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; @@ -23,7 +23,6 @@ import { PopupPageComponent } from "../../../../platform/popup/layout/popup-page @Component({ selector: "app-send-created", templateUrl: "./send-created.component.html", - standalone: true, imports: [ ButtonModule, CommonModule, @@ -31,7 +30,6 @@ import { PopupPageComponent } from "../../../../platform/popup/layout/popup-page PopOutComponent, PopupHeaderComponent, PopupPageComponent, - RouterLink, RouterModule, PopupFooterComponent, IconModule, diff --git a/apps/browser/src/tools/popup/send-v2/send-file-popout-dialog/send-file-popout-dialog-container.component.ts b/apps/browser/src/tools/popup/send-v2/send-file-popout-dialog/send-file-popout-dialog-container.component.ts index 4266dd3914e..251f19cf252 100644 --- a/apps/browser/src/tools/popup/send-v2/send-file-popout-dialog/send-file-popout-dialog-container.component.ts +++ b/apps/browser/src/tools/popup/send-v2/send-file-popout-dialog/send-file-popout-dialog-container.component.ts @@ -15,7 +15,6 @@ import { SendFilePopoutDialogComponent } from "./send-file-popout-dialog.compone @Component({ selector: "send-file-popout-dialog-container", templateUrl: "./send-file-popout-dialog-container.component.html", - standalone: true, imports: [JslibModule, CommonModule], }) export class SendFilePopoutDialogContainerComponent implements OnInit { diff --git a/apps/browser/src/tools/popup/send-v2/send-file-popout-dialog/send-file-popout-dialog.component.ts b/apps/browser/src/tools/popup/send-v2/send-file-popout-dialog/send-file-popout-dialog.component.ts index fb21b5bb026..248b3c49a98 100644 --- a/apps/browser/src/tools/popup/send-v2/send-file-popout-dialog/send-file-popout-dialog.component.ts +++ b/apps/browser/src/tools/popup/send-v2/send-file-popout-dialog/send-file-popout-dialog.component.ts @@ -9,7 +9,6 @@ import BrowserPopupUtils from "../../../../platform/popup/browser-popup-utils"; @Component({ selector: "send-file-popout-dialog", templateUrl: "./send-file-popout-dialog.component.html", - standalone: true, imports: [JslibModule, CommonModule, DialogModule, ButtonModule, TypographyModule], }) export class SendFilePopoutDialogComponent { diff --git a/apps/browser/src/tools/popup/send-v2/send-v2.component.html b/apps/browser/src/tools/popup/send-v2/send-v2.component.html index d51bda45b55..d271f67fa3b 100644 --- a/apps/browser/src/tools/popup/send-v2/send-v2.component.html +++ b/apps/browser/src/tools/popup/send-v2/send-v2.component.html @@ -20,15 +20,29 @@ *ngIf="listState === sendState.Empty" class="tw-flex tw-flex-col tw-h-full tw-justify-center" > - - {{ "sendsNoItemsTitle" | i18n }} - {{ "sendsNoItemsMessage" | i18n }} - - + + + {{ "sendsNoItemsTitle" | i18n }} + {{ "sendsNoItemsMessage" | i18n }} + + + + + + {{ "sendsTitleNoItems" | i18n }} + {{ "sendsBodyNoItems" | i18n }} + + +
diff --git a/apps/browser/src/tools/popup/send-v2/send-v2.component.spec.ts b/apps/browser/src/tools/popup/send-v2/send-v2.component.spec.ts index 6fc4793f5c0..c1f8e9fb263 100644 --- a/apps/browser/src/tools/popup/send-v2/send-v2.component.spec.ts +++ b/apps/browser/src/tools/popup/send-v2/send-v2.component.spec.ts @@ -6,6 +6,7 @@ import { MockProxy, mock } from "jest-mock-extended"; import { of, BehaviorSubject } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { NudgesService } from "@bitwarden/angular/vault"; import { SearchService } from "@bitwarden/common/abstractions/search.service"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; @@ -121,6 +122,7 @@ describe("SendV2Component", () => { { provide: SendListFiltersService, useValue: sendListFiltersService }, { provide: PopupRouterCacheService, useValue: mock() }, { provide: PolicyService, useValue: policyService }, + { provide: NudgesService, useValue: mock() }, ], }).compileComponents(); diff --git a/apps/browser/src/tools/popup/send-v2/send-v2.component.ts b/apps/browser/src/tools/popup/send-v2/send-v2.component.ts index 49804abda5d..e2b5551cc7d 100644 --- a/apps/browser/src/tools/popup/send-v2/send-v2.component.ts +++ b/apps/browser/src/tools/popup/send-v2/send-v2.component.ts @@ -1,10 +1,10 @@ import { CommonModule } from "@angular/common"; -import { Component, OnDestroy, OnInit } from "@angular/core"; +import { Component, OnDestroy } from "@angular/core"; import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; -import { RouterLink } from "@angular/router"; -import { combineLatest, switchMap } from "rxjs"; +import { combineLatest, Observable, switchMap } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { NudgesService, NudgeType } from "@bitwarden/angular/vault"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { PolicyType } from "@bitwarden/common/admin-console/enums"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; @@ -12,13 +12,13 @@ import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { SendType } from "@bitwarden/common/tools/send/enums/send-type"; import { ButtonModule, CalloutModule, Icons, NoItemsModule } from "@bitwarden/components"; import { - NoSendsIcon, NewSendDropdownComponent, - SendListItemsContainerComponent, + NoSendsIcon, SendItemsService, - SendSearchComponent, SendListFiltersComponent, SendListFiltersService, + SendListItemsContainerComponent, + SendSearchComponent, } from "@bitwarden/send-ui"; import { CurrentAccountComponent } from "../../../auth/popup/account-switching/current-account.component"; @@ -26,6 +26,8 @@ import { PopOutComponent } from "../../../platform/popup/components/pop-out.comp import { PopupHeaderComponent } from "../../../platform/popup/layout/popup-header.component"; import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.component"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum SendState { Empty, NoResults, @@ -33,7 +35,6 @@ export enum SendState { @Component({ templateUrl: "send-v2.component.html", - standalone: true, imports: [ CalloutModule, PopupPageComponent, @@ -44,14 +45,13 @@ export enum SendState { JslibModule, CommonModule, ButtonModule, - RouterLink, NewSendDropdownComponent, SendListItemsContainerComponent, SendListFiltersComponent, SendSearchComponent, ], }) -export class SendV2Component implements OnInit, OnDestroy { +export class SendV2Component implements OnDestroy { sendType = SendType; sendState = SendState; @@ -61,6 +61,12 @@ export class SendV2Component implements OnInit, OnDestroy { protected title: string = "allSends"; protected noItemIcon = NoSendsIcon; protected noResultsIcon = Icons.NoResults; + private activeUserId$ = this.accountService.activeAccount$.pipe(getUserId); + protected showSendSpotlight$: Observable = this.activeUserId$.pipe( + switchMap((userId) => + this.nudgesService.showNudgeSpotlight$(NudgeType.SendNudgeStatus, userId), + ), + ); protected sendsDisabled = false; @@ -69,6 +75,7 @@ export class SendV2Component implements OnInit, OnDestroy { protected sendListFiltersService: SendListFiltersService, private policyService: PolicyService, private accountService: AccountService, + private nudgesService: NudgesService, ) { combineLatest([ this.sendItemsService.emptyList$, @@ -109,7 +116,5 @@ export class SendV2Component implements OnInit, OnDestroy { }); } - ngOnInit(): void {} - ngOnDestroy(): void {} } diff --git a/apps/browser/src/tools/popup/settings/about-dialog/about-dialog.component.html b/apps/browser/src/tools/popup/settings/about-dialog/about-dialog.component.html index 40dad4cde4b..af68959fe5d 100644 --- a/apps/browser/src/tools/popup/settings/about-dialog/about-dialog.component.html +++ b/apps/browser/src/tools/popup/settings/about-dialog/about-dialog.component.html @@ -6,7 +6,7 @@

© Bitwarden Inc. 2015-{{ year }}

-
+

{{ "version" | i18n }}: {{ version$ | async }}

SDK: {{ sdkVersion$ | async }}

diff --git a/apps/browser/src/tools/popup/settings/about-dialog/about-dialog.component.ts b/apps/browser/src/tools/popup/settings/about-dialog/about-dialog.component.ts index 6f1c1162eb4..39bff089668 100644 --- a/apps/browser/src/tools/popup/settings/about-dialog/about-dialog.component.ts +++ b/apps/browser/src/tools/popup/settings/about-dialog/about-dialog.component.ts @@ -18,7 +18,6 @@ import { @Component({ templateUrl: "about-dialog.component.html", - standalone: true, imports: [CommonModule, JslibModule, DialogModule, ButtonModule, TypographyModule], }) export class AboutDialogComponent { diff --git a/apps/browser/src/tools/popup/settings/about-page/about-page-v2.component.html b/apps/browser/src/tools/popup/settings/about-page/about-page-v2.component.html index bcc0f12d0d7..839681889a8 100644 --- a/apps/browser/src/tools/popup/settings/about-page/about-page-v2.component.html +++ b/apps/browser/src/tools/popup/settings/about-page/about-page-v2.component.html @@ -23,7 +23,7 @@ - + {{ "moreFromBitwarden" | i18n }} diff --git a/apps/browser/src/tools/popup/settings/about-page/about-page-v2.component.ts b/apps/browser/src/tools/popup/settings/about-page/about-page-v2.component.ts index 1d0d4218439..8a76290eff1 100644 --- a/apps/browser/src/tools/popup/settings/about-page/about-page-v2.component.ts +++ b/apps/browser/src/tools/popup/settings/about-page/about-page-v2.component.ts @@ -5,6 +5,8 @@ import { firstValueFrom } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { DeviceType } from "@bitwarden/common/enums"; +import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { DialogService, ItemModule } from "@bitwarden/components"; @@ -31,7 +33,6 @@ const RateUrls = { @Component({ templateUrl: "about-page-v2.component.html", - standalone: true, imports: [ CommonModule, JslibModule, @@ -47,12 +48,17 @@ export class AboutPageV2Component { private dialogService: DialogService, private environmentService: EnvironmentService, private platformUtilsService: PlatformUtilsService, + private configService: ConfigService, ) {} about() { this.dialogService.open(AboutDialogComponent); } + protected isNudgeFeatureEnabled$ = this.configService.getFeatureFlag$( + FeatureFlag.PM8851_BrowserOnboardingNudge, + ); + async launchHelp() { const confirmed = await this.dialogService.openSimpleDialog({ title: { key: "continueToHelpCenter" }, diff --git a/apps/browser/src/tools/popup/settings/export/export-browser-v2.component.ts b/apps/browser/src/tools/popup/settings/export/export-browser-v2.component.ts index 27147b75d39..5aebee3b781 100644 --- a/apps/browser/src/tools/popup/settings/export/export-browser-v2.component.ts +++ b/apps/browser/src/tools/popup/settings/export/export-browser-v2.component.ts @@ -14,7 +14,6 @@ import { PopupPageComponent } from "../../../../platform/popup/layout/popup-page @Component({ templateUrl: "export-browser-v2.component.html", - standalone: true, imports: [ CommonModule, JslibModule, diff --git a/apps/browser/src/tools/popup/settings/import/import-browser-v2.component.ts b/apps/browser/src/tools/popup/settings/import/import-browser-v2.component.ts index 1c5558bd90e..506dae2fb18 100644 --- a/apps/browser/src/tools/popup/settings/import/import-browser-v2.component.ts +++ b/apps/browser/src/tools/popup/settings/import/import-browser-v2.component.ts @@ -13,7 +13,6 @@ import { PopupPageComponent } from "../../../../platform/popup/layout/popup-page @Component({ templateUrl: "import-browser-v2.component.html", - standalone: true, imports: [ CommonModule, JslibModule, diff --git a/apps/browser/src/tools/popup/settings/settings-v2.component.html b/apps/browser/src/tools/popup/settings/settings-v2.component.html index b6f98b649fe..0b2e84712a4 100644 --- a/apps/browser/src/tools/popup/settings/settings-v2.component.html +++ b/apps/browser/src/tools/popup/settings/settings-v2.component.html @@ -17,7 +17,16 @@ - {{ "autofill" | i18n }} +
+

{{ "autofill" | i18n }}

+ 1 +
@@ -32,7 +41,7 @@
@@ -42,9 +51,10 @@ Will make this dynamic when more nudges are added --> 1
@@ -54,7 +64,7 @@
- + {{ "appearance" | i18n }} @@ -66,5 +76,28 @@ + + + +
+

{{ "downloadBitwardenOnAllDevices" | i18n }}

+ 1 + +
+ +
+
+ + + + {{ "moreFromBitwarden" | i18n }} + + + diff --git a/apps/browser/src/tools/popup/settings/settings-v2.component.ts b/apps/browser/src/tools/popup/settings/settings-v2.component.ts index 737d79ea4ca..a0383b99390 100644 --- a/apps/browser/src/tools/popup/settings/settings-v2.component.ts +++ b/apps/browser/src/tools/popup/settings/settings-v2.component.ts @@ -1,23 +1,33 @@ import { CommonModule } from "@angular/common"; import { Component, OnInit } from "@angular/core"; import { RouterModule } from "@angular/router"; -import { firstValueFrom, Observable } from "rxjs"; +import { + combineLatest, + filter, + firstValueFrom, + map, + Observable, + shareReplay, + switchMap, +} from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; -import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { getUserId } from "@bitwarden/common/auth/services/account.service"; +import { NudgesService, NudgeType } from "@bitwarden/angular/vault"; +import { Account, AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { UserId } from "@bitwarden/common/types/guid"; import { BadgeComponent, ItemModule } from "@bitwarden/components"; -import { NudgeStatus, VaultNudgesService, VaultNudgeType } from "@bitwarden/vault"; import { CurrentAccountComponent } from "../../../auth/popup/account-switching/current-account.component"; +import { AutofillBrowserSettingsService } from "../../../autofill/services/autofill-browser-settings.service"; +import { BrowserApi } from "../../../platform/browser/browser-api"; import { PopOutComponent } from "../../../platform/popup/components/pop-out.component"; import { PopupHeaderComponent } from "../../../platform/popup/layout/popup-header.component"; import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.component"; @Component({ templateUrl: "settings-v2.component.html", - standalone: true, imports: [ CommonModule, JslibModule, @@ -31,25 +41,62 @@ import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.co ], }) export class SettingsV2Component implements OnInit { - VaultNudgeType = VaultNudgeType; - showVaultBadge$: Observable = new Observable(); + NudgeType = NudgeType; activeUserId: UserId | null = null; + protected isBrowserAutofillSettingOverridden = false; + + private authenticatedAccount$: Observable = this.accountService.activeAccount$.pipe( + filter((account): account is Account => account !== null), + shareReplay({ bufferSize: 1, refCount: true }), + ); + + showDownloadBitwardenNudge$: Observable = this.authenticatedAccount$.pipe( + switchMap((account) => + this.nudgesService.showNudgeBadge$(NudgeType.DownloadBitwarden, account.id), + ), + ); + + showVaultBadge$: Observable = this.authenticatedAccount$.pipe( + switchMap((account) => + this.nudgesService.showNudgeBadge$(NudgeType.EmptyVaultNudge, account.id), + ), + ); + + showAutofillBadge$: Observable = combineLatest([ + this.autofillBrowserSettingsService.defaultBrowserAutofillDisabled$, + this.authenticatedAccount$, + ]).pipe( + switchMap(([defaultBrowserAutofillDisabled, account]) => + this.nudgesService.showNudgeBadge$(NudgeType.AutofillNudge, account.id).pipe( + map((badgeStatus) => { + return !defaultBrowserAutofillDisabled && badgeStatus; + }), + ), + ), + ); + + protected isNudgeFeatureEnabled$ = this.configService.getFeatureFlag$( + FeatureFlag.PM8851_BrowserOnboardingNudge, + ); constructor( - private readonly vaultNudgesService: VaultNudgesService, + private readonly nudgesService: NudgesService, private readonly accountService: AccountService, + private readonly autofillBrowserSettingsService: AutofillBrowserSettingsService, + private readonly configService: ConfigService, ) {} + async ngOnInit() { - this.activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); - this.showVaultBadge$ = this.vaultNudgesService.showNudge$( - VaultNudgeType.EmptyVaultNudge, - this.activeUserId, - ); + this.isBrowserAutofillSettingOverridden = + await this.autofillBrowserSettingsService.isBrowserAutofillSettingOverridden( + BrowserApi.getBrowserClientVendor(window), + ); } - async dismissBadge(type: VaultNudgeType) { - if (!(await firstValueFrom(this.showVaultBadge$)).hasBadgeDismissed) { - await this.vaultNudgesService.dismissNudge(type, this.activeUserId as UserId, true); + async dismissBadge(type: NudgeType) { + if (await firstValueFrom(this.showVaultBadge$)) { + const account = await firstValueFrom(this.authenticatedAccount$); + await this.nudgesService.dismissNudge(type, account.id as UserId, true); } } } diff --git a/apps/browser/src/vault/guards/at-risk-passwords.guard.ts b/apps/browser/src/vault/guards/at-risk-passwords.guard.ts index 6bcdddfde81..fc302dd6c36 100644 --- a/apps/browser/src/vault/guards/at-risk-passwords.guard.ts +++ b/apps/browser/src/vault/guards/at-risk-passwords.guard.ts @@ -1,6 +1,6 @@ import { inject } from "@angular/core"; -import { CanActivateFn } from "@angular/router"; -import { switchMap, tap } from "rxjs"; +import { CanActivateFn, Router } from "@angular/router"; +import { map, switchMap } from "rxjs"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; @@ -13,18 +13,22 @@ export const canAccessAtRiskPasswords: CanActivateFn = () => { const taskService = inject(TaskService); const toastService = inject(ToastService); const i18nService = inject(I18nService); + const router = inject(Router); return accountService.activeAccount$.pipe( filterOutNullish(), switchMap((user) => taskService.tasksEnabled$(user.id)), - tap((tasksEnabled) => { + map((tasksEnabled) => { if (!tasksEnabled) { toastService.showToast({ variant: "error", title: "", - message: i18nService.t("accessDenied"), + message: i18nService.t("noPermissionsViewPage"), }); + + return router.createUrlTree(["/tabs/vault"]); } + return true; }), ); }; diff --git a/apps/browser/src/vault/popup/components/at-risk-callout/at-risk-password-callout.component.ts b/apps/browser/src/vault/popup/components/at-risk-callout/at-risk-password-callout.component.ts index ed78d9433f1..18482706272 100644 --- a/apps/browser/src/vault/popup/components/at-risk-callout/at-risk-password-callout.component.ts +++ b/apps/browser/src/vault/popup/components/at-risk-callout/at-risk-password-callout.component.ts @@ -11,7 +11,6 @@ import { I18nPipe } from "@bitwarden/ui-common"; @Component({ selector: "vault-at-risk-password-callout", - standalone: true, imports: [CommonModule, AnchorLinkDirective, RouterModule, CalloutModule, I18nPipe], templateUrl: "./at-risk-password-callout.component.html", }) diff --git a/apps/browser/src/vault/popup/components/at-risk-carousel-dialog/at-risk-carousel-dialog.component.ts b/apps/browser/src/vault/popup/components/at-risk-carousel-dialog/at-risk-carousel-dialog.component.ts index fcca125c2b6..4f6a682e58d 100644 --- a/apps/browser/src/vault/popup/components/at-risk-carousel-dialog/at-risk-carousel-dialog.component.ts +++ b/apps/browser/src/vault/popup/components/at-risk-carousel-dialog/at-risk-carousel-dialog.component.ts @@ -10,6 +10,8 @@ import { import { I18nPipe } from "@bitwarden/ui-common"; import { DarkImageSourceDirective, VaultCarouselModule } from "@bitwarden/vault"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum AtRiskCarouselDialogResult { Dismissed = "dismissed", } @@ -25,7 +27,6 @@ export enum AtRiskCarouselDialogResult { DarkImageSourceDirective, I18nPipe, ], - standalone: true, }) export class AtRiskCarouselDialogComponent { private dialogRef = inject(DialogRef); diff --git a/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.spec.ts b/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.spec.ts index ff583061684..dae00ba6c2b 100644 --- a/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.spec.ts +++ b/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.spec.ts @@ -35,7 +35,6 @@ import { AtRiskPasswordPageService } from "./at-risk-password-page.service"; import { AtRiskPasswordsComponent } from "./at-risk-passwords.component"; @Component({ - standalone: true, selector: "popup-header", template: ``, }) @@ -45,7 +44,6 @@ class MockPopupHeaderComponent { } @Component({ - standalone: true, selector: "popup-page", template: ``, }) @@ -54,7 +52,6 @@ class MockPopupPageComponent { } @Component({ - standalone: true, selector: "app-vault-icon", template: ``, }) diff --git a/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.ts b/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.ts index 1b43151193a..dc6712aa23f 100644 --- a/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.ts +++ b/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.ts @@ -79,7 +79,6 @@ import { AtRiskPasswordPageService } from "./at-risk-password-page.service"; { provide: ChangeLoginPasswordService, useClass: DefaultChangeLoginPasswordService }, ], selector: "vault-at-risk-passwords", - standalone: true, templateUrl: "./at-risk-passwords.component.html", }) export class AtRiskPasswordsComponent implements OnInit { diff --git a/apps/browser/src/vault/popup/components/vault-v2/add-edit/add-edit-v2.component.ts b/apps/browser/src/vault/popup/components/vault-v2/add-edit/add-edit-v2.component.ts index 30fd57a6bc6..a5a6a6f9922 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/add-edit/add-edit-v2.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/add-edit/add-edit-v2.component.ts @@ -14,6 +14,7 @@ import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { EventType } from "@bitwarden/common/enums"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; +import { Utils } from "@bitwarden/common/platform/misc/utils"; import { CipherId, CollectionId, OrganizationId, UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CipherType } from "@bitwarden/common/vault/enums"; @@ -40,6 +41,7 @@ import { } from "@bitwarden/vault"; import { BrowserFido2UserInterfaceSession } from "../../../../../autofill/fido2/services/browser-fido2-user-interface.service"; +import { BrowserApi } from "../../../../../platform/browser/browser-api"; import BrowserPopupUtils from "../../../../../platform/popup/browser-popup-utils"; import { PopOutComponent } from "../../../../../platform/popup/components/pop-out.component"; import { PopupFooterComponent } from "../../../../../platform/popup/layout/popup-footer.component"; @@ -70,6 +72,7 @@ class QueryParams { this.uri = params.uri; this.username = params.username; this.name = params.name; + this.prefillNameAndURIFromTab = params.prefillNameAndURIFromTab; } /** @@ -116,6 +119,12 @@ class QueryParams { * Optional name to pre-fill for the cipher. */ name?: string; + + /** + * Optional flag to pre-fill the name and URI from the current tab. + * NOTE: This will override the `uri` and `name` query parameters if set to true. + */ + prefillNameAndURIFromTab?: true; } export type AddEditQueryParams = Partial>; @@ -123,7 +132,6 @@ export type AddEditQueryParams = Partial>; @Component({ selector: "app-add-edit-v2", templateUrl: "add-edit-v2.component.html", - standalone: true, providers: [ { provide: CipherFormConfigService, useClass: DefaultCipherFormConfigService }, { provide: TotpCaptureService, useClass: BrowserTotpCaptureService }, @@ -281,8 +289,7 @@ export class AddEditV2Component implements OnInit { if (config.mode === "edit" && !config.originalCipher.edit) { config.mode = "partial-edit"; } - - config.initialValues = this.setInitialValuesFromParams(params); + config.initialValues = await this.setInitialValuesFromParams(params); const activeUserId = await firstValueFrom( this.accountService.activeAccount$.pipe(getUserId), @@ -326,7 +333,7 @@ export class AddEditV2Component implements OnInit { }); } - setInitialValuesFromParams(params: QueryParams) { + async setInitialValuesFromParams(params: QueryParams) { const initialValues = {} as OptionalInitialValues; if (params.folderId) { initialValues.folderId = params.folderId; @@ -346,6 +353,14 @@ export class AddEditV2Component implements OnInit { if (params.name) { initialValues.name = params.name; } + + if (params.prefillNameAndURIFromTab) { + const tab = await BrowserApi.getTabFromCurrentWindow(); + + initialValues.loginUri = tab.url; + initialValues.name = Utils.getHostname(tab.url); + } + return initialValues; } diff --git a/apps/browser/src/vault/popup/components/vault-v2/assign-collections/assign-collections.component.ts b/apps/browser/src/vault/popup/components/vault-v2/assign-collections/assign-collections.component.ts index 27f3b7e5e18..8374cc254a9 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/assign-collections/assign-collections.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/assign-collections/assign-collections.component.ts @@ -11,7 +11,6 @@ import { CollectionService } from "@bitwarden/admin-console/common"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { OrganizationId } from "@bitwarden/common/types/guid"; -import { OrgKey, UserKey } from "@bitwarden/common/types/key"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { @@ -29,7 +28,6 @@ import { PopupHeaderComponent } from "../../../../../platform/popup/layout/popup import { PopupPageComponent } from "../../../../../platform/popup/layout/popup-page.component"; @Component({ - standalone: true, selector: "app-assign-collections", templateUrl: "./assign-collections.component.html", imports: [ @@ -66,11 +64,7 @@ export class AssignCollections { route.queryParams.pipe( switchMap(async ({ cipherId }) => { const cipherDomain = await this.cipherService.get(cipherId, userId); - const key: UserKey | OrgKey = await this.cipherService.getKeyForCipherKeyDecryption( - cipherDomain, - userId, - ); - return cipherDomain.decrypt(key); + return await this.cipherService.decrypt(cipherDomain, userId); }), ), ), @@ -79,7 +73,7 @@ export class AssignCollections { combineLatest([cipher$, this.collectionService.decryptedCollections$]) .pipe(takeUntilDestroyed(), first()) .subscribe(([cipherView, collections]) => { - let availableCollections = collections.filter((c) => !c.readOnly); + let availableCollections = collections; const organizationId = (cipherView?.organizationId as OrganizationId) ?? null; // If the cipher is already a part of an organization, diff --git a/apps/browser/src/vault/popup/components/vault-v2/attachments/attachments-v2.component.spec.ts b/apps/browser/src/vault/popup/components/vault-v2/attachments/attachments-v2.component.spec.ts index 7c2cc99e300..6e4215c1ec2 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/attachments/attachments-v2.component.spec.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/attachments/attachments-v2.component.spec.ts @@ -26,7 +26,6 @@ import { PopupRouterCacheService } from "../../../../../platform/popup/view-cach import { AttachmentsV2Component } from "./attachments-v2.component"; @Component({ - standalone: true, selector: "popup-header", template: ``, }) @@ -36,7 +35,6 @@ class MockPopupHeaderComponent { } @Component({ - standalone: true, selector: "popup-footer", template: ``, }) diff --git a/apps/browser/src/vault/popup/components/vault-v2/attachments/attachments-v2.component.ts b/apps/browser/src/vault/popup/components/vault-v2/attachments/attachments-v2.component.ts index 32d446daf75..fc6d882dfd5 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/attachments/attachments-v2.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/attachments/attachments-v2.component.ts @@ -18,7 +18,6 @@ import { PopupPageComponent } from "../../../../../platform/popup/layout/popup-p import { PopupRouterCacheService } from "../../../../../platform/popup/view-cache/popup-router-cache.service"; @Component({ - standalone: true, selector: "app-attachments-v2", templateUrl: "./attachments-v2.component.html", imports: [ diff --git a/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.spec.ts b/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.spec.ts index 66d9096cd5c..ec5c93feb9e 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.spec.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.spec.ts @@ -81,6 +81,7 @@ describe("OpenAttachmentsComponent", () => { useValue: { get: getCipher, getKeyForCipherKeyDecryption: () => Promise.resolve(null), + decrypt: jest.fn().mockResolvedValue(cipherView), }, }, { diff --git a/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.ts b/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.ts index 1bc7e22e6d5..6577975ae0c 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.ts @@ -18,22 +18,15 @@ import { ProductTierType } from "@bitwarden/common/billing/enums"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { CipherId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; -import { - BadgeModule, - CardComponent, - ItemModule, - ToastService, - TypographyModule, -} from "@bitwarden/components"; +import { BadgeModule, ItemModule, ToastService, TypographyModule } from "@bitwarden/components"; import BrowserPopupUtils from "../../../../../../platform/popup/browser-popup-utils"; import { FilePopoutUtilsService } from "../../../../../../tools/popup/services/file-popout-utils.service"; @Component({ - standalone: true, selector: "app-open-attachments", templateUrl: "./open-attachments.component.html", - imports: [BadgeModule, CommonModule, ItemModule, JslibModule, TypographyModule, CardComponent], + imports: [BadgeModule, CommonModule, ItemModule, JslibModule, TypographyModule], }) export class OpenAttachmentsComponent implements OnInit { /** Cipher `id` */ @@ -81,9 +74,7 @@ export class OpenAttachmentsComponent implements OnInit { this.accountService.activeAccount$.pipe(map((a) => a?.id)), ); const cipherDomain = await this.cipherService.get(this.cipherId, activeUserId); - const cipher = await cipherDomain.decrypt( - await this.cipherService.getKeyForCipherKeyDecryption(cipherDomain, activeUserId), - ); + const cipher = await this.cipherService.decrypt(cipherDomain, activeUserId); if (!cipher.organizationId) { this.cipherIsAPartOfFreeOrg = false; diff --git a/apps/browser/src/vault/popup/components/vault-v2/autofill-vault-list-items/autofill-vault-list-items.component.ts b/apps/browser/src/vault/popup/components/vault-v2/autofill-vault-list-items/autofill-vault-list-items.component.ts index 72d51776f7b..b490d71df83 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/autofill-vault-list-items/autofill-vault-list-items.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/autofill-vault-list-items/autofill-vault-list-items.component.ts @@ -6,12 +6,7 @@ import { combineLatest, map, Observable } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { VaultSettingsService } from "@bitwarden/common/vault/abstractions/vault-settings/vault-settings.service"; import { CipherType } from "@bitwarden/common/vault/enums"; -import { - IconButtonModule, - SectionComponent, - SectionHeaderComponent, - TypographyModule, -} from "@bitwarden/components"; +import { IconButtonModule, TypographyModule } from "@bitwarden/components"; import BrowserPopupUtils from "../../../../../platform/popup/browser-popup-utils"; import { VaultPopupAutofillService } from "../../../services/vault-popup-autofill.service"; @@ -20,14 +15,11 @@ import { PopupCipherView } from "../../../views/popup-cipher.view"; import { VaultListItemsContainerComponent } from "../vault-list-items-container/vault-list-items-container.component"; @Component({ - standalone: true, imports: [ CommonModule, - SectionComponent, TypographyModule, VaultListItemsContainerComponent, JslibModule, - SectionHeaderComponent, IconButtonModule, ], selector: "app-autofill-vault-list-items", diff --git a/apps/browser/src/vault/popup/components/vault-v2/blocked-injection-banner/blocked-injection-banner.component.ts b/apps/browser/src/vault/popup/components/vault-v2/blocked-injection-banner/blocked-injection-banner.component.ts index 3a17825f4fb..5824e8d97ea 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/blocked-injection-banner/blocked-injection-banner.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/blocked-injection-banner/blocked-injection-banner.component.ts @@ -16,7 +16,6 @@ import { VaultPopupAutofillService } from "../../../services/vault-popup-autofil const blockedURISettingsRoute = "/blocked-domains"; @Component({ - standalone: true, imports: [ BannerModule, CommonModule, diff --git a/apps/browser/src/vault/popup/components/vault-v2/intro-carousel/intro-carousel.component.ts b/apps/browser/src/vault/popup/components/vault-v2/intro-carousel/intro-carousel.component.ts index 96e1a70306e..527f0f246af 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/intro-carousel/intro-carousel.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/intro-carousel/intro-carousel.component.ts @@ -20,7 +20,6 @@ import { IntroCarouselService } from "../../../services/intro-carousel.service"; JslibModule, I18nPipe, ], - standalone: true, }) export class IntroCarouselComponent { protected securityHandshake = VaultIcons.SecurityHandshake; diff --git a/apps/browser/src/vault/popup/components/vault-v2/item-copy-action/item-copy-actions.component.html b/apps/browser/src/vault/popup/components/vault-v2/item-copy-action/item-copy-actions.component.html index bb3a7b12096..576f6b7def6 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/item-copy-action/item-copy-actions.component.html +++ b/apps/browser/src/vault/popup/components/vault-v2/item-copy-action/item-copy-actions.component.html @@ -40,12 +40,9 @@ type="button" bitIconButton="bwi-clone" size="small" - [appA11yTitle]=" - 'copyFieldValue' | i18n: singleCopiableLogin.key : singleCopiableLogin.value - " - [appCopyClick]="singleCopiableLogin.value" - [valueLabel]="singleCopiableLogin.key" - showToast + [appA11yTitle]="singleCopiableLogin.key" + [appCopyField]="$any(singleCopiableLogin.field)" + [cipher]="cipher" > diff --git a/apps/browser/src/vault/popup/components/vault-v2/new-item-dropdown/new-item-dropdown-v2.component.spec.ts b/apps/browser/src/vault/popup/components/vault-v2/new-item-dropdown/new-item-dropdown-v2.component.spec.ts index a9b92274c9e..54c6ba2f788 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/new-item-dropdown/new-item-dropdown-v2.component.spec.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/new-item-dropdown/new-item-dropdown-v2.component.spec.ts @@ -94,8 +94,7 @@ describe("NewItemDropdownV2Component", () => { collectionId: "777-888-999", organizationId: "444-555-666", folderId: "222-333-444", - uri: "https://example.com", - name: "example.com", + prefillNameAndURIFromTab: "true", }); }); diff --git a/apps/browser/src/vault/popup/components/vault-v2/new-item-dropdown/new-item-dropdown-v2.component.ts b/apps/browser/src/vault/popup/components/vault-v2/new-item-dropdown/new-item-dropdown-v2.component.ts index bb452b89c7b..ef0b009025d 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/new-item-dropdown/new-item-dropdown-v2.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/new-item-dropdown/new-item-dropdown-v2.component.ts @@ -2,10 +2,9 @@ // @ts-strict-ignore import { CommonModule } from "@angular/common"; import { Component, Input, OnInit } from "@angular/core"; -import { Router, RouterLink } from "@angular/router"; +import { RouterLink } from "@angular/router"; import { JslibModule } from "@bitwarden/angular/jslib.module"; -import { Utils } from "@bitwarden/common/platform/misc/utils"; import { CollectionId, OrganizationId } from "@bitwarden/common/types/guid"; import { CipherType } from "@bitwarden/common/vault/enums"; import { ButtonModule, DialogService, MenuModule, NoItemsModule } from "@bitwarden/components"; @@ -24,7 +23,6 @@ export interface NewItemInitialValues { @Component({ selector: "app-new-item-dropdown", templateUrl: "new-item-dropdown-v2.component.html", - standalone: true, imports: [NoItemsModule, JslibModule, CommonModule, ButtonModule, RouterLink, MenuModule], }) export class NewItemDropdownV2Component implements OnInit { @@ -35,10 +33,8 @@ export class NewItemDropdownV2Component implements OnInit { */ @Input() initialValues: NewItemInitialValues; - constructor( - private router: Router, - private dialogService: DialogService, - ) {} + + constructor(private dialogService: DialogService) {} async ngOnInit() { this.tab = await BrowserApi.getTabFromCurrentWindow(); @@ -47,13 +43,12 @@ export class NewItemDropdownV2Component implements OnInit { buildQueryParams(type: CipherType): AddEditQueryParams { const poppedOut = BrowserPopupUtils.inPopout(window); - const loginDetails: { uri?: string; name?: string } = {}; + const loginDetails: { prefillNameAndURIFromTab?: string } = {}; // When a Login Cipher is created and the extension is not popped out, // pass along the uri and name if (!poppedOut && type === CipherType.Login && this.tab) { - loginDetails.uri = this.tab.url; - loginDetails.name = Utils.getHostname(this.tab.url); + loginDetails.prefillNameAndURIFromTab = "true"; } return { diff --git a/apps/browser/src/vault/popup/components/vault-v2/new-settings-callout/new-settings-callout.component.html b/apps/browser/src/vault/popup/components/vault-v2/new-settings-callout/new-settings-callout.component.html deleted file mode 100644 index 6cc60eed6d5..00000000000 --- a/apps/browser/src/vault/popup/components/vault-v2/new-settings-callout/new-settings-callout.component.html +++ /dev/null @@ -1,29 +0,0 @@ - - - -
- {{ "newCustomizationOptionsCalloutContent" | i18n }} - - {{ "newCustomizationOptionsCalloutLink" | i18n }} - -
-
-
diff --git a/apps/browser/src/vault/popup/components/vault-v2/new-settings-callout/new-settings-callout.component.ts b/apps/browser/src/vault/popup/components/vault-v2/new-settings-callout/new-settings-callout.component.ts deleted file mode 100644 index 713dc21c424..00000000000 --- a/apps/browser/src/vault/popup/components/vault-v2/new-settings-callout/new-settings-callout.component.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { CommonModule } from "@angular/common"; -import { Component, OnDestroy, OnInit } from "@angular/core"; -import { Router } from "@angular/router"; -import { firstValueFrom } from "rxjs"; - -import { JslibModule } from "@bitwarden/angular/jslib.module"; -import { VaultProfileService } from "@bitwarden/angular/vault/services/vault-profile.service"; -import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { getUserId } from "@bitwarden/common/auth/services/account.service"; -import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; -import { UserId } from "@bitwarden/common/types/guid"; -import { VaultSettingsService } from "@bitwarden/common/vault/abstractions/vault-settings/vault-settings.service"; -import { ButtonModule, PopoverModule } from "@bitwarden/components"; - -import { VaultPopupCopyButtonsService } from "../../../services/vault-popup-copy-buttons.service"; -import { VaultPageService } from "../vault-page.service"; - -@Component({ - selector: "new-settings-callout", - templateUrl: "new-settings-callout.component.html", - standalone: true, - imports: [PopoverModule, JslibModule, CommonModule, ButtonModule], - providers: [VaultPageService], -}) -export class NewSettingsCalloutComponent implements OnInit, OnDestroy { - protected showNewCustomizationSettingsCallout = false; - protected activeUserId: UserId | null = null; - - constructor( - private accountService: AccountService, - private vaultProfileService: VaultProfileService, - private vaultPageService: VaultPageService, - private router: Router, - private logService: LogService, - private copyButtonService: VaultPopupCopyButtonsService, - private vaultSettingsService: VaultSettingsService, - ) {} - - async ngOnInit() { - this.activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); - - const showQuickCopyActions = await firstValueFrom(this.copyButtonService.showQuickCopyActions$); - const clickItemsToAutofillVaultView = await firstValueFrom( - this.vaultSettingsService.clickItemsToAutofillVaultView$, - ); - - let profileCreatedDate: Date; - - try { - profileCreatedDate = await this.vaultProfileService.getProfileCreationDate(this.activeUserId); - } catch (e) { - this.logService.error("Error getting profile creation date", e); - // Default to before the cutoff date to ensure the callout is shown - profileCreatedDate = new Date("2024-12-24"); - } - - const hasCalloutBeenDismissed = await firstValueFrom( - this.vaultPageService.isCalloutDismissed(this.activeUserId), - ); - - this.showNewCustomizationSettingsCallout = - !showQuickCopyActions && - !clickItemsToAutofillVaultView && - !hasCalloutBeenDismissed && - profileCreatedDate < new Date("2024-12-25"); - } - - async goToAppearance() { - await this.router.navigate(["/appearance"]); - } - - async dismissCallout() { - if (this.activeUserId) { - await this.vaultPageService.dismissCallout(this.activeUserId); - } - } - - async ngOnDestroy() { - await this.dismissCallout(); - } -} diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-generator-dialog/vault-generator-dialog.component.spec.ts b/apps/browser/src/vault/popup/components/vault-v2/vault-generator-dialog/vault-generator-dialog.component.spec.ts index dd5f55a66ee..b5d35e2005e 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/vault-generator-dialog/vault-generator-dialog.component.spec.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/vault-generator-dialog/vault-generator-dialog.component.spec.ts @@ -21,7 +21,6 @@ import { @Component({ selector: "vault-cipher-form-generator", template: "", - standalone: true, }) class MockCipherFormGenerator { @Input() type: "password" | "username" = "password"; diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-generator-dialog/vault-generator-dialog.component.ts b/apps/browser/src/vault/popup/components/vault-v2/vault-generator-dialog/vault-generator-dialog.component.ts index 137f2a9dac3..f02ce46e931 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/vault-generator-dialog/vault-generator-dialog.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/vault-generator-dialog/vault-generator-dialog.component.ts @@ -30,6 +30,8 @@ export interface GeneratorDialogResult { generatedValue?: string; } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum GeneratorDialogAction { Selected = "selected", Canceled = "canceled", @@ -38,7 +40,6 @@ export enum GeneratorDialogAction { @Component({ selector: "app-vault-generator-dialog", templateUrl: "./vault-generator-dialog.component.html", - standalone: true, imports: [ PopupPageComponent, PopupHeaderComponent, diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-header/vault-header-v2.component.ts b/apps/browser/src/vault/popup/components/vault-v2/vault-header/vault-header-v2.component.ts index bcea2e76190..f64b5e6b83d 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/vault-header/vault-header-v2.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/vault-header/vault-header-v2.component.ts @@ -20,7 +20,6 @@ import { VaultV2SearchComponent } from "../vault-search/vault-v2-search.componen @Component({ selector: "app-vault-header-v2", templateUrl: "vault-header-v2.component.html", - standalone: true, imports: [ VaultV2SearchComponent, VaultListFiltersComponent, diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-list-filters/vault-list-filters.component.html b/apps/browser/src/vault/popup/components/vault-v2/vault-list-filters/vault-list-filters.component.html index c61562f9f90..ba4cbf71251 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/vault-list-filters/vault-list-filters.component.html +++ b/apps/browser/src/vault/popup/components/vault-v2/vault-list-filters/vault-list-filters.component.html @@ -20,7 +20,7 @@ *ngIf="collections.length" fullWidth formControlName="collection" - placeholderIcon="bwi-collection" + placeholderIcon="bwi-collection-shared" [placeholderText]="'collection' | i18n" [options]="collections" > diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-list-filters/vault-list-filters.component.ts b/apps/browser/src/vault/popup/components/vault-v2/vault-list-filters/vault-list-filters.component.ts index feccf92cec2..bc43a1d6a46 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/vault-list-filters/vault-list-filters.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/vault-list-filters/vault-list-filters.component.ts @@ -9,7 +9,6 @@ import { ChipSelectComponent } from "@bitwarden/components"; import { VaultPopupListFiltersService } from "../../../services/vault-popup-list-filters.service"; @Component({ - standalone: true, selector: "app-vault-list-filters", templateUrl: "./vault-list-filters.component.html", imports: [CommonModule, JslibModule, ChipSelectComponent, ReactiveFormsModule], diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-list-items-container/vault-list-items-container.component.ts b/apps/browser/src/vault/popup/components/vault-v2/vault-list-items-container/vault-list-items-container.component.ts index 6df1bdf8ae5..cef1ef8d2ff 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/vault-list-items-container/vault-list-items-container.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/vault-list-items-container/vault-list-items-container.component.ts @@ -74,11 +74,9 @@ import { ItemMoreOptionsComponent } from "../item-more-options/item-more-options ScrollingModule, DisclosureComponent, DisclosureTriggerForDirective, - DecryptionFailureDialogComponent, ], selector: "app-vault-list-items-container", templateUrl: "vault-list-items-container.component.html", - standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, }) export class VaultListItemsContainerComponent implements OnInit, AfterViewInit { diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-page.service.ts b/apps/browser/src/vault/popup/components/vault-v2/vault-page.service.ts deleted file mode 100644 index a7c52ed4c51..00000000000 --- a/apps/browser/src/vault/popup/components/vault-v2/vault-page.service.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { inject, Injectable } from "@angular/core"; -import { map, Observable } from "rxjs"; - -import { - BANNERS_DISMISSED_DISK, - StateProvider, - UserKeyDefinition, -} from "@bitwarden/common/platform/state"; -import { UserId } from "@bitwarden/common/types/guid"; - -export const NEW_CUSTOMIZATION_OPTIONS_CALLOUT_DISMISSED_KEY = new UserKeyDefinition( - BANNERS_DISMISSED_DISK, - "newCustomizationOptionsCalloutDismissed", - { - deserializer: (calloutDismissed) => calloutDismissed, - clearOn: [], // Do not clear dismissed callouts - }, -); - -@Injectable() -export class VaultPageService { - private stateProvider = inject(StateProvider); - - isCalloutDismissed(userId: UserId): Observable { - return this.stateProvider - .getUser(userId, NEW_CUSTOMIZATION_OPTIONS_CALLOUT_DISMISSED_KEY) - .state$.pipe(map((dismissed) => !!dismissed)); - } - - async dismissCallout(userId: UserId): Promise { - await this.stateProvider - .getUser(userId, NEW_CUSTOMIZATION_OPTIONS_CALLOUT_DISMISSED_KEY) - .update(() => true); - } -} diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-password-history-v2/vault-password-history-v2.component.ts b/apps/browser/src/vault/popup/components/vault-v2/vault-password-history-v2/vault-password-history-v2.component.ts index 5d315775b10..f2764df7ba7 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/vault-password-history-v2/vault-password-history-v2.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/vault-password-history-v2/vault-password-history-v2.component.ts @@ -19,7 +19,6 @@ import { PopupPageComponent } from "../../../../../platform/popup/layout/popup-p import { PopupRouterCacheService } from "../../../../../platform/popup/view-cache/popup-router-cache.service"; @Component({ - standalone: true, selector: "vault-password-history-v2", templateUrl: "vault-password-history-v2.component.html", imports: [ @@ -69,8 +68,6 @@ export class PasswordHistoryV2Component implements OnInit { const activeUserId = activeAccount.id as UserId; const cipher = await this.cipherService.get(cipherId, activeUserId); - this.cipher = await cipher.decrypt( - await this.cipherService.getKeyForCipherKeyDecryption(cipher, activeUserId), - ); + this.cipher = await this.cipherService.decrypt(cipher, activeUserId); } } diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-search/vault-v2-search.component.ts b/apps/browser/src/vault/popup/components/vault-v2/vault-search/vault-v2-search.component.ts index 32f5611f436..fe2baf463cf 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/vault-search/vault-v2-search.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/vault-search/vault-v2-search.component.ts @@ -1,8 +1,8 @@ import { CommonModule } from "@angular/common"; -import { Component } from "@angular/core"; +import { Component, NgZone } from "@angular/core"; import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; import { FormsModule } from "@angular/forms"; -import { Subject, Subscription, debounceTime, filter } from "rxjs"; +import { Subject, Subscription, debounceTime, distinctUntilChanged, filter } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { SearchModule } from "@bitwarden/components"; @@ -13,7 +13,6 @@ const SearchTextDebounceInterval = 200; @Component({ imports: [CommonModule, SearchModule, JslibModule, FormsModule], - standalone: true, selector: "app-vault-v2-search", templateUrl: "vault-v2-search.component.html", }) @@ -22,13 +21,16 @@ export class VaultV2SearchComponent { private searchText$ = new Subject(); - constructor(private vaultPopupItemsService: VaultPopupItemsService) { + constructor( + private vaultPopupItemsService: VaultPopupItemsService, + private ngZone: NgZone, + ) { this.subscribeToLatestSearchText(); this.subscribeToApplyFilter(); } onSearchTextChanged() { - this.vaultPopupItemsService.applyFilter(this.searchText); + this.searchText$.next(this.searchText); } subscribeToLatestSearchText(): Subscription { @@ -44,9 +46,13 @@ export class VaultV2SearchComponent { subscribeToApplyFilter(): Subscription { return this.searchText$ - .pipe(debounceTime(SearchTextDebounceInterval), takeUntilDestroyed()) + .pipe(debounceTime(SearchTextDebounceInterval), distinctUntilChanged(), takeUntilDestroyed()) .subscribe((data) => { - this.vaultPopupItemsService.applyFilter(data); + this.ngZone.runOutsideAngular(() => { + this.ngZone.run(() => { + this.vaultPopupItemsService.applyFilter(data); + }); + }); }); } } diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.html b/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.html index 894f27245b2..42e772be062 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.html +++ b/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.html @@ -36,7 +36,7 @@ [subtitle]="'emptyVaultNudgeBody' | i18n" [buttonText]="'emptyVaultNudgeButton' | i18n" (onButtonClick)="navigateToImport()" - (onDismiss)="dismissVaultNudgeSpotlight(VaultNudgeType.EmptyVaultNudge)" + (onDismiss)="dismissVaultNudgeSpotlight(NudgeType.EmptyVaultNudge)" >
@@ -44,9 +44,13 @@
+
    +
  • {{ "hasItemsVaultNudgeBodyOne" | i18n }}
  • +
  • {{ "hasItemsVaultNudgeBodyTwo" | i18n }}
  • +
  • {{ "hasItemsVaultNudgeBodyThree" | i18n }}
  • +
- diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.ts b/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.ts index 64805a02394..9310953dbb7 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.ts @@ -16,20 +16,22 @@ import { } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { NudgesService, NudgeType } from "@bitwarden/angular/vault"; +import { SpotlightComponent } from "@bitwarden/angular/vault/components/spotlight/spotlight.component"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { CipherId, CollectionId, OrganizationId, UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CipherType } from "@bitwarden/common/vault/enums"; -import { ButtonModule, DialogService, Icons, NoItemsModule } from "@bitwarden/components"; import { - DecryptionFailureDialogComponent, - SpotlightComponent, - VaultIcons, - VaultNudgesService, - VaultNudgeType, -} from "@bitwarden/vault"; + ButtonModule, + DialogService, + Icons, + NoItemsModule, + TypographyModule, +} from "@bitwarden/components"; +import { DecryptionFailureDialogComponent, VaultIcons } from "@bitwarden/vault"; import { CurrentAccountComponent } from "../../../../auth/popup/account-switching/current-account.component"; import { BrowserApi } from "../../../../platform/browser/browser-api"; @@ -49,12 +51,12 @@ import { NewItemDropdownV2Component, NewItemInitialValues, } from "./new-item-dropdown/new-item-dropdown-v2.component"; -import { NewSettingsCalloutComponent } from "./new-settings-callout/new-settings-callout.component"; import { VaultHeaderV2Component } from "./vault-header/vault-header-v2.component"; -import { VaultPageService } from "./vault-page.service"; import { AutofillVaultListItemsComponent, VaultListItemsContainerComponent } from "."; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums enum VaultState { Empty, NoResults, @@ -64,7 +66,6 @@ enum VaultState { @Component({ selector: "app-vault", templateUrl: "vault-v2.component.html", - standalone: true, imports: [ BlockedInjectionBanner, PopupPageComponent, @@ -81,27 +82,24 @@ enum VaultState { ScrollingModule, VaultHeaderV2Component, AtRiskPasswordCalloutComponent, - NewSettingsCalloutComponent, SpotlightComponent, RouterModule, + TypographyModule, ], - providers: [VaultPageService], }) export class VaultV2Component implements OnInit, AfterViewInit, OnDestroy { @ViewChild(CdkVirtualScrollableElement) virtualScrollElement?: CdkVirtualScrollableElement; - VaultNudgeType = VaultNudgeType; + NudgeType = NudgeType; cipherType = CipherType; private activeUserId$ = this.accountService.activeAccount$.pipe(getUserId); showEmptyVaultSpotlight$: Observable = this.activeUserId$.pipe( switchMap((userId) => - this.vaultNudgesService.showNudge$(VaultNudgeType.EmptyVaultNudge, userId), + this.nudgesService.showNudgeSpotlight$(NudgeType.EmptyVaultNudge, userId), ), - map((nudgeStatus) => !nudgeStatus.hasSpotlightDismissed), ); showHasItemsVaultSpotlight$: Observable = this.activeUserId$.pipe( - switchMap((userId) => this.vaultNudgesService.showNudge$(VaultNudgeType.HasVaultItems, userId)), - map((nudgeStatus) => !nudgeStatus.hasSpotlightDismissed), + switchMap((userId) => this.nudgesService.showNudgeSpotlight$(NudgeType.HasVaultItems, userId)), ); activeUserId: UserId | null = null; @@ -142,7 +140,6 @@ export class VaultV2Component implements OnInit, AfterViewInit, OnDestroy { protected noResultsIcon = Icons.NoResults; protected VaultStateEnum = VaultState; - protected showNewCustomizationSettingsCallout = false; constructor( private vaultPopupItemsService: VaultPopupItemsService, @@ -154,7 +151,7 @@ export class VaultV2Component implements OnInit, AfterViewInit, OnDestroy { private dialogService: DialogService, private vaultCopyButtonsService: VaultPopupCopyButtonsService, private introCarouselService: IntroCarouselService, - private vaultNudgesService: VaultNudgesService, + private nudgesService: NudgesService, private router: Router, ) { combineLatest([ @@ -223,8 +220,8 @@ export class VaultV2Component implements OnInit, AfterViewInit, OnDestroy { } } - async dismissVaultNudgeSpotlight(type: VaultNudgeType) { - await this.vaultNudgesService.dismissNudge(type, this.activeUserId as UserId); + async dismissVaultNudgeSpotlight(type: NudgeType) { + await this.nudgesService.dismissNudge(type, this.activeUserId as UserId); } protected readonly FeatureFlag = FeatureFlag; diff --git a/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.spec.ts b/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.spec.ts index 44874221a59..3222f39a162 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.spec.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.spec.ts @@ -82,6 +82,7 @@ describe("ViewV2Component", () => { getKeyForCipherKeyDecryption: jest.fn().mockResolvedValue({}), deleteWithServer: jest.fn().mockResolvedValue(undefined), softDeleteWithServer: jest.fn().mockResolvedValue(undefined), + decrypt: jest.fn().mockResolvedValue(mockCipher), }; beforeEach(async () => { diff --git a/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.ts b/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.ts index 56db47619b0..77b1819e29d 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.ts @@ -19,6 +19,7 @@ import { COPY_USERNAME_ID, COPY_VERIFICATION_CODE_ID, SHOW_AUTOFILL_BUTTON, + UPDATE_PASSWORD, } from "@bitwarden/common/autofill/constants"; import { EventType } from "@bitwarden/common/enums"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; @@ -49,6 +50,7 @@ import { PasswordRepromptService, } from "@bitwarden/vault"; +import { sendExtensionMessage } from "../../../../../autofill/utils/index"; import { BrowserApi } from "../../../../../platform/browser/browser-api"; import BrowserPopupUtils from "../../../../../platform/popup/browser-popup-utils"; import { PopOutComponent } from "../../../../../platform/popup/components/pop-out.component"; @@ -72,12 +74,12 @@ type LoadAction = | typeof SHOW_AUTOFILL_BUTTON | typeof COPY_USERNAME_ID | typeof COPY_PASSWORD_ID - | typeof COPY_VERIFICATION_CODE_ID; + | typeof COPY_VERIFICATION_CODE_ID + | typeof UPDATE_PASSWORD; @Component({ selector: "app-view-v2", templateUrl: "view-v2.component.html", - standalone: true, imports: [ CommonModule, SearchModule, @@ -200,9 +202,7 @@ export class ViewV2Component { async getCipherData(id: string, userId: UserId) { const cipher = await this.cipherService.get(id, userId); - return await cipher.decrypt( - await this.cipherService.getKeyForCipherKeyDecryption(cipher, userId), - ); + return await this.cipherService.decrypt(cipher, userId); } async editCipher() { @@ -294,7 +294,7 @@ export class ViewV2Component { // Both vaultPopupAutofillService and copyCipherFieldService will perform password re-prompting internally. switch (loadAction) { - case "show-autofill-button": + case SHOW_AUTOFILL_BUTTON: // This action simply shows the cipher view, no need to do anything. if ( this.cipher.reprompt !== CipherRepromptType.None && @@ -303,30 +303,42 @@ export class ViewV2Component { await closeViewVaultItemPopout(`${VaultPopoutType.viewVaultItem}_${this.cipher.id}`); } return; - case "autofill": + case AUTOFILL_ID: actionSuccess = await this.vaultPopupAutofillService.doAutofill(this.cipher, false); break; - case "copy-username": + case COPY_USERNAME_ID: actionSuccess = await this.copyCipherFieldService.copy( this.cipher.login.username, "username", this.cipher, ); break; - case "copy-password": + case COPY_PASSWORD_ID: actionSuccess = await this.copyCipherFieldService.copy( this.cipher.login.password, "password", this.cipher, ); break; - case "copy-totp": + case COPY_VERIFICATION_CODE_ID: actionSuccess = await this.copyCipherFieldService.copy( this.cipher.login.totp, "totp", this.cipher, ); break; + case UPDATE_PASSWORD: { + const repromptSuccess = await this.passwordRepromptService.showPasswordPrompt(); + + await sendExtensionMessage("bgHandleReprompt", { + tab: await chrome.tabs.get(senderTabId), + success: repromptSuccess, + }); + + await closeViewVaultItemPopout(`${VaultPopoutType.viewVaultItem}_${this.cipher.id}`); + + break; + } } if (BrowserPopupUtils.inPopout(window)) { diff --git a/apps/browser/src/vault/popup/services/vault-popup-autofill.service.spec.ts b/apps/browser/src/vault/popup/services/vault-popup-autofill.service.spec.ts index 415aeb31081..73c3fed3276 100644 --- a/apps/browser/src/vault/popup/services/vault-popup-autofill.service.spec.ts +++ b/apps/browser/src/vault/popup/services/vault-popup-autofill.service.spec.ts @@ -353,7 +353,7 @@ describe("VaultPopupAutofillService", () => { }); it("should add a URI to the cipher and save with the server", async () => { - const mockEncryptedCipher = {} as Cipher; + const mockEncryptedCipher = { cipher: {} as Cipher, encryptedFor: mockUserId }; mockCipherService.encrypt.mockResolvedValue(mockEncryptedCipher); const result = await service.doAutofillAndSave(mockCipher); expect(result).toBe(true); diff --git a/apps/browser/src/vault/popup/services/vault-popup-items.service.spec.ts b/apps/browser/src/vault/popup/services/vault-popup-items.service.spec.ts index 52cb393c684..a573f99d3c1 100644 --- a/apps/browser/src/vault/popup/services/vault-popup-items.service.spec.ts +++ b/apps/browser/src/vault/popup/services/vault-popup-items.service.spec.ts @@ -1,5 +1,5 @@ import { WritableSignal, signal } from "@angular/core"; -import { TestBed, discardPeriodicTasks, fakeAsync, tick } from "@angular/core/testing"; +import { TestBed } from "@angular/core/testing"; import { mock } from "jest-mock-extended"; import { BehaviorSubject, firstValueFrom, timeout } from "rxjs"; @@ -483,22 +483,15 @@ describe("VaultPopupItemsService", () => { }); }); - it("should update searchText$ when applyFilter is called", fakeAsync(() => { - let latestValue: string | null; + it("should update searchText$ when applyFilter is called", (done) => { service.searchText$.subscribe((val) => { - latestValue = val; + expect(val).toEqual("test search"); + expect(viewCacheService.mockSignal()).toEqual("test search"); + done(); }); - tick(); - expect(latestValue!).toEqual(""); service.applyFilter("test search"); - tick(); - expect(latestValue!).toEqual("test search"); - - expect(viewCacheService.mockSignal()).toEqual("test search"); - - discardPeriodicTasks(); - })); + }); }); // A function to generate a list of ciphers of different types diff --git a/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.spec.ts b/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.spec.ts index f9785bccd00..621ec795157 100644 --- a/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.spec.ts +++ b/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.spec.ts @@ -4,6 +4,7 @@ import { FormBuilder } from "@angular/forms"; import { BehaviorSubject, skipWhile } from "rxjs"; import { CollectionService, CollectionView } from "@bitwarden/admin-console/common"; +import { ViewCacheService } from "@bitwarden/angular/platform/view-cache"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { PolicyType } from "@bitwarden/common/admin-console/enums"; @@ -20,8 +21,6 @@ import { CipherType } from "@bitwarden/common/vault/enums"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { FolderView } from "@bitwarden/common/vault/models/view/folder.view"; -import { PopupViewCacheService } from "../../../platform/popup/view-cache/popup-view-cache.service"; - import { CachedFilterState, MY_VAULT_ID, @@ -123,7 +122,7 @@ describe("VaultPopupListFiltersService", () => { useValue: accountService, }, { - provide: PopupViewCacheService, + provide: ViewCacheService, useValue: viewCacheService, }, ], @@ -362,7 +361,7 @@ describe("VaultPopupListFiltersService", () => { it("sets collection icon", (done) => { service.collections$.subscribe((collections) => { - expect(collections.every(({ icon }) => icon === "bwi-collection")).toBeTruthy(); + expect(collections.every(({ icon }) => icon === "bwi-collection-shared")).toBeTruthy(); done(); }); }); diff --git a/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.ts b/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.ts index f11fa0f63f0..db4cfeefe9f 100644 --- a/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.ts +++ b/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.ts @@ -15,6 +15,7 @@ import { } from "rxjs"; import { CollectionService, CollectionView } from "@bitwarden/admin-console/common"; +import { ViewCacheService } from "@bitwarden/angular/platform/view-cache"; import { DynamicTreeNode } from "@bitwarden/angular/vault/vault-filter/models/dynamic-tree-node.model"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; @@ -40,8 +41,6 @@ import { FolderView } from "@bitwarden/common/vault/models/view/folder.view"; import { ServiceUtils } from "@bitwarden/common/vault/service-utils"; import { ChipSelectOption } from "@bitwarden/components"; -import { PopupViewCacheService } from "../../../platform/popup/view-cache/popup-view-cache.service"; - const FILTER_VISIBILITY_KEY = new KeyDefinition(VAULT_SETTINGS_DISK, "filterVisibility", { deserializer: (obj) => obj, }); @@ -178,7 +177,7 @@ export class VaultPopupListFiltersService { private policyService: PolicyService, private stateProvider: StateProvider, private accountService: AccountService, - private viewCacheService: PopupViewCacheService, + private viewCacheService: ViewCacheService, ) { this.filterForm.controls.organization.valueChanges .pipe(takeUntilDestroyed()) @@ -461,7 +460,7 @@ export class VaultPopupListFiltersService { }); }), map((collections) => - collections.nestedList.map((c) => this.convertToChipSelectOption(c, "bwi-collection")), + collections.nestedList.map((c) => this.convertToChipSelectOption(c, "bwi-collection-shared")), ), shareReplay({ refCount: true, bufferSize: 1 }), ); diff --git a/apps/browser/src/vault/popup/settings/appearance-v2.component.spec.ts b/apps/browser/src/vault/popup/settings/appearance-v2.component.spec.ts index 30715ebaedf..738ec3ae1ff 100644 --- a/apps/browser/src/vault/popup/settings/appearance-v2.component.spec.ts +++ b/apps/browser/src/vault/popup/settings/appearance-v2.component.spec.ts @@ -23,7 +23,6 @@ import { VaultPopupCopyButtonsService } from "../services/vault-popup-copy-butto import { AppearanceV2Component } from "./appearance-v2.component"; @Component({ - standalone: true, selector: "popup-header", template: ``, }) @@ -33,7 +32,6 @@ class MockPopupHeaderComponent { } @Component({ - standalone: true, selector: "popup-page", template: ``, }) diff --git a/apps/browser/src/vault/popup/settings/appearance-v2.component.ts b/apps/browser/src/vault/popup/settings/appearance-v2.component.ts index 1462a2d7ab4..2a38d281396 100644 --- a/apps/browser/src/vault/popup/settings/appearance-v2.component.ts +++ b/apps/browser/src/vault/popup/settings/appearance-v2.component.ts @@ -35,7 +35,6 @@ import { import { VaultPopupCopyButtonsService } from "../services/vault-popup-copy-buttons.service"; @Component({ - standalone: true, templateUrl: "./appearance-v2.component.html", imports: [ CommonModule, diff --git a/apps/browser/src/vault/popup/settings/download-bitwarden.component.html b/apps/browser/src/vault/popup/settings/download-bitwarden.component.html new file mode 100644 index 00000000000..20896a3c782 --- /dev/null +++ b/apps/browser/src/vault/popup/settings/download-bitwarden.component.html @@ -0,0 +1,64 @@ + + + + + + +

+ {{ "getTheMobileApp" | i18n }} +

+ + + {{ "getTheMobileAppDesc" | i18n }} + +
+ +
+ +
+ +

+ {{ "getTheDesktopApp" | i18n }} +

+ + {{ "getTheDesktopAppDesc" | i18n }} + + {{ "downloadFromBitwardenNow" | i18n }} + + + +
diff --git a/apps/browser/src/vault/popup/settings/download-bitwarden.component.ts b/apps/browser/src/vault/popup/settings/download-bitwarden.component.ts new file mode 100644 index 00000000000..d23d00a1ad7 --- /dev/null +++ b/apps/browser/src/vault/popup/settings/download-bitwarden.component.ts @@ -0,0 +1,40 @@ +import { CommonModule } from "@angular/common"; +import { Component, OnInit } from "@angular/core"; +import { RouterModule } from "@angular/router"; +import { firstValueFrom } from "rxjs"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { NudgesService, NudgeType } from "@bitwarden/angular/vault"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { getUserId } from "@bitwarden/common/auth/services/account.service"; +import { CardComponent, LinkModule, TypographyModule } from "@bitwarden/components"; + +import { PopOutComponent } from "../../../platform/popup/components/pop-out.component"; +import { PopupHeaderComponent } from "../../../platform/popup/layout/popup-header.component"; +import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.component"; + +@Component({ + templateUrl: "download-bitwarden.component.html", + imports: [ + CommonModule, + JslibModule, + RouterModule, + PopupPageComponent, + PopupHeaderComponent, + PopOutComponent, + CardComponent, + TypographyModule, + LinkModule, + ], +}) +export class DownloadBitwardenComponent implements OnInit { + constructor( + private nudgesService: NudgesService, + private accountService: AccountService, + ) {} + + async ngOnInit() { + const userId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + await this.nudgesService.dismissNudge(NudgeType.DownloadBitwarden, userId); + } +} diff --git a/apps/browser/src/vault/popup/settings/folders-v2.component.html b/apps/browser/src/vault/popup/settings/folders-v2.component.html index 552547c0230..8cea05f9c17 100644 --- a/apps/browser/src/vault/popup/settings/folders-v2.component.html +++ b/apps/browser/src/vault/popup/settings/folders-v2.component.html @@ -8,7 +8,7 @@ type="button" (click)="openAddEditFolderDialog()" > - + {{ "new" | i18n }} @@ -47,7 +47,7 @@ (click)="openAddEditFolderDialog()" data-testid="empty-new-folder-button" > - + {{ "newFolder" | i18n }} diff --git a/apps/browser/src/vault/popup/settings/folders-v2.component.spec.ts b/apps/browser/src/vault/popup/settings/folders-v2.component.spec.ts index 6689f5a6c6d..d1450667fa8 100644 --- a/apps/browser/src/vault/popup/settings/folders-v2.component.spec.ts +++ b/apps/browser/src/vault/popup/settings/folders-v2.component.spec.ts @@ -22,7 +22,6 @@ import { PopupHeaderComponent } from "../../../platform/popup/layout/popup-heade import { FoldersV2Component } from "./folders-v2.component"; @Component({ - standalone: true, selector: "popup-header", template: ``, }) @@ -32,7 +31,6 @@ class MockPopupHeaderComponent { } @Component({ - standalone: true, selector: "popup-footer", template: ``, }) diff --git a/apps/browser/src/vault/popup/settings/folders-v2.component.ts b/apps/browser/src/vault/popup/settings/folders-v2.component.ts index f71374e5305..2264415f4fa 100644 --- a/apps/browser/src/vault/popup/settings/folders-v2.component.ts +++ b/apps/browser/src/vault/popup/settings/folders-v2.component.ts @@ -22,7 +22,6 @@ import { PopupHeaderComponent } from "../../../platform/popup/layout/popup-heade import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.component"; @Component({ - standalone: true, templateUrl: "./folders-v2.component.html", imports: [ CommonModule, diff --git a/apps/browser/src/tools/popup/settings/about-page/more-from-bitwarden-page-v2.component.html b/apps/browser/src/vault/popup/settings/more-from-bitwarden-page-v2.component.html similarity index 100% rename from apps/browser/src/tools/popup/settings/about-page/more-from-bitwarden-page-v2.component.html rename to apps/browser/src/vault/popup/settings/more-from-bitwarden-page-v2.component.html diff --git a/apps/browser/src/tools/popup/settings/about-page/more-from-bitwarden-page-v2.component.ts b/apps/browser/src/vault/popup/settings/more-from-bitwarden-page-v2.component.ts similarity index 90% rename from apps/browser/src/tools/popup/settings/about-page/more-from-bitwarden-page-v2.component.ts rename to apps/browser/src/vault/popup/settings/more-from-bitwarden-page-v2.component.ts index a3d1c553977..ec7a73a3bc3 100644 --- a/apps/browser/src/tools/popup/settings/about-page/more-from-bitwarden-page-v2.component.ts +++ b/apps/browser/src/vault/popup/settings/more-from-bitwarden-page-v2.component.ts @@ -11,15 +11,14 @@ import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abs import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; import { DialogService, ItemModule } from "@bitwarden/components"; -import { FamiliesPolicyService } from "../../../../billing/services/families-policy.service"; -import { BrowserApi } from "../../../../platform/browser/browser-api"; -import { PopOutComponent } from "../../../../platform/popup/components/pop-out.component"; -import { PopupHeaderComponent } from "../../../../platform/popup/layout/popup-header.component"; -import { PopupPageComponent } from "../../../../platform/popup/layout/popup-page.component"; +import { FamiliesPolicyService } from "../../../billing/services/families-policy.service"; +import { BrowserApi } from "../../../platform/browser/browser-api"; +import { PopOutComponent } from "../../../platform/popup/components/pop-out.component"; +import { PopupHeaderComponent } from "../../../platform/popup/layout/popup-header.component"; +import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.component"; @Component({ templateUrl: "more-from-bitwarden-page-v2.component.html", - standalone: true, imports: [ CommonModule, JslibModule, diff --git a/apps/browser/src/vault/popup/settings/trash-list-items-container/trash-list-items-container.component.ts b/apps/browser/src/vault/popup/settings/trash-list-items-container/trash-list-items-container.component.ts index cbfc89bf922..0f025ebe3f4 100644 --- a/apps/browser/src/vault/popup/settings/trash-list-items-container/trash-list-items-container.component.ts +++ b/apps/browser/src/vault/popup/settings/trash-list-items-container/trash-list-items-container.component.ts @@ -37,7 +37,6 @@ import { PopupCipherView } from "../../views/popup-cipher.view"; @Component({ selector: "app-trash-list-items-container", templateUrl: "trash-list-items-container.component.html", - standalone: true, imports: [ CommonModule, ItemModule, @@ -49,7 +48,6 @@ import { PopupCipherView } from "../../views/popup-cipher.view"; IconButtonModule, OrgIconDirective, TypographyModule, - DecryptionFailureDialogComponent, ], changeDetection: ChangeDetectionStrategy.OnPush, }) diff --git a/apps/browser/src/vault/popup/settings/trash.component.ts b/apps/browser/src/vault/popup/settings/trash.component.ts index 61843de31bc..d6e5f899bba 100644 --- a/apps/browser/src/vault/popup/settings/trash.component.ts +++ b/apps/browser/src/vault/popup/settings/trash.component.ts @@ -14,7 +14,6 @@ import { TrashListItemsContainerComponent } from "./trash-list-items-container/t @Component({ templateUrl: "trash.component.html", - standalone: true, imports: [ CommonModule, JslibModule, diff --git a/apps/browser/src/vault/popup/settings/vault-settings-v2.component.ts b/apps/browser/src/vault/popup/settings/vault-settings-v2.component.ts index c969f0436df..9efdc568997 100644 --- a/apps/browser/src/vault/popup/settings/vault-settings-v2.component.ts +++ b/apps/browser/src/vault/popup/settings/vault-settings-v2.component.ts @@ -10,19 +10,16 @@ import { ItemModule, ToastOptions, ToastService } from "@bitwarden/components"; import { BrowserApi } from "../../../platform/browser/browser-api"; import BrowserPopupUtils from "../../../platform/popup/browser-popup-utils"; import { PopOutComponent } from "../../../platform/popup/components/pop-out.component"; -import { PopupFooterComponent } from "../../../platform/popup/layout/popup-footer.component"; import { PopupHeaderComponent } from "../../../platform/popup/layout/popup-header.component"; import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.component"; @Component({ templateUrl: "vault-settings-v2.component.html", - standalone: true, imports: [ CommonModule, JslibModule, RouterModule, PopupPageComponent, - PopupFooterComponent, PopupHeaderComponent, PopOutComponent, ItemModule, diff --git a/apps/browser/store/locales/fa/copy.resx b/apps/browser/store/locales/fa/copy.resx index 69816ce3590..2d45e114719 100644 --- a/apps/browser/store/locales/fa/copy.resx +++ b/apps/browser/store/locales/fa/copy.resx @@ -118,58 +118,58 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - مدیریت رمز عبور Bitwarden + مدیر کلمه عبور Bitwarden - در خانه، محل کار، یا در حال حرکت، Bitwarden به سادگی تمامی رمزهای عبور، passkeyها، و اطلاعات حساس شما را امن نگاه می‌دارد. + در خانه، محل کار، یا در حال حرکت، 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 به‌طور منظم توسط شرکت‌های معتبر امنیتی مورد ارزیابی و تست نفوذ قرار می‌گیرد. این بررسی‌ها شامل بررسی کد منبع و تست‌های امنیتی روی IPها، سرورها و اپلیکیشن‌های وب Bitwarden است. -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. +احراز هویت دومرحله‌ای پیشرفته (2FA) + ورود امن با استفاده از احراز هویت‌کننده‌های شخص ثالث، کدهای ایمیلی، یا گواهی‌نامه‌های 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 به بیش از ۶۰ زبان در دسترس است که توسط جامعه جهانی از طریق Crowdin ترجمه شده‌اند. -Cross-Platform Applications -Secure and share sensitive data within your Bitwarden Vault from any browser, mobile device, or desktop OS, and more. +اپلیکیشن‌های چند سکویی + ایمن‌سازی و اشتراک‌گذاری داده‌ها از طریق هر مرورگر، دستگاه موبایل یا سیستم‌عامل دسکتاپ و موارد دیگر. -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 Secrets Manager و Bitwarden Passwordless.dev به وب‌سایت Bitwarden.com مراجعه کنید! - در خانه، محل کار، یا در حال حرکت، Bitwarden به سادگی تمامی رمزهای عبور، passkeyها، و اطلاعات حساس شما را امن نگاه می‌دارد. + در خانه، محل کار، یا در حال حرکت، Bitwarden به سادگی تمامی کلمات عبور، کلیدها، و اطلاعات حساس شما را امن نگاه می‌دارد. همگام‌سازی و دسترسی به گاوصندوق خود از دستگاه های مختلف diff --git a/apps/browser/store/locales/vi/copy.resx b/apps/browser/store/locales/vi/copy.resx index f1a65d0fed5..c262c9bffd7 100644 --- a/apps/browser/store/locales/vi/copy.resx +++ b/apps/browser/store/locales/vi/copy.resx @@ -121,7 +121,7 @@ Trình quản lý mật khẩu Bitwarden - At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information. + Ở nhà, trên cơ quan, hay trên đường đi, Bitwarden có thể dễ dàng bảo về tất cả những mật khẩu, mã khoá, và thông tin cá nhân của bạn. Recognized as the best password manager by PCMag, WIRED, The Verge, CNET, G2, and more! diff --git a/apps/browser/tsconfig.json b/apps/browser/tsconfig.json index e24985f58af..a554120bd1e 100644 --- a/apps/browser/tsconfig.json +++ b/apps/browser/tsconfig.json @@ -1,55 +1,5 @@ { - "compilerOptions": { - "moduleResolution": "node", - "noImplicitAny": true, - "allowSyntheticDefaultImports": true, - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "module": "ES2020", - "target": "ES2016", - "allowJs": true, - "sourceMap": true, - "baseUrl": ".", - "lib": ["ES2021.String"], - "paths": { - "@bitwarden/admin-console/common": ["../../libs/admin-console/src/common"], - "@bitwarden/angular/*": ["../../libs/angular/src/*"], - "@bitwarden/auth/common": ["../../libs/auth/src/common"], - "@bitwarden/auth/angular": ["../../libs/auth/src/angular"], - "@bitwarden/billing": ["../../libs/billing/src"], - "@bitwarden/common/*": ["../../libs/common/src/*"], - "@bitwarden/components": ["../../libs/components/src"], - "@bitwarden/generator-components": ["../../libs/tools/generator/components/src"], - "@bitwarden/generator-core": ["../../libs/tools/generator/core/src"], - "@bitwarden/generator-history": ["../../libs/tools/generator/extensions/history/src"], - "@bitwarden/generator-legacy": ["../../libs/tools/generator/extensions/legacy/src"], - "@bitwarden/generator-navigation": ["../../libs/tools/generator/extensions/navigation/src"], - "@bitwarden/importer-core": ["../../libs/importer/src"], - "@bitwarden/importer-ui": ["../../libs/importer/src/components"], - "@bitwarden/key-management": ["../../libs/key-management/src"], - "@bitwarden/key-management-ui": ["../../libs/key-management-ui/src"], - "@bitwarden/platform": ["../../libs/platform/src"], - "@bitwarden/platform/*": ["../../libs/platform/src/*"], - "@bitwarden/send-ui": ["../../libs/tools/send/send-ui/src"], - "@bitwarden/tools-card": ["../../libs/tools/card/src"], - "@bitwarden/ui-common": ["../../libs/ui/common/src"], - "@bitwarden/ui-common/setup-jest": ["../../libs/ui/common/src/setup-jest"], - "@bitwarden/vault-export-core": [ - "../../libs/tools/export/vault-export/vault-export-core/src" - ], - "@bitwarden/vault-export-ui": ["../../libs/tools/export/vault-export/vault-export-ui/src"], - "@bitwarden/vault": ["../../libs/vault/src"] - }, - "plugins": [ - { - "name": "typescript-strict-plugin" - } - ], - "useDefineForClassFields": false - }, - "angularCompilerOptions": { - "strictTemplates": true - }, + "extends": "../../tsconfig.base", "include": [ "src", "../../libs/common/src/autofill/constants", diff --git a/apps/browser/tsconfig.spec.json b/apps/browser/tsconfig.spec.json index 79b5f5bc4b6..eedff91d23b 100644 --- a/apps/browser/tsconfig.spec.json +++ b/apps/browser/tsconfig.spec.json @@ -1,7 +1,9 @@ { "extends": "./tsconfig.json", - "files": ["./test.setup.ts"], "compilerOptions": { + "isolatedModules": true, + "emitDecoratorMetadata": false, "esModuleInterop": true - } + }, + "files": ["./test.setup.ts"] } diff --git a/apps/browser/webpack.config.js b/apps/browser/webpack.config.js index 6d9113be7ed..e4f60aaf17a 100644 --- a/apps/browser/webpack.config.js +++ b/apps/browser/webpack.config.js @@ -324,8 +324,6 @@ if (manifestVersion == 2) { // Manifest V2 background pages can be run through the regular build pipeline. // Since it's a standard webpage. mainConfig.entry.background = "./src/platform/background.ts"; - mainConfig.entry["content/fido2-page-script-append-mv2"] = - "./src/autofill/fido2/content/fido2-page-script-append.mv2.ts"; mainConfig.entry["content/fido2-page-script-delay-append-mv2"] = "./src/autofill/fido2/content/fido2-page-script-delay-append.mv2.ts"; diff --git a/apps/cli/jest.config.js b/apps/cli/jest.config.js index e0a5b9ec9cc..c96395944b5 100644 --- a/apps/cli/jest.config.js +++ b/apps/cli/jest.config.js @@ -1,6 +1,6 @@ const { pathsToModuleNameMapper } = require("ts-jest"); -const { compilerOptions } = require("./tsconfig"); +const { compilerOptions } = require("../../tsconfig.base"); const sharedConfig = require("../../libs/shared/jest.config.ts"); @@ -13,8 +13,14 @@ module.exports = { moduleNameMapper: { "@bitwarden/common/platform/services/sdk/default-sdk-client-factory": "/../../libs/common/spec/jest-sdk-client-factory", - ...pathsToModuleNameMapper(compilerOptions?.paths || {}, { - prefix: "/", - }), + ...pathsToModuleNameMapper( + { + "@bitwarden/common/spec": ["libs/common/spec"], + ...(compilerOptions?.paths || {}), + }, + { + prefix: "/../../", + }, + ), }, }; diff --git a/apps/cli/package.json b/apps/cli/package.json index 79d4786a23c..4ac93d53c40 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": "2025.4.0", + "version": "2025.5.0", "keywords": [ "bitwarden", "password", @@ -64,13 +64,14 @@ ] }, "dependencies": { - "@koa/multer": "3.0.2", + "@koa/multer": "3.1.0", "@koa/router": "13.1.0", "argon2": "0.41.1", "big-integer": "1.6.52", "browser-hrtime": "1.1.8", "chalk": "4.1.2", "commander": "11.1.0", + "core-js": "3.42.0", "form-data": "4.0.1", "https-proxy-agent": "7.0.6", "inquirer": "8.2.6", @@ -81,13 +82,14 @@ "koa-json": "2.0.2", "lowdb": "1.0.0", "lunr": "2.3.9", - "multer": "1.4.5-lts.1", + "multer": "1.4.5-lts.2", "node-fetch": "2.6.12", "node-forge": "1.3.1", "open": "8.4.2", - "papaparse": "5.5.2", + "papaparse": "5.5.3", "proper-lockfile": "4.1.2", "rxjs": "7.8.1", + "semver": "7.7.2", "tldts": "7.0.1", "zxcvbn": "4.4.2" } diff --git a/apps/cli/src/admin-console/commands/share.command.ts b/apps/cli/src/admin-console/commands/share.command.ts index 6d9e6c8b6c0..540bc2659c9 100644 --- a/apps/cli/src/admin-console/commands/share.command.ts +++ b/apps/cli/src/admin-console/commands/share.command.ts @@ -59,15 +59,11 @@ export class ShareCommand { return Response.badRequest("This item already belongs to an organization."); } - const cipherView = await cipher.decrypt( - await this.cipherService.getKeyForCipherKeyDecryption(cipher, activeUserId), - ); + const cipherView = await this.cipherService.decrypt(cipher, activeUserId); try { await this.cipherService.shareWithServer(cipherView, organizationId, req, activeUserId); const updatedCipher = await this.cipherService.get(cipher.id, activeUserId); - const decCipher = await updatedCipher.decrypt( - await this.cipherService.getKeyForCipherKeyDecryption(updatedCipher, activeUserId), - ); + const decCipher = await this.cipherService.decrypt(updatedCipher, activeUserId); const res = new CipherResponse(decCipher); return Response.success(res); } catch (e) { diff --git a/apps/cli/src/auth/commands/login.command.ts b/apps/cli/src/auth/commands/login.command.ts index 8a94cc4175a..a8e525e2206 100644 --- a/apps/cli/src/auth/commands/login.command.ts +++ b/apps/cli/src/auth/commands/login.command.ts @@ -32,8 +32,9 @@ import { UpdateTempPasswordRequest } from "@bitwarden/common/auth/models/request import { ClientType } from "@bitwarden/common/enums"; import { CryptoFunctionService } from "@bitwarden/common/key-management/crypto/abstractions/crypto-function.service"; import { KeyConnectorService } from "@bitwarden/common/key-management/key-connector/abstractions/key-connector.service"; -import { ErrorResponse } from "@bitwarden/common/models/response/error.response"; +import { MasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction"; import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; @@ -77,6 +78,8 @@ export class LoginCommand { protected logoutCallback: () => Promise, protected kdfConfigService: KdfConfigService, protected ssoUrlService: SsoUrlService, + protected i18nService: I18nService, + protected masterPasswordService: MasterPasswordServiceAbstraction, ) {} async run(email: string, password: string, options: OptionValues) { @@ -105,6 +108,8 @@ export class LoginCommand { return Response.badRequest("client_secret is required."); } } else if (options.sso != null && this.canInteract) { + // If the optional Org SSO Identifier isn't provided, the option value is `true`. + const orgSsoIdentifier = options.sso === true ? null : options.sso; const passwordOptions: any = { type: "password", length: 64, @@ -118,7 +123,7 @@ export class LoginCommand { const codeVerifierHash = await this.cryptoFunctionService.hash(ssoCodeVerifier, "sha256"); const codeChallenge = Utils.fromBufferToUrlB64(codeVerifierHash); try { - const ssoParams = await this.openSsoPrompt(codeChallenge, state); + const ssoParams = await this.openSsoPrompt(codeChallenge, state, orgSsoIdentifier); ssoCode = ssoParams.ssoCode; orgIdentifier = ssoParams.orgIdentifier; } catch { @@ -220,24 +225,11 @@ export class LoginCommand { ); } else { response = await this.loginStrategyService.logIn( - new PasswordLoginCredentials(email, password, null, twoFactor), + new PasswordLoginCredentials(email, password, twoFactor), ); } if (response.requiresEncryptionKeyMigration) { - return Response.error( - "Encryption key migration required. Please login through the web vault to update your encryption key.", - ); - } - if (response.captchaSiteKey) { - const credentials = new PasswordLoginCredentials(email, password); - const handledResponse = await this.handleCaptchaRequired(twoFactor, credentials); - - // Error Response - if (handledResponse instanceof Response) { - return handledResponse; - } else { - response = handledResponse; - } + return Response.error(this.i18nService.t("legacyEncryptionUnsupported")); } if (response.requiresTwoFactor) { const twoFactorProviders = await this.twoFactorService.getSupportedProviders(null); @@ -310,7 +302,6 @@ export class LoginCommand { response = await this.loginStrategyService.logInTwoFactor( new TokenTwoFactorRequest(selectedProvider.type, twoFactorToken), - null, ); } @@ -334,18 +325,6 @@ export class LoginCommand { response = await this.loginStrategyService.logInNewDeviceVerification(newDeviceToken); } - if (response.captchaSiteKey) { - const twoFactorRequest = new TokenTwoFactorRequest(selectedProvider.type, twoFactorToken); - const handledResponse = await this.handleCaptchaRequired(twoFactorRequest); - - // Error Response - if (handledResponse instanceof Response) { - return handledResponse; - } else { - response = handledResponse; - } - } - if (response.requiresTwoFactor) { return Response.error("Login failed."); } @@ -361,14 +340,14 @@ export class LoginCommand { await this.syncService.fullSync(true); // Handle updating passwords if NOT using an API Key for authentication - if ( - response.forcePasswordReset != ForceSetPasswordReason.None && - clientId == null && - clientSecret == null - ) { - if (response.forcePasswordReset === ForceSetPasswordReason.AdminForcePasswordReset) { + if (clientId == null && clientSecret == null) { + const forceSetPasswordReason = await firstValueFrom( + this.masterPasswordService.forceSetPasswordReason$(response.userId), + ); + + if (forceSetPasswordReason === ForceSetPasswordReason.AdminForcePasswordReset) { return await this.updateTempPassword(response.userId); - } else if (response.forcePasswordReset === ForceSetPasswordReason.WeakMasterPassword) { + } else if (forceSetPasswordReason === ForceSetPasswordReason.WeakMasterPassword) { return await this.updateWeakPassword(response.userId, password); } } @@ -627,48 +606,6 @@ export class LoginCommand { return { newPasswordHash, newUserKey: newUserKey, hint: masterPasswordHint }; } - private async handleCaptchaRequired( - twoFactorRequest: TokenTwoFactorRequest, - credentials: PasswordLoginCredentials = null, - ): Promise { - const badCaptcha = Response.badRequest( - "Your authentication request has been flagged and will require user interaction to proceed.\n" + - "Please use your API key to validate this request and ensure BW_CLIENTSECRET is correct, if set.\n" + - "(https://bitwarden.com/help/cli-auth-challenges)", - ); - - try { - const captchaClientSecret = await this.apiClientSecret(true); - if (Utils.isNullOrWhitespace(captchaClientSecret)) { - return badCaptcha; - } - - let authResultResponse: AuthResult = null; - if (credentials != null) { - credentials.captchaToken = captchaClientSecret; - credentials.twoFactor = twoFactorRequest; - authResultResponse = await this.loginStrategyService.logIn(credentials); - } else { - authResultResponse = await this.loginStrategyService.logInTwoFactor( - twoFactorRequest, - captchaClientSecret, - ); - } - - return authResultResponse; - } catch (e) { - if ( - e instanceof ErrorResponse || - (e.constructor.name === ErrorResponse.name && - (e as ErrorResponse).message.includes("Captcha is invalid")) - ) { - return badCaptcha; - } else { - return Response.error(e); - } - } - } - private async apiClientId(): Promise { let clientId: string = null; @@ -729,6 +666,7 @@ export class LoginCommand { private async openSsoPrompt( codeChallenge: string, state: string, + orgSsoIdentifier: string, ): Promise<{ ssoCode: string; orgIdentifier: string }> { const env = await firstValueFrom(this.environmentService.environment$); @@ -777,6 +715,8 @@ export class LoginCommand { this.ssoRedirectUri, state, codeChallenge, + null, + orgSsoIdentifier, ); this.platformUtilsService.launchUri(webAppSsoUrl); }); diff --git a/apps/cli/src/auth/commands/unlock.command.ts b/apps/cli/src/auth/commands/unlock.command.ts index d10c3f38ebd..812a89ed889 100644 --- a/apps/cli/src/auth/commands/unlock.command.ts +++ b/apps/cli/src/auth/commands/unlock.command.ts @@ -14,12 +14,12 @@ import { EnvironmentService } from "@bitwarden/common/platform/abstractions/envi import { Utils } from "@bitwarden/common/platform/misc/utils"; import { ConsoleLogService } from "@bitwarden/common/platform/services/console-log.service"; import { MasterKey } from "@bitwarden/common/types/key"; -import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { KeyService } from "@bitwarden/key-management"; import { ConvertToKeyConnectorCommand } from "../../key-management/convert-to-key-connector.command"; import { Response } from "../../models/response"; import { MessageResponse } from "../../models/response/message.response"; +import { I18nService } from "../../platform/services/i18n.service"; import { CliUtils } from "../../utils"; export class UnlockCommand { @@ -32,9 +32,9 @@ export class UnlockCommand { private logService: ConsoleLogService, private keyConnectorService: KeyConnectorService, private environmentService: EnvironmentService, - private syncService: SyncService, private organizationApiService: OrganizationApiServiceAbstraction, private logout: () => Promise, + private i18nService: I18nService, ) {} async run(password: string, cmdOptions: Record) { @@ -73,14 +73,14 @@ export class UnlockCommand { const userKey = await this.masterPasswordService.decryptUserKeyWithMasterKey(masterKey, userId); await this.keyService.setUserKey(userKey, userId); - if (await this.keyConnectorService.getConvertAccountRequired()) { + if (await firstValueFrom(this.keyConnectorService.convertAccountRequired$)) { const convertToKeyConnectorCommand = new ConvertToKeyConnectorCommand( userId, this.keyConnectorService, this.environmentService, - this.syncService, this.organizationApiService, this.logout, + this.i18nService, ); const convertResponse = await convertToKeyConnectorCommand.run(); if (!convertResponse.success) { diff --git a/apps/cli/src/base-program.ts b/apps/cli/src/base-program.ts index 14c930b804a..5719f78c1b9 100644 --- a/apps/cli/src/base-program.ts +++ b/apps/cli/src/base-program.ts @@ -179,9 +179,9 @@ export abstract class BaseProgram { this.serviceContainer.logService, this.serviceContainer.keyConnectorService, this.serviceContainer.environmentService, - this.serviceContainer.syncService, this.serviceContainer.organizationApiService, this.serviceContainer.logout, + this.serviceContainer.i18nService, ); const response = await command.run(null, null); if (!response.success) { diff --git a/apps/cli/src/commands/download.command.ts b/apps/cli/src/commands/download.command.ts index 01ef675d2a8..2c75617ca5b 100644 --- a/apps/cli/src/commands/download.command.ts +++ b/apps/cli/src/commands/download.command.ts @@ -2,8 +2,6 @@ // @ts-strict-ignore import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; -import { EncArrayBuffer } from "@bitwarden/common/platform/models/domain/enc-array-buffer"; -import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { Response } from "../models/response"; import { FileResponse } from "../models/response/file.response"; @@ -25,15 +23,15 @@ export abstract class DownloadCommand { /** * Fetches an attachment via the url, decrypts it's content and saves it to a file * @param url - url used to retrieve the attachment - * @param key - SymmetricCryptoKey to decrypt the file contents * @param fileName - filename used when written to disk + * @param decrypt - Function used to decrypt the response * @param output - If output is empty or `--raw` was passed to the initial command the content is output onto stdout * @returns Promise */ protected async saveAttachmentToFile( url: string, - key: SymmetricCryptoKey, fileName: string, + decrypt: (resp: globalThis.Response) => Promise, output?: string, ) { const response = await this.apiService.nativeFetch( @@ -46,8 +44,7 @@ export abstract class DownloadCommand { } try { - const encBuf = await EncArrayBuffer.fromResponse(response); - const decBuf = await this.encryptService.decryptToBytes(encBuf, key); + const decBuf = await decrypt(response); if (process.env.BW_SERVE === "true") { const res = new FileResponse(Buffer.from(decBuf), fileName); return Response.success(res); diff --git a/apps/cli/src/commands/edit.command.ts b/apps/cli/src/commands/edit.command.ts index 2d4a854135d..677139d5451 100644 --- a/apps/cli/src/commands/edit.command.ts +++ b/apps/cli/src/commands/edit.command.ts @@ -90,9 +90,7 @@ export class EditCommand { return Response.notFound(); } - let cipherView = await cipher.decrypt( - await this.cipherService.getKeyForCipherKeyDecryption(cipher, activeUserId), - ); + let cipherView = await this.cipherService.decrypt(cipher, activeUserId); if (cipherView.isDeleted) { return Response.badRequest("You may not edit a deleted item. Use the restore command first."); } @@ -100,9 +98,7 @@ export class EditCommand { const encCipher = await this.cipherService.encrypt(cipherView, activeUserId); try { const updatedCipher = await this.cipherService.updateWithServer(encCipher); - const decCipher = await updatedCipher.decrypt( - await this.cipherService.getKeyForCipherKeyDecryption(updatedCipher, activeUserId), - ); + const decCipher = await this.cipherService.decrypt(updatedCipher, activeUserId); const res = new CipherResponse(decCipher); return Response.success(res); } catch (e) { @@ -132,12 +128,7 @@ export class EditCommand { cipher, activeUserId, ); - const decCipher = await updatedCipher.decrypt( - await this.cipherService.getKeyForCipherKeyDecryption( - updatedCipher, - await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)), - ), - ); + const decCipher = await this.cipherService.decrypt(updatedCipher, activeUserId); const res = new CipherResponse(decCipher); return Response.success(res); } catch (e) { @@ -204,7 +195,7 @@ export class EditCommand { (u) => new SelectionReadOnlyRequest(u.id, u.readOnly, u.hidePasswords, u.manage), ); const request = new CollectionRequest(); - request.name = (await this.encryptService.encrypt(req.name, orgKey)).encryptedString; + request.name = (await this.encryptService.encryptString(req.name, orgKey)).encryptedString; request.externalId = req.externalId; request.groups = groups; request.users = users; diff --git a/apps/cli/src/commands/get.command.ts b/apps/cli/src/commands/get.command.ts index 1bdbd051585..8554f8e2ae1 100644 --- a/apps/cli/src/commands/get.command.ts +++ b/apps/cli/src/commands/get.command.ts @@ -27,7 +27,7 @@ import { ErrorResponse } from "@bitwarden/common/models/response/error.response" import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SendType } from "@bitwarden/common/tools/send/enums/send-type"; -import { OrganizationId } from "@bitwarden/common/types/guid"; +import { CipherId, OrganizationId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; import { TotpService } from "@bitwarden/common/vault/abstractions/totp.service"; @@ -116,9 +116,7 @@ export class GetCommand extends DownloadCommand { if (Utils.isGuid(id)) { const cipher = await this.cipherService.get(id, activeUserId); if (cipher != null) { - decCipher = await cipher.decrypt( - await this.cipherService.getKeyForCipherKeyDecryption(cipher, activeUserId), - ); + decCipher = await this.cipherService.decrypt(cipher, activeUserId); } } else if (id.trim() !== "") { let ciphers = await this.cipherService.getAllDecrypted(activeUserId); @@ -347,12 +345,11 @@ export class GetCommand extends DownloadCommand { return Response.multipleResults(attachments.map((a) => a.id)); } - const account = await firstValueFrom(this.accountService.activeAccount$); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); const canAccessPremium = await firstValueFrom( - this.accountProfileService.hasPremiumFromAnySource$(account.id), + this.accountProfileService.hasPremiumFromAnySource$(activeUserId), ); if (!canAccessPremium) { - const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); const originalCipher = await this.cipherService.get(cipher.id, activeUserId); if (originalCipher == null || originalCipher.organizationId == null) { return Response.error("Premium status is required to use this feature."); @@ -376,11 +373,20 @@ export class GetCommand extends DownloadCommand { } } - const key = - attachments[0].key != null - ? attachments[0].key - : await this.keyService.getOrgKey(cipher.organizationId); - return await this.saveAttachmentToFile(url, key, attachments[0].fileName, options.output); + const decryptBufferFn = (resp: globalThis.Response) => + this.cipherService.getDecryptedAttachmentBuffer( + cipher.id as CipherId, + attachments[0], + resp, + activeUserId, + ); + + return await this.saveAttachmentToFile( + url, + attachments[0].fileName, + decryptBufferFn, + options.output, + ); } private async getFolder(id: string) { @@ -455,10 +461,9 @@ export class GetCommand extends DownloadCommand { const response = await this.apiService.getCollectionAccessDetails(options.organizationId, id); const decCollection = new CollectionView(response); - decCollection.name = await this.encryptService.decryptToUtf8( + decCollection.name = await this.encryptService.decryptString( new EncString(response.name), orgKey, - `orgkey-${options.organizationId}`, ); const groups = response.groups == null diff --git a/apps/cli/src/key-management/convert-to-key-connector.command.spec.ts b/apps/cli/src/key-management/convert-to-key-connector.command.spec.ts new file mode 100644 index 00000000000..6b0d4e6f685 --- /dev/null +++ b/apps/cli/src/key-management/convert-to-key-connector.command.spec.ts @@ -0,0 +1,206 @@ +import { createPromptModule } from "inquirer"; +import { mock } from "jest-mock-extended"; +import { of } from "rxjs"; + +import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction"; +import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; +import { KeyConnectorService } from "@bitwarden/common/key-management/key-connector/abstractions/key-connector.service"; +import { + Environment, + EnvironmentService, + Region, + Urls, +} from "@bitwarden/common/platform/abstractions/environment.service"; +import { UserId } from "@bitwarden/common/types/guid"; + +import { Response } from "../models/response"; +import { MessageResponse } from "../models/response/message.response"; +import { I18nService } from "../platform/services/i18n.service"; + +import { ConvertToKeyConnectorCommand } from "./convert-to-key-connector.command"; + +jest.mock("inquirer", () => { + return { + createPromptModule: jest.fn(() => jest.fn(() => Promise.resolve({ convert: "" }))), + }; +}); + +describe("ConvertToKeyConnectorCommand", () => { + let command: ConvertToKeyConnectorCommand; + + const userId = "test-user-id" as UserId; + const organization = { + id: "test-organization-id", + name: "Test Organization", + keyConnectorUrl: "https://keyconnector.example.com", + } as Organization; + + const keyConnectorService = mock(); + const environmentService = mock(); + const organizationApiService = mock(); + const logout = jest.fn(); + const i18nService = mock(); + + beforeEach(async () => { + command = new ConvertToKeyConnectorCommand( + userId, + keyConnectorService, + environmentService, + organizationApiService, + logout, + i18nService, + ); + + i18nService.t.mockImplementation((key: string) => { + switch (key) { + case "removeMasterPasswordForOrganizationUserKeyConnector": + return "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator. Organization name: Test Organization. Key Connector domain: https://keyconnector.example.com"; + case "removeMasterPasswordAndUnlock": + return "Remove master password and unlock"; + case "leaveOrganizationAndUnlock": + return "Leave organization and unlock"; + case "logOut": + return "Log out"; + case "youHaveBeenLoggedOut": + return "You have been logged out."; + case "organizationUsingKeyConnectorOptInLoggedOut": + return "An organization you are a member of is using Key Connector. In order to access the vault, you must opt-in to Key Connector now via the web vault. You have been logged out."; + default: + return ""; + } + }); + }); + + describe("run", () => { + it("should logout and return error response if no interaction available", async () => { + process.env.BW_NOINTERACTION = "true"; + + const response = await command.run(); + + expect(response).not.toBeNull(); + expect(response.success).toEqual(false); + expect(response).toEqual( + Response.error( + new MessageResponse( + "An organization you are a member of is using Key Connector. In order to access the vault, you must opt-in to Key Connector now via the web vault. You have been logged out.", + null, + ), + ), + ); + expect(logout).toHaveBeenCalled(); + }); + + it("should logout and return error response if interaction answer is exit", async () => { + process.env.BW_NOINTERACTION = "false"; + keyConnectorService.getManagingOrganization.mockResolvedValue(organization); + + (createPromptModule as jest.Mock).mockImplementation(() => + jest.fn((prompt) => { + assertPrompt(prompt); + return Promise.resolve({ convert: "exit" }); + }), + ); + + const response = await command.run(); + + expect(response).not.toBeNull(); + expect(response.success).toEqual(false); + expect(response).toEqual(Response.error("You have been logged out.")); + expect(logout).toHaveBeenCalled(); + }); + + it("should key connector migrate user and return success response if answer is remove", async () => { + process.env.BW_NOINTERACTION = "false"; + keyConnectorService.getManagingOrganization.mockResolvedValue(organization); + environmentService.environment$ = of({ + getUrls: () => + ({ + keyConnector: "old-key-connector-url", + }) as Urls, + } as Environment); + + (createPromptModule as jest.Mock).mockImplementation(() => + jest.fn((prompt) => { + assertPrompt(prompt); + return Promise.resolve({ convert: "remove" }); + }), + ); + + const response = await command.run(); + + expect(response).not.toBeNull(); + expect(response.success).toEqual(true); + expect(keyConnectorService.migrateUser).toHaveBeenCalledWith( + organization.keyConnectorUrl, + userId, + ); + expect(environmentService.setEnvironment).toHaveBeenCalledWith(Region.SelfHosted, { + keyConnector: organization.keyConnectorUrl, + } as Urls); + }); + + it("should logout and throw error if key connector migrate user fails", async () => { + process.env.BW_NOINTERACTION = "false"; + keyConnectorService.getManagingOrganization.mockResolvedValue(organization); + + (createPromptModule as jest.Mock).mockImplementation(() => + jest.fn((prompt) => { + assertPrompt(prompt); + return Promise.resolve({ convert: "remove" }); + }), + ); + + keyConnectorService.migrateUser.mockRejectedValue(new Error("Migration failed")); + + await expect(command.run()).rejects.toThrow("Migration failed"); + expect(logout).toHaveBeenCalled(); + }); + + it("should leave organization and return success response if answer is leave", async () => { + process.env.BW_NOINTERACTION = "false"; + keyConnectorService.getManagingOrganization.mockResolvedValue(organization); + + (createPromptModule as jest.Mock).mockImplementation(() => + jest.fn((prompt) => { + assertPrompt(prompt); + return Promise.resolve({ convert: "leave" }); + }), + ); + + const response = await command.run(); + + expect(response).not.toBeNull(); + expect(response.success).toEqual(true); + expect(organizationApiService.leave).toHaveBeenCalledWith(organization.id); + }); + + function assertPrompt(prompt: unknown) { + expect(typeof prompt).toEqual("object"); + expect(prompt).toHaveProperty("type"); + expect(prompt).toHaveProperty("name"); + expect(prompt).toHaveProperty("message"); + expect(prompt).toHaveProperty("choices"); + const promptObj = prompt as Record; + expect(promptObj["type"]).toEqual("list"); + expect(promptObj["name"]).toEqual("convert"); + expect(promptObj["message"]).toEqual( + `A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator. Organization name: ${organization.name}. Key Connector domain: ${organization.keyConnectorUrl}`, + ); + expect(promptObj["choices"]).toBeInstanceOf(Array); + const choices = promptObj["choices"] as Array>; + expect(choices).toHaveLength(3); + expect(choices[0]).toEqual({ + name: "Remove master password and unlock", + value: "remove", + }); + expect(choices[1]).toEqual({ + name: "Leave organization and unlock", + value: "leave", + }); + expect(choices[2]).toEqual({ + name: "Log out", + value: "exit", + }); + } + }); +}); diff --git a/apps/cli/src/key-management/convert-to-key-connector.command.ts b/apps/cli/src/key-management/convert-to-key-connector.command.ts index cdebfd7b55a..ff1de744d74 100644 --- a/apps/cli/src/key-management/convert-to-key-connector.command.ts +++ b/apps/cli/src/key-management/convert-to-key-connector.command.ts @@ -1,5 +1,3 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore import * as inquirer from "inquirer"; import { firstValueFrom } from "rxjs"; @@ -10,19 +8,19 @@ import { Region, } from "@bitwarden/common/platform/abstractions/environment.service"; import { UserId } from "@bitwarden/common/types/guid"; -import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { Response } from "../models/response"; import { MessageResponse } from "../models/response/message.response"; +import { I18nService } from "../platform/services/i18n.service"; export class ConvertToKeyConnectorCommand { constructor( private readonly userId: UserId, private keyConnectorService: KeyConnectorService, private environmentService: EnvironmentService, - private syncService: SyncService, private organizationApiService: OrganizationApiServiceAbstraction, private logout: () => Promise, + private i18nService: I18nService, ) {} async run(): Promise { @@ -32,32 +30,33 @@ export class ConvertToKeyConnectorCommand { await this.logout(); return Response.error( new MessageResponse( - "An organization you are a member of is using Key Connector. " + - "In order to access the vault, you must opt-in to Key Connector now via the web vault. You have been logged out.", + this.i18nService.t("organizationUsingKeyConnectorOptInLoggedOut"), null, ), ); } - const organization = await this.keyConnectorService.getManagingOrganization(); + const organization = await this.keyConnectorService.getManagingOrganization(this.userId); const answer: inquirer.Answers = await inquirer.createPromptModule({ output: process.stderr })({ type: "list", name: "convert", - message: - organization.name + - " is using a self-hosted key server. A master password is no longer required to log in for members of this organization. ", + message: this.i18nService.t( + "removeMasterPasswordForOrganizationUserKeyConnector", + organization.name, + organization.keyConnectorUrl, + ), choices: [ { - name: "Remove master password and unlock", + name: this.i18nService.t("removeMasterPasswordAndUnlock"), value: "remove", }, { - name: "Leave organization and unlock", + name: this.i18nService.t("leaveOrganizationAndUnlock"), value: "leave", }, { - name: "Log out", + name: this.i18nService.t("logOut"), value: "exit", }, ], @@ -65,15 +64,12 @@ export class ConvertToKeyConnectorCommand { if (answer.convert === "remove") { try { - await this.keyConnectorService.migrateUser(); + await this.keyConnectorService.migrateUser(organization.keyConnectorUrl, this.userId); } catch (e) { await this.logout(); throw e; } - await this.keyConnectorService.removeConvertAccountRequired(); - await this.keyConnectorService.setUsesKeyConnector(true, this.userId); - // Update environment URL - required for api key login const env = await firstValueFrom(this.environmentService.environment$); const urls = env.getUrls(); @@ -83,11 +79,10 @@ export class ConvertToKeyConnectorCommand { return Response.success(); } else if (answer.convert === "leave") { await this.organizationApiService.leave(organization.id); - await this.keyConnectorService.removeConvertAccountRequired(); return Response.success(); } else { await this.logout(); - return Response.error("You have been logged out."); + return Response.error(this.i18nService.t("youHaveBeenLoggedOut")); } } } diff --git a/apps/cli/src/locales/en/messages.json b/apps/cli/src/locales/en/messages.json index a9c7af91524..815939c0c95 100644 --- a/apps/cli/src/locales/en/messages.json +++ b/apps/cli/src/locales/en/messages.json @@ -184,5 +184,36 @@ "example": "JustTrust.us" } } + }, + "legacyEncryptionUnsupported": { + "message": "Legacy encryption is no longer supported. Please contact support to recover your account." + }, + "organizationUsingKeyConnectorOptInLoggedOut": { + "message": "An organization you are a member of is using Key Connector. In order to access the vault, you must opt-in to Key Connector now via the web vault. You have been logged out." + }, + "removeMasterPasswordForOrganizationUserKeyConnector": { + "message": "A master password is no longer required for members of the following organization. Please confirm the domain below with your organization administrator. Organization name: $ORGANIZATION$. Key Connector domain: $KEYCONNECTORDOMAIN$", + "placeholders": { + "organization": { + "content": "$1", + "example": "My Org Name" + }, + "keyConnectorDomain": { + "content": "$2", + "example": "Key Connector domain" + } + } + }, + "removeMasterPasswordAndUnlock": { + "message": "Remove master password and unlock" + }, + "leaveOrganizationAndUnlock": { + "message": "Leave organization and unlock" + }, + "logOut": { + "message": "Log out" + }, + "youHaveBeenLoggedOut": { + "message": "You have been logged out." } } diff --git a/apps/cli/src/models/response/message.response.ts b/apps/cli/src/models/response/message.response.ts index dcbe3b92216..889d0982f83 100644 --- a/apps/cli/src/models/response/message.response.ts +++ b/apps/cli/src/models/response/message.response.ts @@ -5,11 +5,11 @@ import { BaseResponse } from "./base.response"; export class MessageResponse implements BaseResponse { object: string; title: string; - message: string; + message: string | null; raw: string; noColor = false; - constructor(title: string, message: string) { + constructor(title: string, message: string | null) { this.object = "message"; this.title = title; this.message = message; diff --git a/apps/cli/src/oss-serve-configurator.ts b/apps/cli/src/oss-serve-configurator.ts index 7028e65a690..cc590df9620 100644 --- a/apps/cli/src/oss-serve-configurator.ts +++ b/apps/cli/src/oss-serve-configurator.ts @@ -144,9 +144,9 @@ export class OssServeConfigurator { this.serviceContainer.logService, this.serviceContainer.keyConnectorService, this.serviceContainer.environmentService, - this.serviceContainer.syncService, this.serviceContainer.organizationApiService, async () => await this.serviceContainer.logout(), + this.serviceContainer.i18nService, ); this.sendCreateCommand = new SendCreateCommand( diff --git a/apps/cli/src/platform/services/node-api.service.ts b/apps/cli/src/platform/services/node-api.service.ts index 8c7629fb3d9..d695272364b 100644 --- a/apps/cli/src/platform/services/node-api.service.ts +++ b/apps/cli/src/platform/services/node-api.service.ts @@ -39,6 +39,7 @@ export class NodeApiService extends ApiService { logService, logoutCallback, vaultTimeoutSettingsService, + { createRequest: (url, request) => new Request(url, request) }, customUserAgent, ); } diff --git a/apps/cli/src/platform/services/node-env-secure-storage.service.ts b/apps/cli/src/platform/services/node-env-secure-storage.service.ts index 5e31995606f..64865340000 100644 --- a/apps/cli/src/platform/services/node-env-secure-storage.service.ts +++ b/apps/cli/src/platform/services/node-env-secure-storage.service.ts @@ -61,7 +61,7 @@ export class NodeEnvSecureStorageService implements AbstractStorageService { if (sessionKey == null) { throw new Error("No session key available."); } - const encValue = await this.encryptService.encryptToBytes( + const encValue = await this.encryptService.encryptFileData( Utils.fromB64ToArray(plainValue), sessionKey, ); @@ -80,7 +80,7 @@ export class NodeEnvSecureStorageService implements AbstractStorageService { } const encBuf = EncArrayBuffer.fromB64(encValue); - const decValue = await this.encryptService.decryptToBytes(encBuf, sessionKey); + const decValue = await this.encryptService.decryptFileData(encBuf, sessionKey); if (decValue == null) { this.logService.info("Failed to decrypt."); return null; diff --git a/apps/cli/src/program.ts b/apps/cli/src/program.ts index c6b79c7dff2..468901282b4 100644 --- a/apps/cli/src/program.ts +++ b/apps/cli/src/program.ts @@ -118,7 +118,10 @@ export class Program extends BaseProgram { .description("Log into a user account.") .option("--method ", "Two-step login method.") .option("--code ", "Two-step login code.") - .option("--sso", "Log in with Single-Sign On.") + .option( + "--sso [identifier]", + "Log in with Single-Sign On with optional organization identifier.", + ) .option("--apikey", "Log in with an Api Key.") .option("--passwordenv ", "Environment variable storing your password") .option( @@ -172,6 +175,8 @@ export class Program extends BaseProgram { async () => await this.serviceContainer.logout(), this.serviceContainer.kdfConfigService, this.serviceContainer.ssoUrlService, + this.serviceContainer.i18nService, + this.serviceContainer.masterPasswordService, ); const response = await command.run(email, password, options); this.processResponse(response, true); @@ -277,9 +282,9 @@ export class Program extends BaseProgram { this.serviceContainer.logService, this.serviceContainer.keyConnectorService, this.serviceContainer.environmentService, - this.serviceContainer.syncService, this.serviceContainer.organizationApiService, async () => await this.serviceContainer.logout(), + this.serviceContainer.i18nService, ); const response = await command.run(password, cmd); this.processResponse(response); diff --git a/apps/cli/src/service-container/service-container.ts b/apps/cli/src/service-container/service-container.ts index fe2f506f229..bc5db09da26 100644 --- a/apps/cli/src/service-container/service-container.ts +++ b/apps/cli/src/service-container/service-container.ts @@ -139,12 +139,14 @@ import { SendApiService } from "@bitwarden/common/tools/send/services/send-api.s import { SendStateProvider } from "@bitwarden/common/tools/send/services/send-state.provider"; import { SendService } from "@bitwarden/common/tools/send/services/send.service"; import { UserId } from "@bitwarden/common/types/guid"; +import { CipherEncryptionService } from "@bitwarden/common/vault/abstractions/cipher-encryption.service"; import { InternalFolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; import { CipherAuthorizationService, DefaultCipherAuthorizationService, } from "@bitwarden/common/vault/services/cipher-authorization.service"; import { CipherService } from "@bitwarden/common/vault/services/cipher.service"; +import { DefaultCipherEncryptionService } from "@bitwarden/common/vault/services/default-cipher-encryption.service"; import { CipherFileUploadService } from "@bitwarden/common/vault/services/file-upload/cipher-file-upload.service"; import { FolderApiService } from "@bitwarden/common/vault/services/folder/folder-api.service"; import { FolderService } from "@bitwarden/common/vault/services/folder/folder.service"; @@ -284,6 +286,7 @@ export class ServiceContainer { ssoUrlService: SsoUrlService; masterPasswordApiService: MasterPasswordApiServiceAbstraction; bulkEncryptService: FallbackBulkEncryptService; + cipherEncryptionService: CipherEncryptionService; constructor() { let p = null; @@ -679,6 +682,11 @@ export class ServiceContainer { this.accountService, ); + this.cipherEncryptionService = new DefaultCipherEncryptionService( + this.sdkService, + this.logService, + ); + this.cipherService = new CipherService( this.keyService, this.domainSettingsService, @@ -694,6 +702,7 @@ export class ServiceContainer { this.stateProvider, this.accountService, this.logService, + this.cipherEncryptionService, ); this.folderService = new FolderService( @@ -865,7 +874,7 @@ export class ServiceContainer { const userId = await firstValueFrom(getUserId(this.accountService.activeAccount$)); await Promise.all([ this.eventUploadService.uploadEvents(userId as UserId), - this.keyService.clearKeys(), + this.keyService.clearKeys(userId), this.cipherService.clear(userId), this.folderService.clear(userId), this.collectionService.clear(userId), diff --git a/apps/cli/src/tools/send/commands/receive.command.ts b/apps/cli/src/tools/send/commands/receive.command.ts index c67b4213d97..a412f7c1667 100644 --- a/apps/cli/src/tools/send/commands/receive.command.ts +++ b/apps/cli/src/tools/send/commands/receive.command.ts @@ -11,6 +11,7 @@ import { ErrorResponse } from "@bitwarden/common/models/response/error.response" import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; +import { EncArrayBuffer } from "@bitwarden/common/platform/models/domain/enc-array-buffer"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { SendType } from "@bitwarden/common/tools/send/enums/send-type"; import { SendAccess } from "@bitwarden/common/tools/send/models/domain/send-access"; @@ -98,10 +99,16 @@ export class SendReceiveCommand extends DownloadCommand { this.sendAccessRequest, apiUrl, ); + + const decryptBufferFn = async (resp: globalThis.Response) => { + const encBuf = await EncArrayBuffer.fromResponse(resp); + return this.encryptService.decryptFileData(encBuf, this.decKey); + }; + return await this.saveAttachmentToFile( downloadData.url, - this.decKey, response?.file?.fileName, + decryptBufferFn, options.output, ); } diff --git a/apps/cli/src/utils.ts b/apps/cli/src/utils.ts index fadede9c71b..e321adbfd5e 100644 --- a/apps/cli/src/utils.ts +++ b/apps/cli/src/utils.ts @@ -161,7 +161,6 @@ export class CliUtils { process.stdin.setEncoding("utf8"); process.stdin.on("readable", () => { - // eslint-disable-next-line while (true) { const chunk = process.stdin.read(); if (chunk == null) { diff --git a/apps/cli/src/vault/create.command.ts b/apps/cli/src/vault/create.command.ts index 713471356c9..b1536e23748 100644 --- a/apps/cli/src/vault/create.command.ts +++ b/apps/cli/src/vault/create.command.ts @@ -93,9 +93,7 @@ export class CreateCommand { const cipher = await this.cipherService.encrypt(CipherExport.toView(req), activeUserId); try { const newCipher = await this.cipherService.createWithServer(cipher); - const decCipher = await newCipher.decrypt( - await this.cipherService.getKeyForCipherKeyDecryption(newCipher, activeUserId), - ); + const decCipher = await this.cipherService.decrypt(newCipher, activeUserId); const res = new CipherResponse(decCipher); return Response.success(res); } catch (e) { @@ -162,9 +160,7 @@ export class CreateCommand { new Uint8Array(fileBuf).buffer, activeUserId, ); - const decCipher = await updatedCipher.decrypt( - await this.cipherService.getKeyForCipherKeyDecryption(updatedCipher, activeUserId), - ); + const decCipher = await this.cipherService.decrypt(updatedCipher, activeUserId); return Response.success(new CipherResponse(decCipher)); } catch (e) { return Response.error(e); @@ -227,7 +223,7 @@ export class CreateCommand { (u) => new SelectionReadOnlyRequest(u.id, u.readOnly, u.hidePasswords, u.manage), ); const request = new CollectionRequest(); - request.name = (await this.encryptService.encrypt(req.name, orgKey)).encryptedString; + request.name = (await this.encryptService.encryptString(req.name, orgKey)).encryptedString; request.externalId = req.externalId; request.groups = groups; request.users = users; diff --git a/apps/cli/src/vault/delete.command.ts b/apps/cli/src/vault/delete.command.ts index 9e648cd9bb0..d1b0b093cf8 100644 --- a/apps/cli/src/vault/delete.command.ts +++ b/apps/cli/src/vault/delete.command.ts @@ -106,6 +106,7 @@ export class DeleteCommand { cipher.id, attachments[0].id, activeUserId, + false, ); return Response.success(); } catch (e) { diff --git a/apps/cli/tsconfig.json b/apps/cli/tsconfig.json index 9d6e3066b29..3bcd098ca19 100644 --- a/apps/cli/tsconfig.json +++ b/apps/cli/tsconfig.json @@ -1,38 +1,4 @@ { - "compilerOptions": { - "pretty": true, - "moduleResolution": "node", - "target": "ES2016", - "module": "ES2020", - "noImplicitAny": true, - "allowSyntheticDefaultImports": true, - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "allowJs": true, - "sourceMap": true, - "baseUrl": ".", - "paths": { - "@bitwarden/common/spec": ["../../libs/common/spec"], - "@bitwarden/admin-console/common": ["../../libs/admin-console/src/common"], - "@bitwarden/auth/common": ["../../libs/auth/src/common"], - "@bitwarden/auth/angular": ["../../libs/auth/src/angular"], - "@bitwarden/common/*": ["../../libs/common/src/*"], - "@bitwarden/importer-core": ["../../libs/importer/src"], - "@bitwarden/generator-core": ["../../libs/tools/generator/core/src"], - "@bitwarden/generator-legacy": ["../../libs/tools/generator/extensions/legacy/src"], - "@bitwarden/generator-history": ["../../libs/tools/generator/extensions/history/src"], - "@bitwarden/generator-navigation": ["../../libs/tools/generator/extensions/navigation/src"], - "@bitwarden/vault-export-core": [ - "../../libs/tools/export/vault-export/vault-export-core/src" - ], - "@bitwarden/key-management": ["../../libs/key-management/src"], - "@bitwarden/node/*": ["../../libs/node/src/*"] - }, - "plugins": [ - { - "name": "typescript-strict-plugin" - } - ] - }, + "extends": "../../tsconfig.base", "include": ["src", "src/**/*.spec.ts"] } diff --git a/apps/desktop/desktop_native/Cargo.lock b/apps/desktop/desktop_native/Cargo.lock index c225dc49f73..28d64e4f504 100644 --- a/apps/desktop/desktop_native/Cargo.lock +++ b/apps/desktop/desktop_native/Cargo.lock @@ -120,9 +120,9 @@ checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" [[package]] name = "arboard" -version = "3.4.1" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df099ccb16cd014ff054ac1bf392c67feeef57164b05c42f037cd40f5d4357f4" +checksum = "c1df21f715862ede32a0c525ce2ca4d52626bb0007f8c18b87a384503ac33e70" dependencies = [ "clipboard-win", "log", @@ -130,6 +130,7 @@ dependencies = [ "objc2-app-kit", "objc2-foundation", "parking_lot", + "percent-encoding", "wl-clipboard-rs", "x11rb", ] @@ -147,6 +148,23 @@ dependencies = [ "zeroize", ] +[[package]] +name = "ashpd" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cbdf310d77fd3aaee6ea2093db7011dc2d35d2eb3481e5607f1f8d942ed99df" +dependencies = [ + "enumflags2", + "futures-channel", + "futures-util", + "rand 0.9.1", + "serde", + "serde_repr", + "tokio", + "url", + "zbus 5.6.0", +] + [[package]] name = "askama" version = "0.12.1" @@ -214,14 +232,15 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" +checksum = "bb812ffb58524bdd10860d7d974e2f01cc0950c2438a74ee5ec2e2280c6c4ffa" dependencies = [ "async-task", "concurrent-queue", "fastrand", "futures-lite", + "pin-project-lite", "slab", ] @@ -249,7 +268,7 @@ dependencies = [ "futures-lite", "parking", "polling", - "rustix", + "rustix 0.38.44", "slab", "tracing", "windows-sys 0.59.0", @@ -266,17 +285,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "async-net" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7" -dependencies = [ - "async-io", - "blocking", - "futures-lite", -] - [[package]] name = "async-process" version = "2.3.0" @@ -292,7 +300,7 @@ dependencies = [ "cfg-if", "event-listener", "futures-lite", - "rustix", + "rustix 0.38.44", "tracing", ] @@ -319,7 +327,7 @@ dependencies = [ "cfg-if", "futures-core", "futures-io", - "rustix", + "rustix 0.38.44", "signal-hook-registry", "slab", "windows-sys 0.59.0", @@ -333,9 +341,9 @@ checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.86" +version = "0.1.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "644dd749086bf3771a2fbc5f256fdb982d53f011c7d5d560304eafeecebce79d" +checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" dependencies = [ "proc-macro2", "quote", @@ -356,9 +364,9 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "backtrace" -version = "0.3.74" +version = "0.3.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" dependencies = [ "addr2line", "cfg-if", @@ -377,15 +385,15 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" -version = "1.6.0" +version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3" [[package]] name = "basic-toml" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "823388e228f614e9558c6804262db37960ec8821856535f5c3f59913140558f8" +checksum = "ba62675e8242a4c4e806d12f11d136e626e6c8361d6b829310732241652a178a" dependencies = [ "serde", ] @@ -412,9 +420,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" [[package]] name = "bitwarden-russh" @@ -459,15 +467,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "block2" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" -dependencies = [ - "objc2", -] - [[package]] name = "blocking" version = "1.6.1" @@ -499,9 +498,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.10.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "camino" @@ -559,12 +558,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "cfg_aliases" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" - [[package]] name = "cfg_aliases" version = "0.2.1" @@ -595,9 +588,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.31" +version = "4.5.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "027bb0d98429ae334a8698531da7077bdf906419543a35a55c2cb1b66437d767" +checksum = "ed93b9805f8ba930df42c2590f05453d5ec36cbb85d018868a5b24d31f6ac000" dependencies = [ "clap_builder", "clap_derive", @@ -605,9 +598,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.31" +version = "4.5.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5589e0cba072e0f3d23791efac0fd8627b49c829c196a492e88168e6a669d863" +checksum = "379026ff283facf611b0ea629334361c4211d1b12ee01024eec1591133b04120" dependencies = [ "anstream", "anstyle", @@ -617,9 +610,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.28" +version = "4.5.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4ced95c6f4a675af3da73304b9ac4ed991640c36374e4b46795c49e17cf1ed" +checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" dependencies = [ "heck", "proc-macro2", @@ -644,10 +637,11 @@ dependencies = [ [[package]] name = "codespan-reporting" -version = "0.11.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +checksum = "fe6d2e5af09e8c8ad56c969f2157a3d4238cebc7c55f0a517728c38f7b200f81" dependencies = [ + "serde", "termcolor", "unicode-width", ] @@ -707,25 +701,6 @@ dependencies = [ "libc", ] -[[package]] -name = "crossbeam-deque" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - [[package]] name = "crossbeam-utils" version = "0.8.21" @@ -739,7 +714,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", - "rand_core", + "rand_core 0.6.4", "typenum", ] @@ -790,9 +765,9 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.141" +version = "1.0.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bc580dceb395cae0efdde0a88f034cfd8a276897e40c693a7b87bed17971d33" +checksum = "a71ea7f29c73f7ffa64c50b83c9fe4d3a6d4be89a86b009eb80d5a6d3429d741" dependencies = [ "cc", "cxxbridge-cmd", @@ -804,9 +779,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.141" +version = "1.0.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49d8c1baedad72a7efda12ad8d7ad687b3e7221dfb304a12443fd69e9de8bb30" +checksum = "36a8232661d66dcf713394726157d3cfe0a89bfc85f52d6e9f9bbc2306797fe7" dependencies = [ "cc", "codespan-reporting", @@ -818,9 +793,9 @@ dependencies = [ [[package]] name = "cxxbridge-cmd" -version = "1.0.141" +version = "1.0.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e43afb0e3b2ef293492a31ecd796af902112460d53e5f923f7804f348a769f9c" +checksum = "4f44296c8693e9ea226a48f6a122727f77aa9e9e338380cb021accaeeb7ee279" dependencies = [ "clap", "codespan-reporting", @@ -831,15 +806,15 @@ dependencies = [ [[package]] name = "cxxbridge-flags" -version = "1.0.141" +version = "1.0.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0257ad2096a2474fe877e9e055ab69603851c3d6b394efcc7e0443899c2492ce" +checksum = "c42f69c181c176981ae44ba9876e2ea41ce8e574c296b38d06925ce9214fb8e4" [[package]] name = "cxxbridge-macro" -version = "1.0.141" +version = "1.0.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b46cbd7358a46b760609f1cb5093683328e58ca50e594a308716f5403fdc03e5" +checksum = "8faff5d4467e0709448187df29ccbf3b0982cc426ee444a193f87b11afb565a8" dependencies = [ "proc-macro2", "quote", @@ -862,9 +837,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" dependencies = [ "const-oid", "pem-rfc7468", @@ -873,24 +848,13 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.11" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" dependencies = [ "powerfmt", ] -[[package]] -name = "derive-new" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d150dea618e920167e5973d70ae6ece4385b7164e0d799fe7c122dd0a5d912ad" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "desktop_core" version = "0.0.0" @@ -899,6 +863,7 @@ dependencies = [ "anyhow", "arboard", "argon2", + "ashpd", "base64", "bitwarden-russh", "byteorder", @@ -917,7 +882,7 @@ dependencies = [ "oo7", "pin-project", "pkcs8", - "rand", + "rand 0.9.1", "rsa", "russh-cryptovec", "scopeguard", @@ -927,7 +892,7 @@ dependencies = [ "ssh-encoding", "ssh-key", "sysinfo", - "thiserror 1.0.69", + "thiserror 2.0.12", "tokio", "tokio-stream", "tokio-util", @@ -935,8 +900,9 @@ dependencies = [ "widestring", "windows 0.61.1", "windows-future", - "zbus", + "zbus 4.4.0", "zbus_polkit", + "zeroizing-alloc", ] [[package]] @@ -968,7 +934,7 @@ dependencies = [ "cc", "core-foundation", "glob", - "thiserror 1.0.69", + "thiserror 2.0.12", "tokio", ] @@ -1019,6 +985,27 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "dispatch2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" +dependencies = [ + "bitflags", + "objc2", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "doctest-file" version = "1.0.0" @@ -1053,12 +1040,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "either" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7914353092ddf589ad78f25c5c1c21b7f80b0ff8621e7c814c3485b5306da9d" - [[package]] name = "embed_plist" version = "1.2.2" @@ -1100,9 +1081,9 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" +checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e" dependencies = [ "libc", "windows-sys 0.59.0", @@ -1110,9 +1091,9 @@ dependencies = [ [[package]] name = "error-code" -version = "3.3.1" +version = "3.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5d9305ccc6942a704f4335694ecd3de2ea531b114ac2d51f5f843750787a92f" +checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59" [[package]] name = "event-listener" @@ -1127,9 +1108,9 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" dependencies = [ "event-listener", "pin-project-lite", @@ -1161,9 +1142,18 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foldhash" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] [[package]] name = "fs-err" @@ -1298,9 +1288,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "libc", @@ -1309,14 +1299,14 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ "cfg-if", "libc", - "wasi 0.13.3+wasi-0.2.2", - "windows-targets 0.52.6", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", ] [[package]] @@ -1360,9 +1350,9 @@ checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" [[package]] name = "heck" @@ -1407,19 +1397,126 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bdbbd5bc8c5749697ccaa352fa45aff8730cf21c68029c0eef1ffed7c3d6ba2" dependencies = [ "cfg-if", - "nix 0.29.0", + "nix", "widestring", "windows 0.57.0", ] [[package]] -name = "indexmap" -version = "2.7.1" +name = "icu_collections" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" + +[[package]] +name = "icu_properties" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2549ca8c7241c82f59c80ba2a6f415d931c5b58d24fb8412caa1a1f02c49139a" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "potential_utf", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8197e866e47b68f8f7d95249e172903bec06004b18b2937f1095d40a0c57de04" + +[[package]] +name = "icu_provider" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +dependencies = [ + "displaydoc", + "icu_locale_core", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "idna" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" dependencies = [ "equivalent", - "hashbrown 0.15.2", + "hashbrown 0.15.3", ] [[package]] @@ -1455,9 +1552,9 @@ checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itoa" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "keytar" @@ -1497,9 +1594,9 @@ checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" [[package]] name = "libloading" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" +checksum = "6a793df0d7afeac54f95b471d3af7f0d4fb975699f972341a4b76988d49cdf0c" dependencies = [ "cfg-if", "windows-targets 0.52.6", @@ -1507,9 +1604,9 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.11" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "libredox" @@ -1523,9 +1620,9 @@ dependencies = [ [[package]] name = "link-cplusplus" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d240c6f7e1ba3a28b0249f774e6a9dd0175054b52dfbb61b16eb8505c3785c9" +checksum = "4a6f6da007f968f9def0d65a05b187e2960183de70c160204ecfccf0ee330212" dependencies = [ "cc", ] @@ -1536,6 +1633,18 @@ version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" +[[package]] +name = "linux-raw-sys" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" + +[[package]] +name = "litemap" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" + [[package]] name = "lock_api" version = "0.4.12" @@ -1616,9 +1725,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.8.5" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" +checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" dependencies = [ "adler2", ] @@ -1692,18 +1801,6 @@ dependencies = [ "libloading", ] -[[package]] -name = "nix" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" -dependencies = [ - "bitflags", - "cfg-if", - "cfg_aliases 0.1.1", - "libc", -] - [[package]] name = "nix" version = "0.29.0" @@ -1712,7 +1809,7 @@ checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ "bitflags", "cfg-if", - "cfg_aliases 0.2.1", + "cfg_aliases", "libc", "memoffset", ] @@ -1772,7 +1869,7 @@ dependencies = [ "num-integer", "num-iter", "num-traits", - "rand", + "rand 0.8.5", "serde", "smallvec", "zeroize", @@ -1843,60 +1940,49 @@ dependencies = [ "libc", ] -[[package]] -name = "objc-sys" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" - [[package]] name = "objc2" -version = "0.5.2" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" +checksum = "88c6597e14493ab2e44ce58f2fdecf095a51f12ca57bec060a11c57332520551" dependencies = [ - "objc-sys", "objc2-encode", ] [[package]] name = "objc2-app-kit" -version = "0.2.2" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" +checksum = "e6f29f568bec459b0ddff777cec4fe3fd8666d82d5a40ebd0ff7e66134f89bcc" dependencies = [ "bitflags", - "block2", - "libc", - "objc2", - "objc2-core-data", - "objc2-core-image", - "objc2-foundation", - "objc2-quartz-core", -] - -[[package]] -name = "objc2-core-data" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" -dependencies = [ - "bitflags", - "block2", "objc2", + "objc2-core-graphics", "objc2-foundation", ] [[package]] -name = "objc2-core-image" -version = "0.2.2" +name = "objc2-core-foundation" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" +checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" dependencies = [ - "block2", + "bitflags", + "dispatch2", "objc2", - "objc2-foundation", - "objc2-metal", +] + +[[package]] +name = "objc2-core-graphics" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "989c6c68c13021b5c2d6b71456ebb0f9dc78d752e86a98da7c716f4f9470f5a4" +dependencies = [ + "bitflags", + "dispatch2", + "objc2", + "objc2-core-foundation", + "objc2-io-surface", ] [[package]] @@ -1907,39 +1993,34 @@ checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" [[package]] name = "objc2-foundation" -version = "0.2.2" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" +checksum = "900831247d2fe1a09a683278e5384cfb8c80c79fe6b166f9d14bfdde0ea1b03c" dependencies = [ "bitflags", - "block2", + "objc2", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-io-kit" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71c1c64d6120e51cd86033f67176b1cb66780c2efe34dec55176f77befd93c0a" +dependencies = [ "libc", - "objc2", + "objc2-core-foundation", ] [[package]] -name = "objc2-metal" -version = "0.2.2" +name = "objc2-io-surface" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" +checksum = "7282e9ac92529fa3457ce90ebb15f4ecbc383e8338060960760fa2cf75420c3c" dependencies = [ "bitflags", - "block2", "objc2", - "objc2-foundation", -] - -[[package]] -name = "objc2-quartz-core" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" -dependencies = [ - "bitflags", - "block2", - "objc2", - "objc2-foundation", - "objc2-metal", + "objc2-core-foundation", ] [[package]] @@ -1953,41 +2034,39 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.3" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "oo7" -version = "0.3.3" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc6ce4692fbfd044ce22ca07dcab1a30fa12432ca2aa5b1294eca50d3332a24" +checksum = "6cb23d3ec3527d65a83be1c1795cb883c52cfa57147d42acc797127df56fc489" dependencies = [ "aes", - "async-fs", - "async-io", - "async-lock", - "async-net", - "blocking", + "ashpd", "cbc", "cipher", "digest", "endi", - "futures-lite", "futures-util", + "getrandom 0.3.3", "hkdf", "hmac", "md-5", "num", "num-bigint-dig", "pbkdf2", - "rand", + "rand 0.9.1", "serde", "sha2", "subtle", - "zbus", + "tokio", + "zbus 5.6.0", + "zbus_macros 5.6.0", "zeroize", - "zvariant", + "zvariant 5.5.1", ] [[package]] @@ -2069,7 +2148,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" dependencies = [ "base64ct", - "rand_core", + "rand_core 0.6.4", "subtle", ] @@ -2098,6 +2177,12 @@ dependencies = [ "base64ct", ] +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + [[package]] name = "petgraph" version = "0.6.5" @@ -2185,15 +2270,15 @@ checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der", "pkcs5", - "rand_core", + "rand_core 0.6.4", "spki", ] [[package]] name = "pkg-config" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "plain" @@ -2211,7 +2296,7 @@ dependencies = [ "concurrent-queue", "hermit-abi", "pin-project-lite", - "rustix", + "rustix 0.38.44", "tracing", "windows-sys 0.59.0", ] @@ -2239,6 +2324,15 @@ dependencies = [ "universal-hash", ] +[[package]] +name = "potential_utf" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +dependencies = [ + "zerovec", +] + [[package]] name = "powerfmt" version = "0.2.0" @@ -2247,49 +2341,55 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ "zerocopy", ] [[package]] name = "proc-macro-crate" -version = "3.2.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" dependencies = [ "toml_edit", ] [[package]] name = "proc-macro2" -version = "1.0.93" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] [[package]] name = "quick-xml" -version = "0.37.2" +version = "0.37.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "165859e9e55f79d67b96c5d96f4e88b6f2695a1972849c15a6a3f5c59fc2c003" +checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb" dependencies = [ "memchr", ] [[package]] name = "quote" -version = "1.0.38" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + [[package]] name = "rand" version = "0.8.5" @@ -2297,8 +2397,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", ] [[package]] @@ -2308,7 +2418,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", ] [[package]] @@ -2317,27 +2437,16 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.2.16", ] [[package]] -name = "rayon" -version = "1.10.0" +name = "rand_core" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", + "getrandom 0.3.3", ] [[package]] @@ -2348,9 +2457,9 @@ checksum = "d3edd4d5d42c92f0a659926464d4cce56b562761267ecf0f469d85b7de384175" [[package]] name = "redox_syscall" -version = "0.5.9" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b568323e98e49e2a0899dcee453dd679fae22d69adf9b11dd508d1549b7e2f" +checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af" dependencies = [ "bitflags", ] @@ -2361,9 +2470,9 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.2.16", "libredox", - "thiserror 2.0.11", + "thiserror 2.0.12", ] [[package]] @@ -2397,9 +2506,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rsa" -version = "0.9.8" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691b" +checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" dependencies = [ "const-oid", "digest", @@ -2408,7 +2517,7 @@ dependencies = [ "num-traits", "pkcs1", "pkcs8", - "rand_core", + "rand_core 0.6.4", "sha2", "signature", "spki", @@ -2450,21 +2559,34 @@ dependencies = [ "bitflags", "errno", "libc", - "linux-raw-sys", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustix" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys 0.9.4", "windows-sys 0.59.0", ] [[package]] name = "rustversion" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" +checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" [[package]] name = "ryu" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "salsa20" @@ -2483,9 +2605,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "scratch" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3cf7c11c38cb994f3d40e8a8cde3bbd1f72a435e4c49e85d6553d8312306152" +checksum = "9f6280af86e5f559536da57a45ebc84948833b3bee313a7dd25232e09c878a52" [[package]] name = "scroll" @@ -2498,9 +2620,9 @@ dependencies = [ [[package]] name = "scroll_derive" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f81c2fde025af7e69b1d1420531c8a8811ca898919db177141a85313b1cb932" +checksum = "1783eabc414609e28a5ba76aee5ddd52199f7107a0b24c2e9746a1ecc34a683d" dependencies = [ "proc-macro2", "quote", @@ -2543,9 +2665,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.25" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" dependencies = [ "serde", ] @@ -2584,9 +2706,9 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" +checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", @@ -2623,9 +2745,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.2" +version = "1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" dependencies = [ "libc", ] @@ -2637,7 +2759,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest", - "rand_core", + "rand_core 0.6.4", ] [[package]] @@ -2668,9 +2790,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" +checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" [[package]] name = "smawk" @@ -2680,9 +2802,9 @@ checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" [[package]] name = "socket2" -version = "0.5.8" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" +checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef" dependencies = [ "libc", "windows-sys 0.52.0", @@ -2741,7 +2863,7 @@ dependencies = [ "bcrypt-pbkdf", "ed25519-dalek", "num-bigint-dig", - "rand_core", + "rand_core 0.6.4", "rsa", "sha2", "signature", @@ -2751,6 +2873,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "static_assertions" version = "1.1.0" @@ -2771,9 +2899,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.98" +version = "2.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" +checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" dependencies = [ "proc-macro2", "quote", @@ -2781,30 +2909,40 @@ dependencies = [ ] [[package]] -name = "sysinfo" -version = "0.33.1" +name = "synstructure" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fc858248ea01b66f19d8e8a6d55f41deaf91e9d495246fd01368d99935c6c01" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sysinfo" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b897c8ea620e181c7955369a31be5f48d9a9121cb59fd33ecef9ff2a34323422" dependencies = [ - "core-foundation-sys", "libc", "memchr", "ntapi", - "rayon", - "windows 0.57.0", + "objc2-core-foundation", + "objc2-io-kit", + "windows 0.61.1", ] [[package]] name = "tempfile" -version = "3.17.1" +version = "3.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e5a0acb1f3f55f65cc4a866c361b2fb2a0ff6366785ae6fbb5f85df07ba230" +checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" dependencies = [ - "cfg-if", "fastrand", - "getrandom 0.3.1", + "getrandom 0.3.3", "once_cell", - "rustix", + "rustix 1.0.7", "windows-sys 0.59.0", ] @@ -2819,9 +2957,9 @@ dependencies = [ [[package]] name = "textwrap" -version = "0.16.1" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" +checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057" dependencies = [ "smawk", ] @@ -2837,11 +2975,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.11" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" dependencies = [ - "thiserror-impl 2.0.11", + "thiserror-impl 2.0.12", ] [[package]] @@ -2857,9 +2995,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.11" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", @@ -2868,9 +3006,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.37" +version = "0.3.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" dependencies = [ "deranged", "itoa", @@ -2885,33 +3023,45 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" [[package]] name = "time-macros" -version = "0.2.19" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" dependencies = [ "num-conv", "time-core", ] [[package]] -name = "tokio" -version = "1.43.1" +name = "tinystr" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "492a604e2fd7f814268a378409e6c92b5525d747d10db9a229723f55a417958c" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tokio" +version = "1.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2513ca694ef9ede0fb23fe71a4ee4107cb102b9dc1930f6d0fd77aae068ae165" dependencies = [ "backtrace", "bytes", "libc", "mio", "pin-project-lite", + "signal-hook-registry", "socket2", "tokio-macros", + "tracing", "windows-sys 0.52.0", ] @@ -2961,15 +3111,15 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.8" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3" [[package]] name = "toml_edit" -version = "0.22.24" +version = "0.22.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" +checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e" dependencies = [ "indexmap", "toml_datetime", @@ -3045,9 +3195,9 @@ checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "unicode-segmentation" @@ -3057,9 +3207,9 @@ checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" -version = "0.1.14" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" [[package]] name = "uniffi" @@ -3201,6 +3351,24 @@ dependencies = [ "subtle", ] +[[package]] +name = "url" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" @@ -3221,43 +3389,43 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasi" -version = "0.13.3+wasi-0.2.2" +version = "0.14.2+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" dependencies = [ "wit-bindgen-rt", ] [[package]] name = "wayland-backend" -version = "0.3.8" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7208998eaa3870dad37ec8836979581506e0c5c64c20c9e79e9d2a10d6f47bf" +checksum = "fe770181423e5fc79d3e2a7f4410b7799d5aab1de4372853de3c6aa13ca24121" dependencies = [ "cc", "downcast-rs", - "rustix", + "rustix 0.38.44", "smallvec", "wayland-sys", ] [[package]] name = "wayland-client" -version = "0.31.8" +version = "0.31.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2120de3d33638aaef5b9f4472bff75f07c56379cf76ea320bd3a3d65ecaf73f" +checksum = "978fa7c67b0847dbd6a9f350ca2569174974cd4082737054dbb7fbb79d7d9a61" dependencies = [ "bitflags", - "rustix", + "rustix 0.38.44", "wayland-backend", "wayland-scanner", ] [[package]] name = "wayland-protocols" -version = "0.31.2" +version = "0.32.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4" +checksum = "779075454e1e9a521794fed15886323ea0feda3f8b0fc1390f5398141310422a" dependencies = [ "bitflags", "wayland-backend", @@ -3267,9 +3435,9 @@ dependencies = [ [[package]] name = "wayland-protocols-wlr" -version = "0.2.0" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6" +checksum = "1cb6cdc73399c0e06504c437fe3cf886f25568dd5454473d565085b36d6a8bbf" dependencies = [ "bitflags", "wayland-backend", @@ -3309,9 +3477,9 @@ dependencies = [ [[package]] name = "widestring" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" +checksum = "dd7cf3379ca1aac9eea11fba24fd7e315d621f8dfe35c8d7d2be8b793726e07d" [[package]] name = "winapi" @@ -3398,7 +3566,7 @@ dependencies = [ "windows-interface 0.59.1", "windows-link", "windows-result 0.3.2", - "windows-strings 0.4.0", + "windows-strings", ] [[package]] @@ -3473,13 +3641,13 @@ dependencies = [ [[package]] name = "windows-registry" -version = "0.4.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" +checksum = "ad1da3e436dc7653dfdf3da67332e22bff09bb0e28b0239e1624499c7830842e" dependencies = [ + "windows-link", "windows-result 0.3.2", - "windows-strings 0.3.1", - "windows-targets 0.53.0", + "windows-strings", ] [[package]] @@ -3500,15 +3668,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "windows-strings" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" -dependencies = [ - "windows-link", -] - [[package]] name = "windows-strings" version = "0.4.0" @@ -3560,29 +3719,13 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", + "windows_i686_gnullvm", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] -[[package]] -name = "windows-targets" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" -dependencies = [ - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", -] - [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -3595,12 +3738,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" - [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -3613,12 +3750,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" - [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -3631,24 +3762,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" -[[package]] -name = "windows_i686_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" - [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" - [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -3661,12 +3780,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_i686_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" - [[package]] name = "windows_plugin_authenticator" version = "0.0.0" @@ -3688,12 +3801,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" - [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -3706,12 +3813,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" - [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -3724,41 +3825,34 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" - [[package]] name = "winnow" -version = "0.7.3" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7f4ea97f6f78012141bcdb6a216b2609f0979ada50b20ca5b52dde2eac2bb1" +checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec" dependencies = [ "memchr", ] [[package]] name = "wit-bindgen-rt" -version = "0.33.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ "bitflags", ] [[package]] name = "wl-clipboard-rs" -version = "0.8.1" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12b41773911497b18ca8553c3daaf8ec9fe9819caf93d451d3055f69de028adb" +checksum = "2a083daad7e8a4b8805ad73947ccadabe62afe37ce0e9787a56ff373d34762c7" dependencies = [ - "derive-new", "libc", "log", - "nix 0.28.0", "os_pipe", + "rustix 0.38.44", "tempfile", "thiserror 1.0.69", "tree_magic_mini", @@ -3768,6 +3862,12 @@ dependencies = [ "wayland-protocols-wlr", ] +[[package]] +name = "writeable" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" + [[package]] name = "x11rb" version = "0.13.1" @@ -3775,7 +3875,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12" dependencies = [ "gethostname", - "rustix", + "rustix 0.38.44", "x11rb-protocol", ] @@ -3795,6 +3895,30 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "yoke" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + [[package]] name = "zbus" version = "4.4.0" @@ -3817,9 +3941,9 @@ dependencies = [ "futures-sink", "futures-util", "hex", - "nix 0.29.0", + "nix", "ordered-stream", - "rand", + "rand 0.8.5", "serde", "serde_repr", "sha1", @@ -3828,9 +3952,37 @@ dependencies = [ "uds_windows", "windows-sys 0.52.0", "xdg-home", - "zbus_macros", - "zbus_names", - "zvariant", + "zbus_macros 4.4.0", + "zbus_names 3.0.0", + "zvariant 4.2.0", +] + +[[package]] +name = "zbus" +version = "5.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2522b82023923eecb0b366da727ec883ace092e7887b61d3da5139f26b44da58" +dependencies = [ + "async-broadcast", + "async-recursion", + "async-trait", + "enumflags2", + "event-listener", + "futures-core", + "futures-lite", + "hex", + "nix", + "ordered-stream", + "serde", + "serde_repr", + "tokio", + "tracing", + "uds_windows", + "windows-sys 0.59.0", + "winnow", + "zbus_macros 5.6.0", + "zbus_names 4.2.0", + "zvariant 5.5.1", ] [[package]] @@ -3843,7 +3995,22 @@ dependencies = [ "proc-macro2", "quote", "syn", - "zvariant_utils", + "zvariant_utils 2.1.0", +] + +[[package]] +name = "zbus_macros" +version = "5.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d2e12843c75108c00c618c2e8ef9675b50b6ec095b36dc965f2e5aed463c15" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", + "zbus_names 4.2.0", + "zvariant 5.5.1", + "zvariant_utils 3.2.0", ] [[package]] @@ -3854,7 +4021,19 @@ checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c" dependencies = [ "serde", "static_assertions", - "zvariant", + "zvariant 4.2.0", +] + +[[package]] +name = "zbus_names" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7be68e64bf6ce8db94f63e72f0c7eb9a60d733f7e0499e628dfab0f84d6bcb97" +dependencies = [ + "serde", + "static_assertions", + "winnow", + "zvariant 5.5.1", ] [[package]] @@ -3867,30 +4046,50 @@ dependencies = [ "serde", "serde_repr", "static_assertions", - "zbus", + "zbus 4.4.0", ] [[package]] name = "zerocopy" -version = "0.7.35" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" dependencies = [ - "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.35" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + [[package]] name = "zeroize" version = "1.8.1" @@ -3911,6 +4110,45 @@ dependencies = [ "syn", ] +[[package]] +name = "zeroizing-alloc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebff5e6b81c1c7dca2d0bd333b2006da48cb37dbcae5a8da888f31fcb3c19934" + +[[package]] +name = "zerotrie" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "zvariant" version = "4.2.0" @@ -3921,7 +4159,22 @@ dependencies = [ "enumflags2", "serde", "static_assertions", - "zvariant_derive", + "zvariant_derive 4.2.0", +] + +[[package]] +name = "zvariant" +version = "5.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "557e89d54880377a507c94cd5452f20e35d14325faf9d2958ebeadce0966c1b2" +dependencies = [ + "endi", + "enumflags2", + "serde", + "url", + "winnow", + "zvariant_derive 5.5.1", + "zvariant_utils 3.2.0", ] [[package]] @@ -3934,7 +4187,20 @@ dependencies = [ "proc-macro2", "quote", "syn", - "zvariant_utils", + "zvariant_utils 2.1.0", +] + +[[package]] +name = "zvariant_derive" +version = "5.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "757779842a0d242061d24c28be589ce392e45350dfb9186dfd7a042a2e19870c" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", + "zvariant_utils 3.2.0", ] [[package]] @@ -3947,3 +4213,17 @@ dependencies = [ "quote", "syn", ] + +[[package]] +name = "zvariant_utils" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e16edfee43e5d7b553b77872d99bc36afdda75c223ca7ad5e3fbecd82ca5fc34" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "static_assertions", + "syn", + "winnow", +] diff --git a/apps/desktop/desktop_native/Cargo.toml b/apps/desktop/desktop_native/Cargo.toml index d9e61124864..1fce5a7c597 100644 --- a/apps/desktop/desktop_native/Cargo.toml +++ b/apps/desktop/desktop_native/Cargo.toml @@ -11,13 +11,14 @@ publish = false [workspace.dependencies] aes = "=0.8.4" anyhow = "=1.0.94" -arboard = { version = "=3.4.1", default-features = false } +arboard = { version = "=3.5.0", default-features = false } argon2 = "=0.5.3" +ashpd = "=0.11.0" base64 = "=0.22.1" -bindgen = "0.71.1" +bindgen = "=0.71.1" bitwarden-russh = { git = "https://github.com/bitwarden/bitwarden-russh.git", rev = "3d48f140fd506412d186203238993163a8c4e536" } byteorder = "=1.5.0" -bytes = "1.9.0" +bytes = "=1.10.1" cbc = "=0.1.2" core-foundation = "=0.10.0" dirs = "=6.0.0" @@ -33,12 +34,12 @@ log = "=0.4.25" napi = "=2.16.15" napi-build = "=2.1.4" napi-derive = "=2.16.13" -oo7 = "=0.3.3" +oo7 = "=0.4.3" oslog = "=0.2.0" pin-project = "=1.1.10" pkcs8 = "=0.10.2" -rand = "=0.8.5" -rsa = "=0.9.8" +rand = "=0.9.1" +rsa = "=0.9.6" russh-cryptovec = "=0.7.3" scopeguard = "=1.2.0" security-framework = "=3.1.0" @@ -49,17 +50,18 @@ sha2 = "=0.10.8" simplelog = "=0.12.2" ssh-encoding = "=0.2.0" ssh-key = {version = "=0.6.7", default-features = false } -sysinfo = "0.33.1" -thiserror = "=1.0.69" -tokio = "=1.43.1" +sysinfo = "=0.35.0" +thiserror = "=2.0.12" +tokio = "=1.45.0" tokio-stream = "=0.1.15" tokio-util = "=0.7.13" typenum = "=1.18.0" uniffi = "=0.28.3" -widestring = "=1.1.0" +widestring = "=1.2.0" windows = "=0.61.1" windows-core = "=0.61.0" windows-future = "=0.2.0" -windows-registry = "=0.4.0" +windows-registry = "=0.5.1" zbus = "=4.4.0" zbus_polkit = "=4.0.0" +zeroizing-alloc = "=0.1.0" diff --git a/apps/desktop/desktop_native/build.js b/apps/desktop/desktop_native/build.js index da61da15f9d..2edd0e89616 100644 --- a/apps/desktop/desktop_native/build.js +++ b/apps/desktop/desktop_native/build.js @@ -45,6 +45,10 @@ function buildProxyBin(target, release = true) { } } +function installTarget(target) { + child_process.execSync(`rustup target add ${target}`, { stdio: 'inherit', cwd: __dirname }); +} + if (!crossPlatform && !target) { console.log(`Building native modules in ${mode} mode for the native architecture`); buildNapiModule(false, mode === "release"); @@ -54,6 +58,7 @@ if (!crossPlatform && !target) { if (target) { console.log(`Building for target: ${target} in ${mode} mode`); + installTarget(target); buildNapiModule(target, mode === "release"); buildProxyBin(target, mode === "release"); return; @@ -70,6 +75,7 @@ if (process.platform === "linux") { } platformTargets.forEach(([target, _]) => { + installTarget(target); buildNapiModule(target); buildProxyBin(target); }); diff --git a/apps/desktop/desktop_native/core/Cargo.toml b/apps/desktop/desktop_native/core/Cargo.toml index a8a8e0a2a44..7cd67dbad6a 100644 --- a/apps/desktop/desktop_native/core/Cargo.toml +++ b/apps/desktop/desktop_native/core/Cargo.toml @@ -55,6 +55,7 @@ rsa = { workspace = true } ed25519 = { workspace = true, features = ["pkcs8"] } bytes = { workspace = true } sysinfo = { workspace = true, features = ["windows"] } +zeroizing-alloc = { workspace = true } [target.'cfg(windows)'.dependencies] widestring = { workspace = true, optional = true } @@ -84,6 +85,7 @@ desktop_objc = { path = "../objc" } [target.'cfg(target_os = "linux")'.dependencies] oo7 = { workspace = true } libc = { workspace = true } +ashpd = { workspace = true } zbus = { workspace = true, optional = true } zbus_polkit = { workspace = true, optional = true } diff --git a/apps/desktop/desktop_native/core/src/autostart/linux.rs b/apps/desktop/desktop_native/core/src/autostart/linux.rs new file mode 100644 index 00000000000..1fd02a6ea5d --- /dev/null +++ b/apps/desktop/desktop_native/core/src/autostart/linux.rs @@ -0,0 +1,21 @@ +use anyhow::Result; +use ashpd::desktop::background::Background; + +pub async fn set_autostart(autostart: bool, params: Vec) -> Result<()> { + let request = if params.is_empty() { + Background::request().auto_start(autostart) + } else { + Background::request().command(params).auto_start(autostart) + }; + + match request.send().await.and_then(|r| r.response()) { + Ok(response) => { + println!("[ASHPD] Autostart enabled: {:?}", response); + Ok(()) + } + Err(err) => { + println!("[ASHPD] Error enabling autostart: {}", err); + Err(anyhow::anyhow!("error enabling autostart {}", err)) + } + } +} diff --git a/apps/desktop/desktop_native/core/src/autostart/mod.rs b/apps/desktop/desktop_native/core/src/autostart/mod.rs new file mode 100644 index 00000000000..78e27eb433e --- /dev/null +++ b/apps/desktop/desktop_native/core/src/autostart/mod.rs @@ -0,0 +1,5 @@ +#[cfg_attr(target_os = "linux", path = "linux.rs")] +#[cfg_attr(target_os = "windows", path = "unimplemented.rs")] +#[cfg_attr(target_os = "macos", path = "unimplemented.rs")] +mod autostart_impl; +pub use autostart_impl::*; diff --git a/apps/desktop/desktop_native/core/src/autostart/unimplemented.rs b/apps/desktop/desktop_native/core/src/autostart/unimplemented.rs new file mode 100644 index 00000000000..14f567bdc65 --- /dev/null +++ b/apps/desktop/desktop_native/core/src/autostart/unimplemented.rs @@ -0,0 +1,5 @@ +use anyhow::Result; + +pub async fn set_autostart(_autostart: bool, _params: Vec) -> Result<()> { + unimplemented!(); +} diff --git a/apps/desktop/desktop_native/core/src/biometric/unix.rs b/apps/desktop/desktop_native/core/src/biometric/unix.rs index e57b77515e3..60392adc9d7 100644 --- a/apps/desktop/desktop_native/core/src/biometric/unix.rs +++ b/apps/desktop/desktop_native/core/src/biometric/unix.rs @@ -104,6 +104,6 @@ impl super::BiometricTrait for Biometric { fn random_challenge() -> [u8; 16] { let mut challenge = [0u8; 16]; - rand::thread_rng().fill_bytes(&mut challenge); + rand::rng().fill_bytes(&mut challenge); challenge } diff --git a/apps/desktop/desktop_native/core/src/biometric/windows.rs b/apps/desktop/desktop_native/core/src/biometric/windows.rs index b9fea345c16..4c2e2c8ae25 100644 --- a/apps/desktop/desktop_native/core/src/biometric/windows.rs +++ b/apps/desktop/desktop_native/core/src/biometric/windows.rs @@ -174,7 +174,7 @@ impl super::BiometricTrait for Biometric { fn random_challenge() -> [u8; 16] { let mut challenge = [0u8; 16]; - rand::thread_rng().fill_bytes(&mut challenge); + rand::rng().fill_bytes(&mut challenge); challenge } diff --git a/apps/desktop/desktop_native/core/src/lib.rs b/apps/desktop/desktop_native/core/src/lib.rs index 4a6686cc1f5..a72ec04e9c2 100644 --- a/apps/desktop/desktop_native/core/src/lib.rs +++ b/apps/desktop/desktop_native/core/src/lib.rs @@ -1,4 +1,5 @@ pub mod autofill; +pub mod autostart; pub mod biometric; pub mod clipboard; pub mod crypto; @@ -8,3 +9,8 @@ pub mod password; pub mod powermonitor; pub mod process_isolation; pub mod ssh_agent; + +use zeroizing_alloc::ZeroAlloc; + +#[global_allocator] +static ALLOC: ZeroAlloc = ZeroAlloc(std::alloc::System); diff --git a/apps/desktop/desktop_native/napi/index.d.ts b/apps/desktop/desktop_native/napi/index.d.ts index 17ac120662d..0718c12553f 100644 --- a/apps/desktop/desktop_native/napi/index.d.ts +++ b/apps/desktop/desktop_native/napi/index.d.ts @@ -111,6 +111,9 @@ export declare namespace ipc { send(message: string): number } } +export declare namespace autostart { + export function setAutostart(autostart: boolean, params: Array): Promise +} export declare namespace autofill { export function runCommand(value: string): Promise export const enum UserVerification { diff --git a/apps/desktop/desktop_native/napi/src/lib.rs b/apps/desktop/desktop_native/napi/src/lib.rs index 33bdc3d3d57..3451ef2bdc5 100644 --- a/apps/desktop/desktop_native/napi/src/lib.rs +++ b/apps/desktop/desktop_native/napi/src/lib.rs @@ -477,6 +477,16 @@ pub mod ipc { } } +#[napi] +pub mod autostart { + #[napi] + pub async fn set_autostart(autostart: bool, params: Vec) -> napi::Result<()> { + desktop_core::autostart::set_autostart(autostart, params) + .await + .map_err(|e| napi::Error::from_reason(format!("Error setting autostart - {e} - {e:?}"))) + } +} + #[napi] pub mod autofill { use desktop_core::ipc::server::{Message, MessageType}; diff --git a/apps/desktop/desktop_native/rust-toolchain.toml b/apps/desktop/desktop_native/rust-toolchain.toml new file mode 100644 index 00000000000..898a61f3f4b --- /dev/null +++ b/apps/desktop/desktop_native/rust-toolchain.toml @@ -0,0 +1,4 @@ +[toolchain] +channel = "1.85.0" +components = [ "rustfmt", "clippy" ] +profile = "minimal" diff --git a/apps/desktop/electron-builder.json b/apps/desktop/electron-builder.json index d51d9412d80..1e96198d4ad 100644 --- a/apps/desktop/electron-builder.json +++ b/apps/desktop/electron-builder.json @@ -243,7 +243,7 @@ }, "snap": { "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.", + "description": "Password Manager\n**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/jest.config.js b/apps/desktop/jest.config.js index 73f5ada287a..14cd959810e 100644 --- a/apps/desktop/jest.config.js +++ b/apps/desktop/jest.config.js @@ -1,18 +1,17 @@ const { pathsToModuleNameMapper } = require("ts-jest"); -const { compilerOptions } = require("./tsconfig"); +const { compilerOptions } = require("../../tsconfig.base"); const sharedConfig = require("../../libs/shared/jest.config.angular"); /** @type {import('jest').Config} */ module.exports = { ...sharedConfig, - preset: "jest-preset-angular", setupFilesAfterEnv: ["/test.setup.ts"], moduleNameMapper: pathsToModuleNameMapper( - { "@bitwarden/common/spec": ["../../libs/common/spec"], ...(compilerOptions?.paths ?? {}) }, + { "@bitwarden/common/spec": ["libs/common/spec"], ...(compilerOptions?.paths ?? {}) }, { - prefix: "/", + prefix: "/../../", }, ), }; diff --git a/apps/desktop/native-messaging-test-runner/package-lock.json b/apps/desktop/native-messaging-test-runner/package-lock.json index d506e109e94..37b8cf96ff3 100644 --- a/apps/desktop/native-messaging-test-runner/package-lock.json +++ b/apps/desktop/native-messaging-test-runner/package-lock.json @@ -17,7 +17,7 @@ "yargs": "17.7.2" }, "devDependencies": { - "@types/node": "22.14.1", + "@types/node": "22.15.3", "typescript": "5.4.2" } }, @@ -101,18 +101,18 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.14.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.1.tgz", - "integrity": "sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw==", + "version": "22.15.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.3.tgz", + "integrity": "sha512-lX7HFZeHf4QG/J7tBZqrCAXwz9J5RD56Y6MpP0eJkka8p+K0RY/yBTW7CYFJ4VGCclxqOLKmiGP5juQc6MKgcw==", "license": "MIT", "dependencies": { "undici-types": "~6.21.0" } }, "node_modules/acorn": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", - "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", "license": "MIT", "bin": { "acorn": "bin/acorn" diff --git a/apps/desktop/native-messaging-test-runner/package.json b/apps/desktop/native-messaging-test-runner/package.json index f67ab259d3b..ea6b1b3e7a8 100644 --- a/apps/desktop/native-messaging-test-runner/package.json +++ b/apps/desktop/native-messaging-test-runner/package.json @@ -22,7 +22,7 @@ "yargs": "17.7.2" }, "devDependencies": { - "@types/node": "22.14.1", + "@types/node": "22.15.3", "typescript": "5.4.2" }, "_moduleAliases": { diff --git a/apps/desktop/native-messaging-test-runner/src/ipc.service.ts b/apps/desktop/native-messaging-test-runner/src/ipc.service.ts index b02ff1a4225..d8616e9757a 100644 --- a/apps/desktop/native-messaging-test-runner/src/ipc.service.ts +++ b/apps/desktop/native-messaging-test-runner/src/ipc.service.ts @@ -15,6 +15,8 @@ const DEFAULT_MESSAGE_TIMEOUT = 10 * 1000; // 10 seconds export type MessageHandler = (MessageCommon) => void; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum IPCConnectionState { Disconnected = "disconnected", Connecting = "connecting", diff --git a/apps/desktop/native-messaging-test-runner/src/native-message.service.ts b/apps/desktop/native-messaging-test-runner/src/native-message.service.ts index c01d581afe8..c2356f93e28 100644 --- a/apps/desktop/native-messaging-test-runner/src/native-message.service.ts +++ b/apps/desktop/native-messaging-test-runner/src/native-message.service.ts @@ -220,7 +220,7 @@ export default class NativeMessageService { const sharedKey = await this.getSharedKeyForKey(key); - return this.encryptService.encrypt(commandDataString, sharedKey); + return this.encryptService.encryptString(commandDataString, sharedKey); } private async decryptResponsePayload( @@ -228,11 +228,7 @@ export default class NativeMessageService { key: string, ): Promise { const sharedKey = await this.getSharedKeyForKey(key); - const decrypted = await this.encryptService.decryptToUtf8( - payload, - sharedKey, - "native-messaging-session", - ); + const decrypted = await this.encryptService.decryptString(payload, sharedKey); return JSON.parse(decrypted); } diff --git a/apps/desktop/native-messaging-test-runner/tsconfig.json b/apps/desktop/native-messaging-test-runner/tsconfig.json index 59c7040e509..608e5a3bf4c 100644 --- a/apps/desktop/native-messaging-test-runner/tsconfig.json +++ b/apps/desktop/native-messaging-test-runner/tsconfig.json @@ -1,6 +1,6 @@ { + "extends": "../tsconfig", "compilerOptions": { - "baseUrl": "./", "outDir": "dist", "target": "es6", "module": "CommonJS", @@ -10,12 +10,7 @@ "sourceMap": false, "declaration": false, "paths": { - "@src/*": ["src/*"], - "@bitwarden/admin-console/*": ["../../../libs/admin-console/src/*"], - "@bitwarden/auth/*": ["../../../libs/auth/src/*"], - "@bitwarden/common/*": ["../../../libs/common/src/*"], - "@bitwarden/key-management": ["../../../libs/key-management/src/"], - "@bitwarden/node/*": ["../../../libs/node/src/*"] + "@src/*": ["src/*"] }, "plugins": [ { diff --git a/apps/desktop/package.json b/apps/desktop/package.json index 26efe8e6428..2488b12b4ca 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": "2025.5.0", + "version": "2025.5.1", "keywords": [ "bitwarden", "password", diff --git a/apps/desktop/src/app/accounts/settings.component.html b/apps/desktop/src/app/accounts/settings.component.html index bcbd9969f96..e56615c9122 100644 --- a/apps/desktop/src/app/accounts/settings.component.html +++ b/apps/desktop/src/app/accounts/settings.component.html @@ -440,6 +440,22 @@ "enableSshAgentDesc" | i18n }}
+
+ + + {{ + "sshAgentPromptBehaviorDesc" | i18n + }} +
diff --git a/apps/desktop/src/vault/app/vault/add-edit.component.ts b/apps/desktop/src/vault/app/vault/add-edit.component.ts index 2c8b5a8321a..eb04003a418 100644 --- a/apps/desktop/src/vault/app/vault/add-edit.component.ts +++ b/apps/desktop/src/vault/app/vault/add-edit.component.ts @@ -30,6 +30,7 @@ const BroadcasterSubscriptionId = "AddEditComponent"; @Component({ selector: "app-vault-add-edit", templateUrl: "add-edit.component.html", + standalone: false, }) export class AddEditComponent extends BaseAddEditComponent implements OnInit, OnChanges, OnDestroy { @ViewChild("form") diff --git a/apps/desktop/src/vault/app/vault/attachments.component.ts b/apps/desktop/src/vault/app/vault/attachments.component.ts index ea4f49b8431..a116a4d2acb 100644 --- a/apps/desktop/src/vault/app/vault/attachments.component.ts +++ b/apps/desktop/src/vault/app/vault/attachments.component.ts @@ -5,6 +5,7 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; @@ -17,6 +18,7 @@ import { KeyService } from "@bitwarden/key-management"; @Component({ selector: "app-vault-attachments", templateUrl: "attachments.component.html", + standalone: false, }) export class AttachmentsComponent extends BaseAttachmentsComponent { constructor( @@ -33,6 +35,7 @@ export class AttachmentsComponent extends BaseAttachmentsComponent { billingAccountProfileStateService: BillingAccountProfileStateService, accountService: AccountService, toastService: ToastService, + configService: ConfigService, ) { super( cipherService, @@ -49,6 +52,7 @@ export class AttachmentsComponent extends BaseAttachmentsComponent { billingAccountProfileStateService, accountService, toastService, + configService, ); } } diff --git a/apps/desktop/src/vault/app/vault/collections.component.ts b/apps/desktop/src/vault/app/vault/collections.component.ts index e7684c3c07a..46455d04cd2 100644 --- a/apps/desktop/src/vault/app/vault/collections.component.ts +++ b/apps/desktop/src/vault/app/vault/collections.component.ts @@ -13,6 +13,7 @@ import { ToastService } from "@bitwarden/components"; @Component({ selector: "app-vault-collections", templateUrl: "collections.component.html", + standalone: false, }) export class CollectionsComponent extends BaseCollectionsComponent { constructor( diff --git a/apps/desktop/src/vault/app/vault/credential-generator-dialog.component.ts b/apps/desktop/src/vault/app/vault/credential-generator-dialog.component.ts index 2858d7330e5..1a375fc0f5a 100644 --- a/apps/desktop/src/vault/app/vault/credential-generator-dialog.component.ts +++ b/apps/desktop/src/vault/app/vault/credential-generator-dialog.component.ts @@ -31,13 +31,14 @@ export interface CredentialGeneratorDialogResult { generatedValue?: string; } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum CredentialGeneratorDialogAction { Selected = "selected", Canceled = "canceled", } @Component({ - standalone: true, selector: "credential-generator-dialog", templateUrl: "credential-generator-dialog.component.html", imports: [ diff --git a/apps/desktop/src/vault/app/vault/folder-add-edit.component.ts b/apps/desktop/src/vault/app/vault/folder-add-edit.component.ts index cdb879693c0..cecd5cd671c 100644 --- a/apps/desktop/src/vault/app/vault/folder-add-edit.component.ts +++ b/apps/desktop/src/vault/app/vault/folder-add-edit.component.ts @@ -14,6 +14,7 @@ import { KeyService } from "@bitwarden/key-management"; @Component({ selector: "app-folder-add-edit", templateUrl: "folder-add-edit.component.html", + standalone: false, }) export class FolderAddEditComponent extends BaseFolderAddEditComponent { constructor( diff --git a/apps/desktop/src/vault/app/vault/item-footer.component.html b/apps/desktop/src/vault/app/vault/item-footer.component.html index 6915555c08b..5a067da372e 100644 --- a/apps/desktop/src/vault/app/vault/item-footer.component.html +++ b/apps/desktop/src/vault/app/vault/item-footer.component.html @@ -2,14 +2,13 @@ @@ -115,7 +114,7 @@ id="newItemDropdown" appA11yTitle="{{ 'new' | i18n }}" > - + {{ "new" | i18n }} @@ -140,7 +139,7 @@ diff --git a/apps/web/src/app/admin-console/organizations/collections/vault-header/vault-header.component.ts b/apps/web/src/app/admin-console/organizations/collections/vault-header/vault-header.component.ts index 7efb79ebdb6..b343d5874bc 100644 --- a/apps/web/src/app/admin-console/organizations/collections/vault-header/vault-header.component.ts +++ b/apps/web/src/app/admin-console/organizations/collections/vault-header/vault-header.component.ts @@ -35,7 +35,6 @@ import { import { CollectionDialogTabType } from "../../shared/components/collection-dialog"; @Component({ - standalone: true, selector: "app-org-vault-header", templateUrl: "./vault-header.component.html", imports: [ @@ -117,7 +116,7 @@ export class VaultHeaderComponent { } get icon() { - return this.filter.collectionId !== undefined ? "bwi-collection" : ""; + return this.filter.collectionId !== undefined ? "bwi-collection-shared" : ""; } protected get showBreadcrumbs() { diff --git a/apps/web/src/app/admin-console/organizations/collections/vault.component.html b/apps/web/src/app/admin-console/organizations/collections/vault.component.html index 22da9a566f4..e8782ca0f2d 100644 --- a/apps/web/src/app/admin-console/organizations/collections/vault.component.html +++ b/apps/web/src/app/admin-console/organizations/collections/vault.component.html @@ -153,6 +153,3 @@
- - - diff --git a/apps/web/src/app/admin-console/organizations/collections/vault.component.ts b/apps/web/src/app/admin-console/organizations/collections/vault.component.ts index edf93e3c953..bc0f517d1fb 100644 --- a/apps/web/src/app/admin-console/organizations/collections/vault.component.ts +++ b/apps/web/src/app/admin-console/organizations/collections/vault.component.ts @@ -125,20 +125,25 @@ import { BulkCollectionsDialogResult, } from "./bulk-collections-dialog"; import { CollectionAccessRestrictedComponent } from "./collection-access-restricted.component"; -import { getNestedCollectionTree, getFlatCollectionTree } from "./utils"; +import { + getNestedCollectionTree, + getFlatCollectionTree, + getNestedCollectionTree_vNext, +} from "./utils"; import { VaultFilterModule } from "./vault-filter/vault-filter.module"; import { VaultHeaderComponent } from "./vault-header/vault-header.component"; const BroadcasterSubscriptionId = "OrgVaultComponent"; const SearchTextDebounceInterval = 200; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums enum AddAccessStatusType { All = 0, AddAccess = 1, } @Component({ - standalone: true, selector: "app-org-vault", templateUrl: "vault.component.html", imports: [ @@ -360,8 +365,7 @@ export class VaultComponent implements OnInit, OnDestroy { if (this.organization.canEditAllCiphers) { return collections; } - // The user is only allowed to add/edit items to assigned collections that are not readonly - return collections.filter((c) => c.assigned && !c.readOnly); + return collections.filter((c) => c.assigned); }), shareReplay({ refCount: true, bufferSize: 1 }), ); @@ -419,9 +423,16 @@ export class VaultComponent implements OnInit, OnDestroy { }), ); - const nestedCollections$ = allCollections$.pipe( - map((collections) => getNestedCollectionTree(collections)), - shareReplay({ refCount: true, bufferSize: 1 }), + const nestedCollections$ = combineLatest([ + allCollections$, + this.configService.getFeatureFlag$(FeatureFlag.OptimizeNestedTraverseTypescript), + ]).pipe( + map( + ([collections, shouldOptimize]) => + (shouldOptimize + ? getNestedCollectionTree_vNext(collections) + : getNestedCollectionTree(collections)) as TreeNode[], + ), ); const collections$ = combineLatest([ @@ -853,6 +864,7 @@ export class VaultComponent implements OnInit, OnDestroy { const dialogRef = AttachmentsV2Component.open(this.dialogService, { cipherId: cipher.id as CipherId, organizationId: cipher.organizationId as OrganizationId, + admin: true, }); const result = await firstValueFrom(dialogRef.closed); diff --git a/apps/web/src/app/admin-console/organizations/create/organization-information.component.ts b/apps/web/src/app/admin-console/organizations/create/organization-information.component.ts index fc168f842dc..cd14b73a156 100644 --- a/apps/web/src/app/admin-console/organizations/create/organization-information.component.ts +++ b/apps/web/src/app/admin-console/organizations/create/organization-information.component.ts @@ -9,6 +9,7 @@ import { AccountService } from "@bitwarden/common/auth/abstractions/account.serv @Component({ selector: "app-org-info", templateUrl: "organization-information.component.html", + standalone: false, }) export class OrganizationInformationComponent implements OnInit { @Input() nameOnly = false; diff --git a/apps/web/src/app/admin-console/organizations/guards/is-enterprise-org.guard.spec.ts b/apps/web/src/app/admin-console/organizations/guards/is-enterprise-org.guard.spec.ts index f5fce0e5e42..bc4a942301a 100644 --- a/apps/web/src/app/admin-console/organizations/guards/is-enterprise-org.guard.spec.ts +++ b/apps/web/src/app/admin-console/organizations/guards/is-enterprise-org.guard.spec.ts @@ -21,16 +21,19 @@ import { isEnterpriseOrgGuard } from "./is-enterprise-org.guard"; @Component({ template: "

This is the home screen!

", + standalone: false, }) export class HomescreenComponent {} @Component({ template: "

This component can only be accessed by a enterprise organization!

", + standalone: false, }) export class IsEnterpriseOrganizationComponent {} @Component({ template: "

This is the organization upgrade screen!

", + standalone: false, }) export class OrganizationUpgradeScreenComponent {} diff --git a/apps/web/src/app/admin-console/organizations/guards/is-paid-org.guard.spec.ts b/apps/web/src/app/admin-console/organizations/guards/is-paid-org.guard.spec.ts index 8efed8cefa2..ab5fd79321a 100644 --- a/apps/web/src/app/admin-console/organizations/guards/is-paid-org.guard.spec.ts +++ b/apps/web/src/app/admin-console/organizations/guards/is-paid-org.guard.spec.ts @@ -20,16 +20,19 @@ import { isPaidOrgGuard } from "./is-paid-org.guard"; @Component({ template: "

This is the home screen!

", + standalone: false, }) export class HomescreenComponent {} @Component({ template: "

This component can only be accessed by a paid organization!

", + standalone: false, }) export class PaidOrganizationOnlyComponent {} @Component({ template: "

This is the organization upgrade screen!

", + standalone: false, }) export class OrganizationUpgradeScreenComponent {} diff --git a/apps/web/src/app/admin-console/organizations/guards/org-redirect.guard.spec.ts b/apps/web/src/app/admin-console/organizations/guards/org-redirect.guard.spec.ts index fa348867a86..9dc084484f3 100644 --- a/apps/web/src/app/admin-console/organizations/guards/org-redirect.guard.spec.ts +++ b/apps/web/src/app/admin-console/organizations/guards/org-redirect.guard.spec.ts @@ -19,16 +19,19 @@ import { organizationRedirectGuard } from "./org-redirect.guard"; @Component({ template: "

This is the home screen!

", + standalone: false, }) export class HomescreenComponent {} @Component({ template: "

This is the admin console!

", + standalone: false, }) export class AdminConsoleComponent {} @Component({ template: "

This is a subroute of the admin console!

", + standalone: false, }) export class AdminConsoleSubrouteComponent {} diff --git a/apps/web/src/app/admin-console/organizations/integrations/integrations.component.ts b/apps/web/src/app/admin-console/organizations/integrations/integrations.component.ts index 80c12af8522..e6a62b1db73 100644 --- a/apps/web/src/app/admin-console/organizations/integrations/integrations.component.ts +++ b/apps/web/src/app/admin-console/organizations/integrations/integrations.component.ts @@ -22,7 +22,6 @@ import { Integration } from "../shared/components/integrations/models"; @Component({ selector: "ac-integrations", templateUrl: "./integrations.component.html", - standalone: true, imports: [ SharedModule, SharedOrganizationModule, diff --git a/apps/web/src/app/admin-console/organizations/layouts/organization-layout.component.html b/apps/web/src/app/admin-console/organizations/layouts/organization-layout.component.html index fec790dabcb..f991678e834 100644 --- a/apps/web/src/app/admin-console/organizations/layouts/organization-layout.component.html +++ b/apps/web/src/app/admin-console/organizations/layouts/organization-layout.component.html @@ -6,6 +6,7 @@ icon="bwi-filter" *ngIf="organization.useRiskInsights" [text]="'accessIntelligence' | i18n" + route="access-intelligence" > @@ -138,22 +139,6 @@ - - {{ "accountDeprovisioningNotification" | i18n }} - - {{ "learnMore" | i18n }} - - canAccessOrgAdmin(org); - protected domainVerificationNavigationTextKey: string; protected integrationPageEnabled$: Observable; @@ -66,7 +61,6 @@ export class OrganizationLayoutComponent implements OnInit { organizationIsUnmanaged$: Observable; enterpriseOrganization$: Observable; - showAccountDeprovisioningBanner$: Observable; protected isBreadcrumbEventLogsEnabled$: Observable; protected showSponsoredFamiliesDropdown$: Observable; protected canShowPoliciesTab$: Observable; @@ -78,7 +72,6 @@ export class OrganizationLayoutComponent implements OnInit { private configService: ConfigService, private policyService: PolicyService, private providerService: ProviderService, - protected bannerService: AccountDeprovisioningBannerService, private accountService: AccountService, private freeFamiliesPolicyService: FreeFamiliesPolicyService, private organizationBillingService: OrganizationBillingServiceAbstraction, @@ -101,20 +94,6 @@ export class OrganizationLayoutComponent implements OnInit { this.showSponsoredFamiliesDropdown$ = this.freeFamiliesPolicyService.showSponsoredFamiliesDropdown$(this.organization$); - this.showAccountDeprovisioningBanner$ = combineLatest([ - this.bannerService.showBanner$, - this.configService.getFeatureFlag$(FeatureFlag.AccountDeprovisioningBanner), - this.organization$, - ]).pipe( - map( - ([dismissedOrgs, featureFlagEnabled, organization]) => - organization.productTierType === ProductTierType.Enterprise && - organization.isAdmin && - !dismissedOrgs?.includes(organization.id) && - featureFlagEnabled, - ), - ); - this.canAccessExport$ = this.organization$.pipe(map((org) => org.canAccessExport)); this.showPaymentAndHistory$ = this.organization$.pipe( @@ -146,12 +125,6 @@ export class OrganizationLayoutComponent implements OnInit { this.integrationPageEnabled$ = this.organization$.pipe(map((org) => org.canAccessIntegrations)); - this.domainVerificationNavigationTextKey = (await this.configService.getFeatureFlag( - FeatureFlag.AccountDeprovisioning, - )) - ? "claimedDomains" - : "domainVerification"; - this.canShowPoliciesTab$ = this.organization$.pipe( switchMap((organization) => this.organizationBillingService diff --git a/apps/web/src/app/admin-console/organizations/layouts/services/account-deprovisioning-banner.service.spec.ts b/apps/web/src/app/admin-console/organizations/layouts/services/account-deprovisioning-banner.service.spec.ts deleted file mode 100644 index 414828969df..00000000000 --- a/apps/web/src/app/admin-console/organizations/layouts/services/account-deprovisioning-banner.service.spec.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { firstValueFrom } from "rxjs"; - -import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; -import { Utils } from "@bitwarden/common/platform/misc/utils"; -import { - FakeAccountService, - FakeStateProvider, - mockAccountServiceWith, -} from "@bitwarden/common/spec"; -import { UserId } from "@bitwarden/common/types/guid"; - -import { AccountDeprovisioningBannerService } from "./account-deprovisioning-banner.service"; - -describe("Account Deprovisioning Banner Service", () => { - const userId = Utils.newGuid() as UserId; - let accountService: FakeAccountService; - let stateProvider: FakeStateProvider; - let bannerService: AccountDeprovisioningBannerService; - - beforeEach(async () => { - accountService = mockAccountServiceWith(userId); - stateProvider = new FakeStateProvider(accountService); - bannerService = new AccountDeprovisioningBannerService(stateProvider); - }); - - it("updates state with single org", async () => { - const fakeOrg = new Organization(); - fakeOrg.id = "123"; - - await bannerService.hideBanner(fakeOrg); - const state = await firstValueFrom(bannerService.showBanner$); - - expect(state).toEqual([fakeOrg.id]); - }); - - it("updates state with multiple orgs", async () => { - const fakeOrg1 = new Organization(); - fakeOrg1.id = "123"; - const fakeOrg2 = new Organization(); - fakeOrg2.id = "234"; - const fakeOrg3 = new Organization(); - fakeOrg3.id = "987"; - - await bannerService.hideBanner(fakeOrg1); - await bannerService.hideBanner(fakeOrg2); - await bannerService.hideBanner(fakeOrg3); - - const state = await firstValueFrom(bannerService.showBanner$); - - expect(state).toContain(fakeOrg1.id); - expect(state).toContain(fakeOrg2.id); - expect(state).toContain(fakeOrg3.id); - }); - - it("does not add the same org id multiple times", async () => { - const fakeOrg = new Organization(); - fakeOrg.id = "123"; - - await bannerService.hideBanner(fakeOrg); - await bannerService.hideBanner(fakeOrg); - - const state = await firstValueFrom(bannerService.showBanner$); - - expect(state).toEqual([fakeOrg.id]); - }); - - it("does not add null to the state", async () => { - await bannerService.hideBanner(null as unknown as Organization); - await bannerService.hideBanner(undefined as unknown as Organization); - - const state = await firstValueFrom(bannerService.showBanner$); - - expect(state).toBeNull(); - }); -}); diff --git a/apps/web/src/app/admin-console/organizations/layouts/services/account-deprovisioning-banner.service.ts b/apps/web/src/app/admin-console/organizations/layouts/services/account-deprovisioning-banner.service.ts deleted file mode 100644 index 86a6b7df3e2..00000000000 --- a/apps/web/src/app/admin-console/organizations/layouts/services/account-deprovisioning-banner.service.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Injectable } from "@angular/core"; - -import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; -import { - ACCOUNT_DEPROVISIONING_BANNER_DISK, - StateProvider, - UserKeyDefinition, -} from "@bitwarden/common/platform/state"; - -export const SHOW_BANNER_KEY = new UserKeyDefinition( - ACCOUNT_DEPROVISIONING_BANNER_DISK, - "accountDeprovisioningBanner", - { - deserializer: (b) => b, - clearOn: [], - }, -); - -@Injectable({ providedIn: "root" }) -export class AccountDeprovisioningBannerService { - private _showBanner = this.stateProvider.getActive(SHOW_BANNER_KEY); - - showBanner$ = this._showBanner.state$; - - constructor(private stateProvider: StateProvider) {} - - async hideBanner(organization: Organization) { - await this._showBanner.update((state) => { - if (!organization) { - return state; - } - if (!state) { - return [organization.id]; - } else if (!state.includes(organization.id)) { - return [...state, organization.id]; - } - return state; - }); - } -} diff --git a/apps/web/src/app/admin-console/organizations/manage/entity-events.component.ts b/apps/web/src/app/admin-console/organizations/manage/entity-events.component.ts index 4eab2969fff..10f68695e88 100644 --- a/apps/web/src/app/admin-console/organizations/manage/entity-events.component.ts +++ b/apps/web/src/app/admin-console/organizations/manage/entity-events.component.ts @@ -38,7 +38,6 @@ export interface EntityEventsDialogParams { @Component({ imports: [SharedModule], templateUrl: "entity-events.component.html", - standalone: true, }) export class EntityEventsComponent implements OnInit, OnDestroy { loading = true; diff --git a/apps/web/src/app/admin-console/organizations/manage/events.component.ts b/apps/web/src/app/admin-console/organizations/manage/events.component.ts index 737a38ee2ab..3daa6c17d07 100644 --- a/apps/web/src/app/admin-console/organizations/manage/events.component.ts +++ b/apps/web/src/app/admin-console/organizations/manage/events.component.ts @@ -48,6 +48,7 @@ const EVENT_SYSTEM_USER_TO_TRANSLATION: Record = { @Component({ selector: "app-org-events", templateUrl: "events.component.html", + standalone: false, }) export class EventsComponent extends BaseEventsComponent implements OnInit, OnDestroy { exportFileName = "org-events"; diff --git a/apps/web/src/app/admin-console/organizations/manage/group-add-edit.component.html b/apps/web/src/app/admin-console/organizations/manage/group-add-edit.component.html index 5c8c0c07f88..101512dea04 100644 --- a/apps/web/src/app/admin-console/organizations/manage/group-add-edit.component.html +++ b/apps/web/src/app/admin-console/organizations/manage/group-add-edit.component.html @@ -23,7 +23,7 @@ {{ "characterMaximum" | i18n: 100 }} - + {{ "externalId" | i18n }} {{ "externalIdDesc" | i18n }} diff --git a/apps/web/src/app/admin-console/organizations/manage/group-add-edit.component.ts b/apps/web/src/app/admin-console/organizations/manage/group-add-edit.component.ts index 2a5af32ecc2..ca7d07220b2 100644 --- a/apps/web/src/app/admin-console/organizations/manage/group-add-edit.component.ts +++ b/apps/web/src/app/admin-console/organizations/manage/group-add-edit.component.ts @@ -28,7 +28,6 @@ import { } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ErrorResponse } from "@bitwarden/common/models/response/error.response"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; @@ -58,6 +57,8 @@ import { AddEditGroupDetail } from "./../core/views/add-edit-group-detail"; /** * Indices for the available tabs in the dialog */ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum GroupAddEditTabType { Info = 0, Members = 1, @@ -82,6 +83,8 @@ export interface GroupAddEditDialogParams { initialTab?: GroupAddEditTabType; } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum GroupAddEditDialogResultType { Saved = "saved", Canceled = "canceled", @@ -106,6 +109,7 @@ export const openGroupAddEditDialog = ( @Component({ selector: "app-group-add-edit", templateUrl: "group-add-edit.component.html", + standalone: false, }) export class GroupAddEditComponent implements OnInit, OnDestroy { private organization$ = this.accountService.activeAccount$.pipe( @@ -142,6 +146,10 @@ export class GroupAddEditComponent implements OnInit, OnDestroy { return this.params.organizationId; } + protected get isExternalIdVisible(): boolean { + return !!this.groupForm.get("externalId")?.value; + } + protected get editMode(): boolean { return this.groupId != null; } @@ -222,10 +230,6 @@ export class GroupAddEditComponent implements OnInit, OnDestroy { this.groupDetails$, ]).pipe(map(([allowAdminAccess, groupDetails]) => !allowAdminAccess && groupDetails != null)); - protected isExternalIdVisible$ = this.configService - .getFeatureFlag$(FeatureFlag.SsoExternalIdVisibility) - .pipe(map((isEnabled) => !isEnabled || !!this.groupForm.get("externalId")?.value)); - constructor( @Inject(DIALOG_DATA) private params: GroupAddEditDialogParams, private dialogRef: DialogRef, diff --git a/apps/web/src/app/admin-console/organizations/manage/groups.component.html b/apps/web/src/app/admin-console/organizations/manage/groups.component.html index 82ad2c36b8c..caae23f500d 100644 --- a/apps/web/src/app/admin-console/organizations/manage/groups.component.html +++ b/apps/web/src/app/admin-console/organizations/manage/groups.component.html @@ -93,7 +93,8 @@ {{ "members" | i18n }} - - - - diff --git a/apps/web/src/app/admin-console/organizations/manage/organization-trust.component.ts b/apps/web/src/app/admin-console/organizations/manage/organization-trust.component.ts deleted file mode 100644 index 3f013c9fc74..00000000000 --- a/apps/web/src/app/admin-console/organizations/manage/organization-trust.component.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { DialogRef, DIALOG_DATA } from "@angular/cdk/dialog"; -import { Component, OnInit, Inject } from "@angular/core"; -import { FormBuilder } from "@angular/forms"; - -import { OrganizationManagementPreferencesService } from "@bitwarden/common/admin-console/abstractions/organization-management-preferences/organization-management-preferences.service"; -import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; -import { DialogService } from "@bitwarden/components"; -import { KeyService } from "@bitwarden/key-management"; - -type OrganizationTrustDialogData = { - /** display name of the organization */ - name: string; - /** identifies the organization */ - orgId: string; - /** org public key */ - publicKey: Uint8Array; -}; -@Component({ - selector: "organization-trust", - templateUrl: "organization-trust.component.html", -}) -export class OrganizationTrustComponent implements OnInit { - loading = true; - fingerprint: string = ""; - confirmForm = this.formBuilder.group({}); - - constructor( - @Inject(DIALOG_DATA) protected params: OrganizationTrustDialogData, - private formBuilder: FormBuilder, - private keyService: KeyService, - protected organizationManagementPreferencesService: OrganizationManagementPreferencesService, - private logService: LogService, - private dialogRef: DialogRef, - ) {} - - async ngOnInit() { - try { - const fingerprint = await this.keyService.getFingerprint( - this.params.orgId, - this.params.publicKey, - ); - if (fingerprint != null) { - this.fingerprint = fingerprint.join("-"); - } - } catch (e) { - this.logService.error(e); - } - this.loading = false; - } - - submit = async () => { - if (this.loading) { - return; - } - - this.dialogRef.close(true); - }; - - /** - * Strongly typed helper to open a OrganizationTrustComponent - * @param dialogService Instance of the dialog service that will be used to open the dialog - * @param data The data to pass to the dialog - */ - static open(dialogService: DialogService, data: OrganizationTrustDialogData) { - return dialogService.open(OrganizationTrustComponent, { - data, - }); - } -} diff --git a/apps/web/src/app/admin-console/organizations/manage/user-confirm.component.ts b/apps/web/src/app/admin-console/organizations/manage/user-confirm.component.ts index b5068ba55a6..03b77cfaa71 100644 --- a/apps/web/src/app/admin-console/organizations/manage/user-confirm.component.ts +++ b/apps/web/src/app/admin-console/organizations/manage/user-confirm.component.ts @@ -18,6 +18,7 @@ export type UserConfirmDialogData = { @Component({ selector: "app-user-confirm", templateUrl: "user-confirm.component.html", + standalone: false, }) export class UserConfirmComponent implements OnInit { name: string; diff --git a/apps/web/src/app/admin-console/organizations/manage/verify-recover-delete-org.component.ts b/apps/web/src/app/admin-console/organizations/manage/verify-recover-delete-org.component.ts index 6dcdff00160..f88eb82e529 100644 --- a/apps/web/src/app/admin-console/organizations/manage/verify-recover-delete-org.component.ts +++ b/apps/web/src/app/admin-console/organizations/manage/verify-recover-delete-org.component.ts @@ -14,7 +14,6 @@ import { SharedModule } from "../../../shared/shared.module"; @Component({ templateUrl: "verify-recover-delete-org.component.html", - standalone: true, imports: [SharedModule], }) export class VerifyRecoverDeleteOrgComponent implements OnInit { diff --git a/apps/web/src/app/admin-console/organizations/members/components/bulk/bulk-confirm-dialog.component.ts b/apps/web/src/app/admin-console/organizations/members/components/bulk/bulk-confirm-dialog.component.ts index c19984f980d..4ec50799ae0 100644 --- a/apps/web/src/app/admin-console/organizations/members/components/bulk/bulk-confirm-dialog.component.ts +++ b/apps/web/src/app/admin-console/organizations/members/components/bulk/bulk-confirm-dialog.component.ts @@ -33,6 +33,7 @@ type BulkConfirmDialogParams = { @Component({ templateUrl: "bulk-confirm-dialog.component.html", + standalone: false, }) export class BulkConfirmDialogComponent extends BaseBulkConfirmComponent { organizationId: string; diff --git a/apps/web/src/app/admin-console/organizations/members/components/bulk/bulk-delete-dialog.component.ts b/apps/web/src/app/admin-console/organizations/members/components/bulk/bulk-delete-dialog.component.ts index 27caea3ebd3..8fb60e85b08 100644 --- a/apps/web/src/app/admin-console/organizations/members/components/bulk/bulk-delete-dialog.component.ts +++ b/apps/web/src/app/admin-console/organizations/members/components/bulk/bulk-delete-dialog.component.ts @@ -1,12 +1,9 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore import { Component, Inject } from "@angular/core"; -import { firstValueFrom } from "rxjs"; import { OrganizationUserApiService } from "@bitwarden/admin-console/common"; import { OrganizationUserStatusType } from "@bitwarden/common/admin-console/enums"; -import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; -import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { DIALOG_DATA, DialogConfig, DialogService } from "@bitwarden/components"; @@ -21,6 +18,7 @@ type BulkDeleteDialogParams = { @Component({ templateUrl: "bulk-delete-dialog.component.html", + standalone: false, }) export class BulkDeleteDialogComponent { organizationId: string; @@ -35,7 +33,6 @@ export class BulkDeleteDialogComponent { @Inject(DIALOG_DATA) protected dialogParams: BulkDeleteDialogParams, protected i18nService: I18nService, private organizationUserApiService: OrganizationUserApiService, - private configService: ConfigService, private deleteManagedMemberWarningService: DeleteManagedMemberWarningService, ) { this.organizationId = dialogParams.organizationId; @@ -43,11 +40,7 @@ export class BulkDeleteDialogComponent { } async submit() { - if ( - await firstValueFrom(this.configService.getFeatureFlag$(FeatureFlag.AccountDeprovisioning)) - ) { - await this.deleteManagedMemberWarningService.acknowledgeWarning(this.organizationId); - } + await this.deleteManagedMemberWarningService.acknowledgeWarning(this.organizationId); try { this.loading = true; diff --git a/apps/web/src/app/admin-console/organizations/members/components/bulk/bulk-enable-sm-dialog.component.ts b/apps/web/src/app/admin-console/organizations/members/components/bulk/bulk-enable-sm-dialog.component.ts index e01809789f3..9132625c587 100644 --- a/apps/web/src/app/admin-console/organizations/members/components/bulk/bulk-enable-sm-dialog.component.ts +++ b/apps/web/src/app/admin-console/organizations/members/components/bulk/bulk-enable-sm-dialog.component.ts @@ -22,6 +22,7 @@ export type BulkEnableSecretsManagerDialogData = { @Component({ templateUrl: `bulk-enable-sm-dialog.component.html`, + standalone: false, }) export class BulkEnableSecretsManagerDialogComponent implements OnInit { protected dataSource = new TableDataSource(); diff --git a/apps/web/src/app/admin-console/organizations/members/components/bulk/bulk-remove-dialog.component.ts b/apps/web/src/app/admin-console/organizations/members/components/bulk/bulk-remove-dialog.component.ts index 00711e355cb..5bbc6f093f0 100644 --- a/apps/web/src/app/admin-console/organizations/members/components/bulk/bulk-remove-dialog.component.ts +++ b/apps/web/src/app/admin-console/organizations/members/components/bulk/bulk-remove-dialog.component.ts @@ -21,6 +21,7 @@ type BulkRemoveDialogParams = { @Component({ templateUrl: "bulk-remove-dialog.component.html", + standalone: false, }) export class BulkRemoveDialogComponent extends BaseBulkRemoveComponent { organizationId: string; diff --git a/apps/web/src/app/admin-console/organizations/members/components/bulk/bulk-restore-revoke.component.html b/apps/web/src/app/admin-console/organizations/members/components/bulk/bulk-restore-revoke.component.html index 4925c210039..1b711b366d6 100644 --- a/apps/web/src/app/admin-console/organizations/members/components/bulk/bulk-restore-revoke.component.html +++ b/apps/web/src/app/admin-console/organizations/members/components/bulk/bulk-restore-revoke.component.html @@ -1,12 +1,6 @@ - + - {{ bulkMemberTitle }} - - {{ bulkTitle }} - + {{ bulkTitle }}
@@ -20,7 +14,7 @@ {{ "nonCompliantMembersError" | i18n }} @@ -50,7 +44,7 @@ - {{ (accountDeprovisioning.enabled ? "member" : "user") | i18n }} + {{ "member" | i18n }} {{ "details" | i18n }} @@ -82,7 +76,7 @@ - {{ (accountDeprovisioning.enabled ? "member" : "user") | i18n }} + {{ "member" | i18n }} {{ "status" | i18n }} @@ -113,7 +107,7 @@ [bitAction]="submit" buttonType="primary" > - {{ accountDeprovisioning.enabled ? bulkMemberTitle : bulkTitle }} + {{ bulkTitle }} @@ -16,6 +23,7 @@ [selected]="status" (selectedChange)="statusToggle.next($event)" [attr.aria-label]="'memberStatusFilter' | i18n" + *ngIf="showUserManagementControls$ | async" > {{ "all" | i18n }} @@ -71,7 +79,7 @@ - + @@ -174,74 +183,143 @@ alignContent="middle" [ngClass]="rowHeightClass" > - + - -
- -
-
- - - {{ "invited" | i18n }} - - - {{ "needsConfirmation" | i18n }} - - - {{ "revoked" | i18n }} - -
-
- {{ u.email }} + + +
+ +
+
+ + + {{ "invited" | i18n }} + + + {{ "needsConfirmation" | i18n }} + + + {{ "revoked" | i18n }} + +
+
+ {{ u.email }} +
-
- + + + + +
+ +
+
+ {{ u.name ?? u.email }} + + {{ "invited" | i18n }} + + + {{ "needsConfirmation" | i18n }} + + + {{ "revoked" | i18n }} + +
+
+ {{ u.email }} +
+
+
+ +
- - - + + + + + + + + + + - - {{ u.type | userType }} - + + + {{ u.type | userType }} + + + + + {{ u.type | userType }} + + @@ -271,53 +349,58 @@ > - - - - - - - - + + + + + + + + + + + + - - - - + + + + + + + @@ -373,4 +459,3 @@ - diff --git a/apps/web/src/app/admin-console/organizations/members/members.component.ts b/apps/web/src/app/admin-console/organizations/members/members.component.ts index 3ce78354046..4f453762b5d 100644 --- a/apps/web/src/app/admin-console/organizations/members/members.component.ts +++ b/apps/web/src/app/admin-console/organizations/members/members.component.ts @@ -1,6 +1,6 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { Component, OnInit, ViewChild, ViewContainerRef } from "@angular/core"; +import { Component } from "@angular/core"; import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; import { ActivatedRoute, Router } from "@angular/router"; import { @@ -90,11 +90,9 @@ class MembersTableDataSource extends PeopleTableDataSource @Component({ templateUrl: "members.component.html", + standalone: false, }) -export class MembersComponent extends BaseMembersComponent implements OnInit { - @ViewChild("resetPasswordTemplate", { read: ViewContainerRef, static: true }) - resetPasswordModalRef: ViewContainerRef; - +export class MembersComponent extends BaseMembersComponent { userType = OrganizationUserType; userStatusType = OrganizationUserStatusType; memberTab = MemberDialogTab; @@ -104,16 +102,18 @@ export class MembersComponent extends BaseMembersComponent status: OrganizationUserStatusType = null; orgResetPasswordPolicyEnabled = false; orgIsOnSecretsManagerStandalone = false; - accountDeprovisioningEnabled = false; protected canUseSecretsManager$: Observable; + protected showUserManagementControls$: Observable; // Fixed sizes used for cdkVirtualScroll protected rowHeight = 69; protected rowHeightClass = `tw-h-[69px]`; + private organizationUsersCount = 0; + get occupiedSeatCount(): number { - return this.dataSource.activeUserCount; + return this.organizationUsersCount; } constructor( @@ -139,8 +139,8 @@ export class MembersComponent extends BaseMembersComponent private groupService: GroupApiService, private collectionService: CollectionService, private billingApiService: BillingApiServiceAbstraction, - private configService: ConfigService, protected deleteManagedMemberWarningService: DeleteManagedMemberWarningService, + private configService: ConfigService, ) { super( apiService, @@ -220,6 +220,7 @@ export class MembersComponent extends BaseMembersComponent ); this.orgIsOnSecretsManagerStandalone = billingMetadata.isOnSecretsManagerStandalone; + this.organizationUsersCount = billingMetadata.organizationOccupiedSeats; await this.load(); @@ -235,11 +236,16 @@ export class MembersComponent extends BaseMembersComponent takeUntilDestroyed(), ) .subscribe(); - } - async ngOnInit() { - this.accountDeprovisioningEnabled = await this.configService.getFeatureFlag( - FeatureFlag.AccountDeprovisioning, + // Setup feature flag-dependent observables + const separateCustomRolePermissionsEnabled$ = this.configService.getFeatureFlag$( + FeatureFlag.SeparateCustomRolePermissions, + ); + this.showUserManagementControls$ = separateCustomRolePermissionsEnabled$.pipe( + map( + (separateCustomRolePermissionsEnabled) => + !separateCustomRolePermissionsEnabled || this.organization.canManageUsers, + ), ); } @@ -591,20 +597,18 @@ export class MembersComponent extends BaseMembersComponent } async bulkDelete() { - if (this.accountDeprovisioningEnabled) { - const warningAcknowledged = await firstValueFrom( - this.deleteManagedMemberWarningService.warningAcknowledged(this.organization.id), - ); + const warningAcknowledged = await firstValueFrom( + this.deleteManagedMemberWarningService.warningAcknowledged(this.organization.id), + ); - if ( - !warningAcknowledged && - this.organization.canManageUsers && - this.organization.productTierType === ProductTierType.Enterprise - ) { - const acknowledged = await this.deleteManagedMemberWarningService.showWarning(); - if (!acknowledged) { - return; - } + if ( + !warningAcknowledged && + this.organization.canManageUsers && + this.organization.productTierType === ProductTierType.Enterprise + ) { + const acknowledged = await this.deleteManagedMemberWarningService.showWarning(); + if (!acknowledged) { + return; } } @@ -794,20 +798,18 @@ export class MembersComponent extends BaseMembersComponent } async deleteUser(user: OrganizationUserView) { - if (this.accountDeprovisioningEnabled) { - const warningAcknowledged = await firstValueFrom( - this.deleteManagedMemberWarningService.warningAcknowledged(this.organization.id), - ); + const warningAcknowledged = await firstValueFrom( + this.deleteManagedMemberWarningService.warningAcknowledged(this.organization.id), + ); - if ( - !warningAcknowledged && - this.organization.canManageUsers && - this.organization.productTierType === ProductTierType.Enterprise - ) { - const acknowledged = await this.deleteManagedMemberWarningService.showWarning(); - if (!acknowledged) { - return false; - } + if ( + !warningAcknowledged && + this.organization.canManageUsers && + this.organization.productTierType === ProductTierType.Enterprise + ) { + const acknowledged = await this.deleteManagedMemberWarningService.showWarning(); + if (!acknowledged) { + return false; } } @@ -829,9 +831,7 @@ export class MembersComponent extends BaseMembersComponent return false; } - if (this.accountDeprovisioningEnabled) { - await this.deleteManagedMemberWarningService.acknowledgeWarning(this.organization.id); - } + await this.deleteManagedMemberWarningService.acknowledgeWarning(this.organization.id); this.actionPromise = this.organizationUserApiService.deleteOrganizationUser( this.organization.id, @@ -864,56 +864,23 @@ export class MembersComponent extends BaseMembersComponent }); } - get showBulkConfirmUsers(): boolean { - if (!this.accountDeprovisioningEnabled) { - return super.showBulkConfirmUsers; - } - - return this.dataSource - .getCheckedUsers() - .every((member) => member.status == this.userStatusType.Accepted); - } - - get showBulkReinviteUsers(): boolean { - if (!this.accountDeprovisioningEnabled) { - return super.showBulkReinviteUsers; - } - - return this.dataSource - .getCheckedUsers() - .every((member) => member.status == this.userStatusType.Invited); - } - get showBulkRestoreUsers(): boolean { - return ( - !this.accountDeprovisioningEnabled || - this.dataSource - .getCheckedUsers() - .every((member) => member.status == this.userStatusType.Revoked) - ); + return this.dataSource + .getCheckedUsers() + .every((member) => member.status == this.userStatusType.Revoked); } get showBulkRevokeUsers(): boolean { - return ( - !this.accountDeprovisioningEnabled || - this.dataSource - .getCheckedUsers() - .every((member) => member.status != this.userStatusType.Revoked) - ); + return this.dataSource + .getCheckedUsers() + .every((member) => member.status != this.userStatusType.Revoked); } get showBulkRemoveUsers(): boolean { - return ( - !this.accountDeprovisioningEnabled || - this.dataSource.getCheckedUsers().every((member) => !member.managedByOrganization) - ); + return this.dataSource.getCheckedUsers().every((member) => !member.managedByOrganization); } get showBulkDeleteUsers(): boolean { - if (!this.accountDeprovisioningEnabled) { - return false; - } - const validStatuses = [ this.userStatusType.Accepted, this.userStatusType.Confirmed, diff --git a/apps/web/src/app/admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service.ts b/apps/web/src/app/admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service.ts index 78d2d8fd165..ecf4d26eb52 100644 --- a/apps/web/src/app/admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service.ts +++ b/apps/web/src/app/admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service.ts @@ -112,7 +112,7 @@ export class OrganizationUserResetPasswordService if (orgSymKey == null) { throw new Error("No org key found"); } - const decPrivateKey = await this.encryptService.decryptToBytes( + const decPrivateKey = await this.encryptService.unwrapDecapsulationKey( new EncString(response.encryptedPrivateKey), orgSymKey, ); diff --git a/apps/web/src/app/admin-console/organizations/organization-routing.module.ts b/apps/web/src/app/admin-console/organizations/organization-routing.module.ts index e5c68b73546..4d8971f74fd 100644 --- a/apps/web/src/app/admin-console/organizations/organization-routing.module.ts +++ b/apps/web/src/app/admin-console/organizations/organization-routing.module.ts @@ -14,7 +14,7 @@ import { } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; -import { deepLinkGuard } from "../../auth/guards/deep-link.guard"; +import { deepLinkGuard } from "../../auth/guards/deep-link/deep-link.guard"; import { VaultModule } from "./collections/vault.module"; import { isEnterpriseOrgGuard } from "./guards/is-enterprise-org.guard"; diff --git a/apps/web/src/app/admin-console/organizations/policies/disable-send.component.ts b/apps/web/src/app/admin-console/organizations/policies/disable-send.component.ts index 2acf175e3da..b323ac00d34 100644 --- a/apps/web/src/app/admin-console/organizations/policies/disable-send.component.ts +++ b/apps/web/src/app/admin-console/organizations/policies/disable-send.component.ts @@ -14,5 +14,6 @@ export class DisableSendPolicy extends BasePolicy { @Component({ selector: "policy-disable-send", templateUrl: "disable-send.component.html", + standalone: false, }) export class DisableSendPolicyComponent extends BasePolicyComponent {} diff --git a/apps/web/src/app/admin-console/organizations/policies/master-password.component.ts b/apps/web/src/app/admin-console/organizations/policies/master-password.component.ts index 328989df66b..54cf1be88fc 100644 --- a/apps/web/src/app/admin-console/organizations/policies/master-password.component.ts +++ b/apps/web/src/app/admin-console/organizations/policies/master-password.component.ts @@ -28,6 +28,7 @@ export class MasterPasswordPolicy extends BasePolicy { @Component({ selector: "policy-master-password", templateUrl: "master-password.component.html", + standalone: false, }) export class MasterPasswordPolicyComponent extends BasePolicyComponent implements OnInit { MinPasswordLength = Utils.minimumPasswordLength; diff --git a/apps/web/src/app/admin-console/organizations/policies/password-generator.component.ts b/apps/web/src/app/admin-console/organizations/policies/password-generator.component.ts index 4439f974e55..26f87f333eb 100644 --- a/apps/web/src/app/admin-console/organizations/policies/password-generator.component.ts +++ b/apps/web/src/app/admin-console/organizations/policies/password-generator.component.ts @@ -7,7 +7,7 @@ import { BehaviorSubject, map } from "rxjs"; import { PolicyType } from "@bitwarden/common/admin-console/enums"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { Generators } from "@bitwarden/generator-core"; +import { BuiltIn, Profile } from "@bitwarden/generator-core"; import { BasePolicy, BasePolicyComponent } from "./base-policy.component"; @@ -21,18 +21,27 @@ export class PasswordGeneratorPolicy extends BasePolicy { @Component({ selector: "policy-password-generator", templateUrl: "password-generator.component.html", + standalone: false, }) export class PasswordGeneratorPolicyComponent extends BasePolicyComponent { // these properties forward the application default settings to the UI // for HTML attribute bindings - protected readonly minLengthMin = Generators.password.settings.constraints.length.min; - protected readonly minLengthMax = Generators.password.settings.constraints.length.max; - protected readonly minNumbersMin = Generators.password.settings.constraints.minNumber.min; - protected readonly minNumbersMax = Generators.password.settings.constraints.minNumber.max; - protected readonly minSpecialMin = Generators.password.settings.constraints.minSpecial.min; - protected readonly minSpecialMax = Generators.password.settings.constraints.minSpecial.max; - protected readonly minNumberWordsMin = Generators.passphrase.settings.constraints.numWords.min; - protected readonly minNumberWordsMax = Generators.passphrase.settings.constraints.numWords.max; + protected readonly minLengthMin = + BuiltIn.password.profiles[Profile.account].constraints.default.length.min; + protected readonly minLengthMax = + BuiltIn.password.profiles[Profile.account].constraints.default.length.max; + protected readonly minNumbersMin = + BuiltIn.password.profiles[Profile.account].constraints.default.minNumber.min; + protected readonly minNumbersMax = + BuiltIn.password.profiles[Profile.account].constraints.default.minNumber.max; + protected readonly minSpecialMin = + BuiltIn.password.profiles[Profile.account].constraints.default.minSpecial.min; + protected readonly minSpecialMax = + BuiltIn.password.profiles[Profile.account].constraints.default.minSpecial.max; + protected readonly minNumberWordsMin = + BuiltIn.passphrase.profiles[Profile.account].constraints.default.numWords.min; + protected readonly minNumberWordsMax = + BuiltIn.passphrase.profiles[Profile.account].constraints.default.numWords.max; data = this.formBuilder.group({ overridePasswordType: [null], diff --git a/apps/web/src/app/admin-console/organizations/policies/personal-ownership.component.ts b/apps/web/src/app/admin-console/organizations/policies/personal-ownership.component.ts index 36c79a61fe4..ef92ee90581 100644 --- a/apps/web/src/app/admin-console/organizations/policies/personal-ownership.component.ts +++ b/apps/web/src/app/admin-console/organizations/policies/personal-ownership.component.ts @@ -14,5 +14,6 @@ export class PersonalOwnershipPolicy extends BasePolicy { @Component({ selector: "policy-personal-ownership", templateUrl: "personal-ownership.component.html", + standalone: false, }) export class PersonalOwnershipPolicyComponent extends BasePolicyComponent {} diff --git a/apps/web/src/app/admin-console/organizations/policies/policies.component.html b/apps/web/src/app/admin-console/organizations/policies/policies.component.html index e40b9d80e9e..016d631019e 100644 --- a/apps/web/src/app/admin-console/organizations/policies/policies.component.html +++ b/apps/web/src/app/admin-console/organizations/policies/policies.component.html @@ -35,5 +35,4 @@ - diff --git a/apps/web/src/app/admin-console/organizations/policies/policies.component.ts b/apps/web/src/app/admin-console/organizations/policies/policies.component.ts index 2b86d76d9b1..73f0d99b4f9 100644 --- a/apps/web/src/app/admin-console/organizations/policies/policies.component.ts +++ b/apps/web/src/app/admin-console/organizations/policies/policies.component.ts @@ -1,6 +1,6 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { Component, OnInit, ViewChild, ViewContainerRef } from "@angular/core"; +import { Component, OnInit } from "@angular/core"; import { ActivatedRoute } from "@angular/router"; import { firstValueFrom, lastValueFrom, map, Observable, switchMap } from "rxjs"; import { first } from "rxjs/operators"; @@ -31,11 +31,9 @@ import { PolicyEditComponent, PolicyEditDialogResult } from "./policy-edit.compo @Component({ selector: "app-org-policies", templateUrl: "policies.component.html", + standalone: false, }) export class PoliciesComponent implements OnInit { - @ViewChild("editTemplate", { read: ViewContainerRef, static: true }) - editModalRef: ViewContainerRef; - loading = true; organizationId: string; policies: BasePolicy[]; diff --git a/apps/web/src/app/admin-console/organizations/policies/policy-edit.component.ts b/apps/web/src/app/admin-console/organizations/policies/policy-edit.component.ts index 49f4d15a100..d3d03d2aaae 100644 --- a/apps/web/src/app/admin-console/organizations/policies/policy-edit.component.ts +++ b/apps/web/src/app/admin-console/organizations/policies/policy-edit.component.ts @@ -41,6 +41,8 @@ export type PolicyEditDialogData = { organizationId: string; }; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum PolicyEditDialogResult { Saved = "saved", UpgradePlan = "upgrade-plan", @@ -48,6 +50,7 @@ export enum PolicyEditDialogResult { @Component({ selector: "app-policy-edit", templateUrl: "policy-edit.component.html", + standalone: false, }) export class PolicyEditComponent implements AfterViewInit { @ViewChild("policyForm", { read: ViewContainerRef, static: true }) diff --git a/apps/web/src/app/admin-console/organizations/policies/remove-unlock-with-pin.component.ts b/apps/web/src/app/admin-console/organizations/policies/remove-unlock-with-pin.component.ts index b737c803b5f..0d0f42b603e 100644 --- a/apps/web/src/app/admin-console/organizations/policies/remove-unlock-with-pin.component.ts +++ b/apps/web/src/app/admin-console/organizations/policies/remove-unlock-with-pin.component.ts @@ -14,5 +14,6 @@ export class RemoveUnlockWithPinPolicy extends BasePolicy { @Component({ selector: "remove-unlock-with-pin", templateUrl: "remove-unlock-with-pin.component.html", + standalone: false, }) export class RemoveUnlockWithPinPolicyComponent extends BasePolicyComponent {} diff --git a/apps/web/src/app/admin-console/organizations/policies/require-sso.component.ts b/apps/web/src/app/admin-console/organizations/policies/require-sso.component.ts index ea85168f986..21de143dea6 100644 --- a/apps/web/src/app/admin-console/organizations/policies/require-sso.component.ts +++ b/apps/web/src/app/admin-console/organizations/policies/require-sso.component.ts @@ -19,5 +19,6 @@ export class RequireSsoPolicy extends BasePolicy { @Component({ selector: "policy-require-sso", templateUrl: "require-sso.component.html", + standalone: false, }) export class RequireSsoPolicyComponent extends BasePolicyComponent {} diff --git a/apps/web/src/app/admin-console/organizations/policies/reset-password.component.ts b/apps/web/src/app/admin-console/organizations/policies/reset-password.component.ts index 80e4e5254ff..62fc42f6a06 100644 --- a/apps/web/src/app/admin-console/organizations/policies/reset-password.component.ts +++ b/apps/web/src/app/admin-console/organizations/policies/reset-password.component.ts @@ -27,6 +27,7 @@ export class ResetPasswordPolicy extends BasePolicy { @Component({ selector: "policy-reset-password", templateUrl: "reset-password.component.html", + standalone: false, }) export class ResetPasswordPolicyComponent extends BasePolicyComponent implements OnInit { data = this.formBuilder.group({ diff --git a/apps/web/src/app/admin-console/organizations/policies/send-options.component.ts b/apps/web/src/app/admin-console/organizations/policies/send-options.component.ts index af6d1f38694..9a0a8871296 100644 --- a/apps/web/src/app/admin-console/organizations/policies/send-options.component.ts +++ b/apps/web/src/app/admin-console/organizations/policies/send-options.component.ts @@ -15,6 +15,7 @@ export class SendOptionsPolicy extends BasePolicy { @Component({ selector: "policy-send-options", templateUrl: "send-options.component.html", + standalone: false, }) export class SendOptionsPolicyComponent extends BasePolicyComponent { data = this.formBuilder.group({ diff --git a/apps/web/src/app/admin-console/organizations/policies/single-org.component.html b/apps/web/src/app/admin-console/organizations/policies/single-org.component.html index db48c835750..082970a4f05 100644 --- a/apps/web/src/app/admin-console/organizations/policies/single-org.component.html +++ b/apps/web/src/app/admin-console/organizations/policies/single-org.component.html @@ -1,11 +1,6 @@ - + {{ "singleOrgPolicyMemberWarning" | i18n }} - - - {{ "singleOrgPolicyWarning" | i18n }} - - diff --git a/apps/web/src/app/admin-console/organizations/policies/single-org.component.ts b/apps/web/src/app/admin-console/organizations/policies/single-org.component.ts index b3a537f08da..ad32b4218bc 100644 --- a/apps/web/src/app/admin-console/organizations/policies/single-org.component.ts +++ b/apps/web/src/app/admin-console/organizations/policies/single-org.component.ts @@ -1,15 +1,12 @@ import { Component, OnInit } from "@angular/core"; -import { firstValueFrom, Observable } from "rxjs"; import { PolicyType } from "@bitwarden/common/admin-console/enums"; -import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; -import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { BasePolicy, BasePolicyComponent } from "./base-policy.component"; export class SingleOrgPolicy extends BasePolicy { name = "singleOrg"; - description = "singleOrgDesc"; + description = "singleOrgPolicyDesc"; type = PolicyType.SingleOrg; component = SingleOrgPolicyComponent; } @@ -17,24 +14,12 @@ export class SingleOrgPolicy extends BasePolicy { @Component({ selector: "policy-single-org", templateUrl: "single-org.component.html", + standalone: false, }) export class SingleOrgPolicyComponent extends BasePolicyComponent implements OnInit { - constructor(private configService: ConfigService) { - super(); - } - - protected accountDeprovisioningEnabled$: Observable = this.configService.getFeatureFlag$( - FeatureFlag.AccountDeprovisioning, - ); - async ngOnInit() { super.ngOnInit(); - const isAccountDeprovisioningEnabled = await firstValueFrom(this.accountDeprovisioningEnabled$); - this.policy.description = isAccountDeprovisioningEnabled - ? "singleOrgPolicyDesc" - : "singleOrgDesc"; - if (!this.policyResponse.canToggleState) { this.enabled.disable(); } diff --git a/apps/web/src/app/admin-console/organizations/policies/two-factor-authentication.component.ts b/apps/web/src/app/admin-console/organizations/policies/two-factor-authentication.component.ts index 51151808872..691e12c72f6 100644 --- a/apps/web/src/app/admin-console/organizations/policies/two-factor-authentication.component.ts +++ b/apps/web/src/app/admin-console/organizations/policies/two-factor-authentication.component.ts @@ -14,5 +14,6 @@ export class TwoFactorAuthenticationPolicy extends BasePolicy { @Component({ selector: "policy-two-factor-authentication", templateUrl: "two-factor-authentication.component.html", + standalone: false, }) export class TwoFactorAuthenticationPolicyComponent extends BasePolicyComponent {} diff --git a/apps/web/src/app/admin-console/organizations/reporting/organization-reporting-routing.module.ts b/apps/web/src/app/admin-console/organizations/reporting/organization-reporting-routing.module.ts index 635053dd1e2..4c825b26bb2 100644 --- a/apps/web/src/app/admin-console/organizations/reporting/organization-reporting-routing.module.ts +++ b/apps/web/src/app/admin-console/organizations/reporting/organization-reporting-routing.module.ts @@ -9,12 +9,16 @@ import { Organization } from "@bitwarden/common/admin-console/models/domain/orga import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; -import { ExposedPasswordsReportComponent } from "../../../tools/reports/pages/organizations/exposed-passwords-report.component"; -import { InactiveTwoFactorReportComponent } from "../../../tools/reports/pages/organizations/inactive-two-factor-report.component"; -import { ReusedPasswordsReportComponent } from "../../../tools/reports/pages/organizations/reused-passwords-report.component"; -import { UnsecuredWebsitesReportComponent } from "../../../tools/reports/pages/organizations/unsecured-websites-report.component"; -import { WeakPasswordsReportComponent } from "../../../tools/reports/pages/organizations/weak-passwords-report.component"; -/* eslint no-restricted-imports: "error" */ +// eslint-disable-next-line no-restricted-imports +import { ExposedPasswordsReportComponent } from "../../../dirt/reports/pages/organizations/exposed-passwords-report.component"; +// eslint-disable-next-line no-restricted-imports +import { InactiveTwoFactorReportComponent } from "../../../dirt/reports/pages/organizations/inactive-two-factor-report.component"; +// eslint-disable-next-line no-restricted-imports +import { ReusedPasswordsReportComponent } from "../../../dirt/reports/pages/organizations/reused-passwords-report.component"; +// eslint-disable-next-line no-restricted-imports +import { UnsecuredWebsitesReportComponent } from "../../../dirt/reports/pages/organizations/unsecured-websites-report.component"; +// eslint-disable-next-line no-restricted-imports +import { WeakPasswordsReportComponent } from "../../../dirt/reports/pages/organizations/weak-passwords-report.component"; import { isPaidOrgGuard } from "../guards/is-paid-org.guard"; import { organizationPermissionsGuard } from "../guards/org-permissions.guard"; import { organizationRedirectGuard } from "../guards/org-redirect.guard"; diff --git a/apps/web/src/app/admin-console/organizations/reporting/organization-reporting.module.ts b/apps/web/src/app/admin-console/organizations/reporting/organization-reporting.module.ts index d17bb0c5995..22c3edcf240 100644 --- a/apps/web/src/app/admin-console/organizations/reporting/organization-reporting.module.ts +++ b/apps/web/src/app/admin-console/organizations/reporting/organization-reporting.module.ts @@ -1,8 +1,8 @@ import { NgModule } from "@angular/core"; +import { ReportsSharedModule } from "../../../dirt/reports"; import { LooseComponentsModule } from "../../../shared"; import { SharedModule } from "../../../shared/shared.module"; -import { ReportsSharedModule } from "../../../tools/reports"; import { OrganizationReportingRoutingModule } from "./organization-reporting-routing.module"; import { ReportsHomeComponent } from "./reports-home.component"; diff --git a/apps/web/src/app/admin-console/organizations/reporting/reports-home.component.ts b/apps/web/src/app/admin-console/organizations/reporting/reports-home.component.ts index 6090396293f..52cb24c90d1 100644 --- a/apps/web/src/app/admin-console/organizations/reporting/reports-home.component.ts +++ b/apps/web/src/app/admin-console/organizations/reporting/reports-home.component.ts @@ -12,11 +12,12 @@ import { AccountService } from "@bitwarden/common/auth/abstractions/account.serv import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { ProductTierType } from "@bitwarden/common/billing/enums"; -import { ReportVariant, reports, ReportType, ReportEntry } from "../../../tools/reports"; +import { ReportVariant, reports, ReportType, ReportEntry } from "../../../dirt/reports"; @Component({ selector: "app-org-reports-home", templateUrl: "reports-home.component.html", + standalone: false, }) export class ReportsHomeComponent implements OnInit { reports$: Observable; diff --git a/apps/web/src/app/admin-console/organizations/settings/account.component.html b/apps/web/src/app/admin-console/organizations/settings/account.component.html index 8ae94b08f57..e6064779ece 100644 --- a/apps/web/src/app/admin-console/organizations/settings/account.component.html +++ b/apps/web/src/app/admin-console/organizations/settings/account.component.html @@ -93,7 +93,4 @@ {{ "purgeVault" | i18n }} - - - diff --git a/apps/web/src/app/admin-console/organizations/settings/account.component.ts b/apps/web/src/app/admin-console/organizations/settings/account.component.ts index 57892442c16..b376c48b39a 100644 --- a/apps/web/src/app/admin-console/organizations/settings/account.component.ts +++ b/apps/web/src/app/admin-console/organizations/settings/account.component.ts @@ -1,6 +1,6 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { Component, OnDestroy, OnInit, ViewChild, ViewContainerRef } from "@angular/core"; +import { Component, OnDestroy, OnInit } from "@angular/core"; import { FormBuilder, Validators } from "@angular/forms"; import { ActivatedRoute, Router } from "@angular/router"; import { @@ -41,13 +41,9 @@ import { DeleteOrganizationDialogResult, openDeleteOrganizationDialog } from "./ @Component({ selector: "app-org-account", templateUrl: "account.component.html", + standalone: false, }) export class AccountComponent implements OnInit, OnDestroy { - @ViewChild("apiKeyTemplate", { read: ViewContainerRef, static: true }) - apiKeyModalRef: ViewContainerRef; - @ViewChild("rotateApiKeyTemplate", { read: ViewContainerRef, static: true }) - rotateApiKeyModalRef: ViewContainerRef; - selfHosted = false; canEditSubscription = true; loading = true; diff --git a/apps/web/src/app/admin-console/organizations/settings/components/delete-organization-dialog.component.ts b/apps/web/src/app/admin-console/organizations/settings/components/delete-organization-dialog.component.ts index c23dcf2c8f2..8c2bfe079de 100644 --- a/apps/web/src/app/admin-console/organizations/settings/components/delete-organization-dialog.component.ts +++ b/apps/web/src/app/admin-console/organizations/settings/components/delete-organization-dialog.component.ts @@ -71,6 +71,8 @@ export interface DeleteOrganizationDialogParams { requestType: "InvalidFamiliesForEnterprise" | "RegularDelete"; } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum DeleteOrganizationDialogResult { Deleted = "deleted", Canceled = "canceled", @@ -78,7 +80,6 @@ export enum DeleteOrganizationDialogResult { @Component({ selector: "app-delete-organization", - standalone: true, imports: [SharedModule, UserVerificationModule], templateUrl: "delete-organization-dialog.component.html", }) diff --git a/apps/web/src/app/admin-console/organizations/settings/two-factor-setup.component.ts b/apps/web/src/app/admin-console/organizations/settings/two-factor-setup.component.ts index 014b8e3a3ef..020a16dd932 100644 --- a/apps/web/src/app/admin-console/organizations/settings/two-factor-setup.component.ts +++ b/apps/web/src/app/admin-console/organizations/settings/two-factor-setup.component.ts @@ -29,6 +29,7 @@ import { TwoFactorVerifyComponent } from "../../../auth/settings/two-factor/two- @Component({ selector: "app-two-factor-setup", templateUrl: "../../../auth/settings/two-factor/two-factor-setup.component.html", + standalone: false, }) export class TwoFactorSetupComponent extends BaseTwoFactorSetupComponent implements OnInit { tabbedHeader = false; @@ -118,7 +119,7 @@ export class TwoFactorSetupComponent extends BaseTwoFactorSetupComponent impleme return this.apiService.getTwoFactorOrganizationProviders(this.organizationId); } - protected filterProvider(type: TwoFactorProviderType) { + protected filterProvider(type: TwoFactorProviderType): boolean { return type !== TwoFactorProviderType.OrganizationDuo; } } diff --git a/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.component.ts b/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.component.ts index bb25cd90875..366df34b2b8 100644 --- a/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.component.ts +++ b/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.component.ts @@ -26,6 +26,8 @@ import { Permission, } from "./access-selector.models"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum PermissionMode { /** * No permission controls or column present. No permission values are emitted. @@ -53,6 +55,7 @@ export enum PermissionMode { multi: true, }, ], + standalone: false, }) export class AccessSelectorComponent implements ControlValueAccessor, OnInit, OnDestroy { private destroy$ = new Subject(); @@ -310,7 +313,7 @@ export class AccessSelectorComponent implements ControlValueAccessor, OnInit, On protected itemIcon(item: AccessItemView) { switch (item.type) { case AccessItemType.Collection: - return "bwi-collection"; + return "bwi-collection-shared"; case AccessItemType.Group: return "bwi-users"; case AccessItemType.Member: diff --git a/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.models.ts b/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.models.ts index 8702c0f7a6c..884483d32b0 100644 --- a/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.models.ts +++ b/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.models.ts @@ -15,6 +15,8 @@ import { GroupView } from "../../../core"; /** * Permission options that replace/correspond with manage, readOnly, and hidePassword server fields. */ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum CollectionPermission { View = "view", ViewExceptPass = "viewExceptPass", @@ -23,6 +25,8 @@ export enum CollectionPermission { Manage = "manage", } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum AccessItemType { Collection, Group, diff --git a/apps/web/src/app/admin-console/organizations/shared/components/access-selector/user-type.pipe.ts b/apps/web/src/app/admin-console/organizations/shared/components/access-selector/user-type.pipe.ts index 3d43c63efb0..673d09ec0f0 100644 --- a/apps/web/src/app/admin-console/organizations/shared/components/access-selector/user-type.pipe.ts +++ b/apps/web/src/app/admin-console/organizations/shared/components/access-selector/user-type.pipe.ts @@ -5,6 +5,7 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic @Pipe({ name: "userType", + standalone: false, }) export class UserTypePipe implements PipeTransform { constructor(private i18nService: I18nService) {} diff --git a/apps/web/src/app/admin-console/organizations/shared/components/collection-dialog/collection-dialog.component.html b/apps/web/src/app/admin-console/organizations/shared/components/collection-dialog/collection-dialog.component.html index 984d21bf251..4a91fcc2a41 100644 --- a/apps/web/src/app/admin-console/organizations/shared/components/collection-dialog/collection-dialog.component.html +++ b/apps/web/src/app/admin-console/organizations/shared/components/collection-dialog/collection-dialog.component.html @@ -35,7 +35,7 @@ - + {{ "externalId" | i18n }} {{ "externalIdDesc" | i18n }} @@ -48,14 +48,14 @@ diff --git a/apps/web/src/app/admin-console/organizations/shared/components/collection-dialog/collection-dialog.component.ts b/apps/web/src/app/admin-console/organizations/shared/components/collection-dialog/collection-dialog.component.ts index 37d0ebbd195..e9865f14d54 100644 --- a/apps/web/src/app/admin-console/organizations/shared/components/collection-dialog/collection-dialog.component.ts +++ b/apps/web/src/app/admin-console/organizations/shared/components/collection-dialog/collection-dialog.component.ts @@ -38,7 +38,6 @@ import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { DIALOG_DATA, @@ -65,6 +64,8 @@ import { } from "../access-selector/access-selector.models"; import { AccessSelectorModule } from "../access-selector/access-selector.module"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum CollectionDialogTabType { Info = 0, Access = 1, @@ -76,6 +77,8 @@ export enum CollectionDialogTabType { * @readonly * @enum {string} */ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums enum ButtonType { /** Displayed when the user has reached the maximum number of collections allowed for the organization. */ Upgrade = "upgrade", @@ -103,6 +106,8 @@ export interface CollectionDialogResult { collection: CollectionResponse | CollectionView; } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum CollectionDialogAction { Saved = "saved", Canceled = "canceled", @@ -112,7 +117,6 @@ export enum CollectionDialogAction { @Component({ templateUrl: "collection-dialog.component.html", - standalone: true, imports: [SharedModule, AccessSelectorModule, SelectModule], }) export class CollectionDialogComponent implements OnInit, OnDestroy { @@ -129,7 +133,7 @@ export class CollectionDialogComponent implements OnInit, OnDestroy { protected showOrgSelector = false; protected formGroup = this.formBuilder.group({ name: ["", [Validators.required, BitValidators.forbiddenCharacters(["/"])]], - externalId: "", + externalId: { value: "", disabled: true }, parent: undefined as string | undefined, access: [[] as AccessItemValue[]], selectedOrg: "", @@ -139,16 +143,6 @@ export class CollectionDialogComponent implements OnInit, OnDestroy { protected showAddAccessWarning = false; protected collections: Collection[]; protected buttonDisplayName: ButtonType = ButtonType.Save; - protected isExternalIdVisible$ = this.configService - .getFeatureFlag$(FeatureFlag.SsoExternalIdVisibility) - .pipe( - map((isEnabled) => { - return ( - !isEnabled || - (!!this.params.isAdminConsoleActive && !!this.formGroup.get("externalId")?.value) - ); - }), - ); private orgExceedingCollectionLimit!: Organization; constructor( @@ -159,7 +153,6 @@ export class CollectionDialogComponent implements OnInit, OnDestroy { private groupService: GroupApiService, private collectionAdminService: CollectionAdminService, private i18nService: I18nService, - private platformUtilsService: PlatformUtilsService, private organizationUserApiService: OrganizationUserApiService, private dialogService: DialogService, private changeDetectorRef: ChangeDetectorRef, @@ -348,6 +341,10 @@ export class CollectionDialogComponent implements OnInit, OnDestroy { return this.formGroup.controls.selectedOrg; } + protected get isExternalIdVisible(): boolean { + return this.params.isAdminConsoleActive && !!this.formGroup.get("externalId")?.value; + } + protected get collectionId() { return this.params.collectionId; } @@ -484,23 +481,10 @@ export class CollectionDialogComponent implements OnInit, OnDestroy { private handleFormGroupReadonly(readonly: boolean) { if (readonly) { this.formGroup.controls.name.disable(); - this.formGroup.controls.externalId.disable(); this.formGroup.controls.parent.disable(); this.formGroup.controls.access.disable(); } else { this.formGroup.controls.name.enable(); - - this.configService - .getFeatureFlag$(FeatureFlag.SsoExternalIdVisibility) - .pipe(takeUntil(this.destroy$)) - .subscribe((isEnabled) => { - if (isEnabled) { - this.formGroup.controls.externalId.disable(); - } else { - this.formGroup.controls.externalId.enable(); - } - }); - this.formGroup.controls.parent.enable(); this.formGroup.controls.access.enable(); } diff --git a/apps/web/src/app/admin-console/organizations/shared/components/integrations/integration-card/integration-card.component.ts b/apps/web/src/app/admin-console/organizations/shared/components/integrations/integration-card/integration-card.component.ts index 3943ceb22ed..20e4028e9df 100644 --- a/apps/web/src/app/admin-console/organizations/shared/components/integrations/integration-card/integration-card.component.ts +++ b/apps/web/src/app/admin-console/organizations/shared/components/integrations/integration-card/integration-card.component.ts @@ -20,7 +20,6 @@ import { SharedModule } from "../../../../../../shared/shared.module"; @Component({ selector: "app-integration-card", templateUrl: "./integration-card.component.html", - standalone: true, imports: [SharedModule], }) export class IntegrationCardComponent implements AfterViewInit, OnDestroy { diff --git a/apps/web/src/app/admin-console/organizations/shared/components/integrations/integration-grid/integration-grid.component.ts b/apps/web/src/app/admin-console/organizations/shared/components/integrations/integration-grid/integration-grid.component.ts index 2e3158f9894..55b552bd251 100644 --- a/apps/web/src/app/admin-console/organizations/shared/components/integrations/integration-grid/integration-grid.component.ts +++ b/apps/web/src/app/admin-console/organizations/shared/components/integrations/integration-grid/integration-grid.component.ts @@ -11,7 +11,6 @@ import { Integration } from "../models"; @Component({ selector: "app-integration-grid", templateUrl: "./integration-grid.component.html", - standalone: true, imports: [IntegrationCardComponent, SharedModule], }) export class IntegrationGridComponent { diff --git a/apps/web/src/app/admin-console/organizations/shared/components/integrations/integrations.pipe.ts b/apps/web/src/app/admin-console/organizations/shared/components/integrations/integrations.pipe.ts index 760d9913e9e..ae9f73e78c0 100644 --- a/apps/web/src/app/admin-console/organizations/shared/components/integrations/integrations.pipe.ts +++ b/apps/web/src/app/admin-console/organizations/shared/components/integrations/integrations.pipe.ts @@ -6,7 +6,6 @@ import { Integration } from "../../../shared/components/integrations/models"; @Pipe({ name: "filterIntegrations", - standalone: true, }) export class FilterIntegrationsPipe implements PipeTransform { transform(integrations: Integration[], type: IntegrationType): Integration[] { diff --git a/apps/web/src/app/admin-console/organizations/sponsorships/accept-family-sponsorship.component.ts b/apps/web/src/app/admin-console/organizations/sponsorships/accept-family-sponsorship.component.ts index 7ceaed28f80..4df6defe8ad 100644 --- a/apps/web/src/app/admin-console/organizations/sponsorships/accept-family-sponsorship.component.ts +++ b/apps/web/src/app/admin-console/organizations/sponsorships/accept-family-sponsorship.component.ts @@ -19,6 +19,7 @@ import { BaseAcceptComponent } from "../../../common/base.accept.component"; @Component({ selector: "app-accept-family-sponsorship", templateUrl: "accept-family-sponsorship.component.html", + standalone: false, }) export class AcceptFamilySponsorshipComponent extends BaseAcceptComponent { protected logo = BitwardenLogo; diff --git a/apps/web/src/app/admin-console/organizations/sponsorships/families-for-enterprise-setup.component.ts b/apps/web/src/app/admin-console/organizations/sponsorships/families-for-enterprise-setup.component.ts index 57fe212fa65..30c0ba159c1 100644 --- a/apps/web/src/app/admin-console/organizations/sponsorships/families-for-enterprise-setup.component.ts +++ b/apps/web/src/app/admin-console/organizations/sponsorships/families-for-enterprise-setup.component.ts @@ -30,7 +30,6 @@ import { @Component({ templateUrl: "families-for-enterprise-setup.component.html", - standalone: true, imports: [SharedModule, OrganizationPlansComponent], }) export class FamiliesForEnterpriseSetupComponent implements OnInit, OnDestroy { diff --git a/apps/web/src/app/admin-console/organizations/users/enroll-master-password-reset.component.ts b/apps/web/src/app/admin-console/organizations/users/enroll-master-password-reset.component.ts index 15e7af1cd2d..b63171ae6e6 100644 --- a/apps/web/src/app/admin-console/organizations/users/enroll-master-password-reset.component.ts +++ b/apps/web/src/app/admin-console/organizations/users/enroll-master-password-reset.component.ts @@ -18,8 +18,8 @@ import { Utils } from "@bitwarden/common/platform/misc/utils"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { DialogService, ToastService } from "@bitwarden/components"; import { KeyService } from "@bitwarden/key-management"; +import { AccountRecoveryTrustComponent } from "@bitwarden/key-management-ui"; -import { OrganizationTrustComponent } from "../manage/organization-trust.component"; import { OrganizationUserResetPasswordService } from "../members/services/organization-user-reset-password/organization-user-reset-password.service"; interface EnrollMasterPasswordResetData { @@ -62,7 +62,7 @@ export class EnrollMasterPasswordReset { await userVerificationService.buildRequest( secret, ); - const dialogRef = OrganizationTrustComponent.open(dialogService, { + const dialogRef = AccountRecoveryTrustComponent.open(dialogService, { name: data.organization.name, orgId: data.organization.id, publicKey, diff --git a/apps/web/src/app/admin-console/settings/create-organization.component.ts b/apps/web/src/app/admin-console/settings/create-organization.component.ts index 7a20826086d..f87e9ec5b72 100644 --- a/apps/web/src/app/admin-console/settings/create-organization.component.ts +++ b/apps/web/src/app/admin-console/settings/create-organization.component.ts @@ -13,7 +13,6 @@ import { SharedModule } from "../../shared"; @Component({ templateUrl: "create-organization.component.html", - standalone: true, imports: [SharedModule, OrganizationPlansComponent, HeaderModule], }) export class CreateOrganizationComponent { diff --git a/apps/web/src/app/app.component.ts b/apps/web/src/app/app.component.ts index 55e2595e0f7..3de9bf0a8c8 100644 --- a/apps/web/src/app/app.component.ts +++ b/apps/web/src/app/app.component.ts @@ -3,25 +3,20 @@ import { DOCUMENT } from "@angular/common"; import { Component, Inject, NgZone, OnDestroy, OnInit } from "@angular/core"; import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; -import { NavigationEnd, Router } from "@angular/router"; -import * as jq from "jquery"; +import { Router } from "@angular/router"; import { Subject, filter, firstValueFrom, map, takeUntil, timeout } from "rxjs"; import { CollectionService } from "@bitwarden/admin-console/common"; import { DeviceTrustToastService } from "@bitwarden/angular/auth/services/device-trust-toast.service.abstraction"; -import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { EventUploadService } from "@bitwarden/common/abstractions/event/event-upload.service"; import { SearchService } from "@bitwarden/common/abstractions/search.service"; import { InternalOrganizationServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; -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 { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { ProcessReloadServiceAbstraction } from "@bitwarden/common/key-management/abstractions/process-reload.service"; -import { KeyConnectorService } from "@bitwarden/common/key-management/key-connector/abstractions/key-connector.service"; import { VaultTimeoutService } from "@bitwarden/common/key-management/vault-timeout"; -import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service"; import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; @@ -29,11 +24,9 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { NotificationsService } from "@bitwarden/common/platform/notifications"; import { StateEventRunnerService } from "@bitwarden/common/platform/state"; -import { SyncService } from "@bitwarden/common/platform/sync"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { InternalFolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; import { DialogService, ToastService } from "@bitwarden/components"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { KeyService, BiometricStateService } from "@bitwarden/key-management"; import { PolicyListService } from "./admin-console/core/policy-list.service"; @@ -56,6 +49,7 @@ const IdleTimeout = 60000 * 10; // 10 minutes @Component({ selector: "app-root", templateUrl: "app.component.html", + standalone: false, }) export class AppComponent implements OnDestroy, OnInit { private lastActivity: Date = null; @@ -69,8 +63,6 @@ export class AppComponent implements OnDestroy, OnInit { @Inject(DOCUMENT) private document: Document, private broadcasterService: BroadcasterService, private folderService: InternalFolderService, - private syncService: SyncService, - private passwordGenerationService: PasswordGenerationServiceAbstraction, private cipherService: CipherService, private authService: AuthService, private router: Router, @@ -85,17 +77,13 @@ export class AppComponent implements OnDestroy, OnInit { private notificationsService: NotificationsService, private stateService: StateService, private eventUploadService: EventUploadService, - private policyService: InternalPolicyService, protected policyListService: PolicyListService, - private keyConnectorService: KeyConnectorService, protected configService: ConfigService, private dialogService: DialogService, private biometricStateService: BiometricStateService, private stateEventRunnerService: StateEventRunnerService, private organizationService: InternalOrganizationServiceAbstraction, private accountService: AccountService, - private apiService: ApiService, - private appIdService: AppIdService, private processReloadService: ProcessReloadServiceAbstraction, private deviceTrustToastService: DeviceTrustToastService, ) { @@ -247,15 +235,6 @@ export class AppComponent implements OnDestroy, OnInit { }); }); - this.router.events.pipe(takeUntil(this.destroy$)).subscribe((event) => { - if (event instanceof NavigationEnd) { - const modals = Array.from(document.querySelectorAll(".modal")); - for (const modal of modals) { - (jq(modal) as any).modal("hide"); - } - } - }); - this.policyListService.addPolicies([ new TwoFactorAuthenticationPolicy(), new MasterPasswordPolicy(), @@ -303,7 +282,7 @@ export class AppComponent implements OnDestroy, OnInit { ); await Promise.all([ - this.keyService.clearKeys(), + this.keyService.clearKeys(userId), this.cipherService.clear(userId), this.folderService.clear(userId), this.collectionService.clear(userId), diff --git a/apps/web/src/app/auth/core/enums/webauthn-login-credential-prf-status.enum.ts b/apps/web/src/app/auth/core/enums/webauthn-login-credential-prf-status.enum.ts index 7dc8217fde5..3073917e57b 100644 --- a/apps/web/src/app/auth/core/enums/webauthn-login-credential-prf-status.enum.ts +++ b/apps/web/src/app/auth/core/enums/webauthn-login-credential-prf-status.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum WebauthnLoginCredentialPrfStatus { Enabled = 0, Supported = 1, diff --git a/apps/web/src/app/auth/core/services/change-password/index.ts b/apps/web/src/app/auth/core/services/change-password/index.ts new file mode 100644 index 00000000000..9b2aa1c0143 --- /dev/null +++ b/apps/web/src/app/auth/core/services/change-password/index.ts @@ -0,0 +1 @@ +export * from "./web-change-password.service"; diff --git a/apps/web/src/app/auth/core/services/change-password/web-change-password.service.spec.ts b/apps/web/src/app/auth/core/services/change-password/web-change-password.service.spec.ts new file mode 100644 index 00000000000..45abfe4720a --- /dev/null +++ b/apps/web/src/app/auth/core/services/change-password/web-change-password.service.spec.ts @@ -0,0 +1,63 @@ +import { mock, MockProxy } from "jest-mock-extended"; + +import { ChangePasswordService } from "@bitwarden/auth/angular"; +import { Account } from "@bitwarden/common/auth/abstractions/account.service"; +import { MasterPasswordApiService } from "@bitwarden/common/auth/abstractions/master-password-api.service.abstraction"; +import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction"; +import { UserId } from "@bitwarden/common/types/guid"; +import { KeyService } from "@bitwarden/key-management"; +import { UserKeyRotationService } from "@bitwarden/web-vault/app/key-management/key-rotation/user-key-rotation.service"; + +import { WebChangePasswordService } from "./web-change-password.service"; + +describe("WebChangePasswordService", () => { + let keyService: MockProxy; + let masterPasswordApiService: MockProxy; + let masterPasswordService: MockProxy; + let userKeyRotationService: MockProxy; + + let sut: ChangePasswordService; + + const userId = "userId" as UserId; + const user: Account = { + id: userId, + email: "email", + emailVerified: false, + name: "name", + }; + + const currentPassword = "currentPassword"; + const newPassword = "newPassword"; + const newPasswordHint = "newPasswordHint"; + + beforeEach(() => { + keyService = mock(); + masterPasswordApiService = mock(); + masterPasswordService = mock(); + userKeyRotationService = mock(); + + sut = new WebChangePasswordService( + keyService, + masterPasswordApiService, + masterPasswordService, + userKeyRotationService, + ); + }); + + describe("rotateUserKeyMasterPasswordAndEncryptedData()", () => { + it("should call the method with the same name on the UserKeyRotationService with the correct arguments", async () => { + // Arrange & Act + await sut.rotateUserKeyMasterPasswordAndEncryptedData( + currentPassword, + newPassword, + user, + newPasswordHint, + ); + + // Assert + expect( + userKeyRotationService.rotateUserKeyMasterPasswordAndEncryptedData, + ).toHaveBeenCalledWith(currentPassword, newPassword, user, newPasswordHint); + }); + }); +}); diff --git a/apps/web/src/app/auth/core/services/change-password/web-change-password.service.ts b/apps/web/src/app/auth/core/services/change-password/web-change-password.service.ts new file mode 100644 index 00000000000..b75aef0f1fc --- /dev/null +++ b/apps/web/src/app/auth/core/services/change-password/web-change-password.service.ts @@ -0,0 +1,34 @@ +import { ChangePasswordService, DefaultChangePasswordService } from "@bitwarden/auth/angular"; +import { Account } from "@bitwarden/common/auth/abstractions/account.service"; +import { MasterPasswordApiService } from "@bitwarden/common/auth/abstractions/master-password-api.service.abstraction"; +import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction"; +import { KeyService } from "@bitwarden/key-management"; +import { UserKeyRotationService } from "@bitwarden/web-vault/app/key-management/key-rotation/user-key-rotation.service"; + +export class WebChangePasswordService + extends DefaultChangePasswordService + implements ChangePasswordService +{ + constructor( + protected keyService: KeyService, + protected masterPasswordApiService: MasterPasswordApiService, + protected masterPasswordService: InternalMasterPasswordServiceAbstraction, + private userKeyRotationService: UserKeyRotationService, + ) { + super(keyService, masterPasswordApiService, masterPasswordService); + } + + override async rotateUserKeyMasterPasswordAndEncryptedData( + currentPassword: string, + newPassword: string, + user: Account, + newPasswordHint: string, + ): Promise { + await this.userKeyRotationService.rotateUserKeyMasterPasswordAndEncryptedData( + currentPassword, + newPassword, + user, + newPasswordHint, + ); + } +} diff --git a/apps/web/src/app/auth/core/services/index.ts b/apps/web/src/app/auth/core/services/index.ts index 11c8dd98872..5539e3b76ea 100644 --- a/apps/web/src/app/auth/core/services/index.ts +++ b/apps/web/src/app/auth/core/services/index.ts @@ -1,3 +1,4 @@ +export * from "./change-password"; export * from "./login"; export * from "./login-decryption-options"; export * from "./webauthn-login"; diff --git a/apps/web/src/app/auth/core/services/login/web-login-component.service.ts b/apps/web/src/app/auth/core/services/login/web-login-component.service.ts index c644f26dd90..36e7143ccd0 100644 --- a/apps/web/src/app/auth/core/services/login/web-login-component.service.ts +++ b/apps/web/src/app/auth/core/services/login/web-login-component.service.ts @@ -98,7 +98,7 @@ export class WebLoginComponentService const enforcedPasswordPolicyOptions = await firstValueFrom( this.accountService.activeAccount$.pipe( getUserId, - switchMap((userId) => this.policyService.masterPasswordPolicyOptions$(userId)), + switchMap((userId) => this.policyService.masterPasswordPolicyOptions$(userId, policies)), ), ); diff --git a/apps/web/src/app/auth/core/services/registration/web-registration-finish.service.spec.ts b/apps/web/src/app/auth/core/services/registration/web-registration-finish.service.spec.ts index aa02e28b3b3..fe3b0837aa8 100644 --- a/apps/web/src/app/auth/core/services/registration/web-registration-finish.service.spec.ts +++ b/apps/web/src/app/auth/core/services/registration/web-registration-finish.service.spec.ts @@ -172,7 +172,6 @@ describe("WebRegistrationFinishService", () => { let userKey: UserKey; let userKeyEncString: EncString; let userKeyPair: [string, EncString]; - let capchaBypassToken: string; let orgInvite: OrganizationInvite; let orgSponsoredFreeFamilyPlanToken: string; @@ -186,11 +185,11 @@ describe("WebRegistrationFinishService", () => { emailVerificationToken = "emailVerificationToken"; masterKey = new SymmetricCryptoKey(new Uint8Array(64).buffer as CsprngArray) as MasterKey; passwordInputResult = { - masterKey: masterKey, - serverMasterKeyHash: "serverMasterKeyHash", - localMasterKeyHash: "localMasterKeyHash", + newMasterKey: masterKey, + newServerMasterKeyHash: "newServerMasterKeyHash", + newLocalMasterKeyHash: "newLocalMasterKeyHash", kdfConfig: DEFAULT_KDF_CONFIG, - hint: "hint", + newPasswordHint: "newPasswordHint", newPassword: "newPassword", }; @@ -198,7 +197,6 @@ describe("WebRegistrationFinishService", () => { userKeyEncString = new EncString("userKeyEncrypted"); userKeyPair = ["publicKey", new EncString("privateKey")]; - capchaBypassToken = "capchaBypassToken"; orgInvite = new OrganizationInvite(); orgInvite.organizationUserId = "organizationUserId"; @@ -219,19 +217,13 @@ describe("WebRegistrationFinishService", () => { ); }); - it("registers the user and returns a captcha bypass token when given valid email verification input", async () => { + it("registers the user when given valid email verification input", async () => { keyService.makeUserKey.mockResolvedValue([userKey, userKeyEncString]); keyService.makeKeyPair.mockResolvedValue(userKeyPair); - accountApiService.registerFinish.mockResolvedValue(capchaBypassToken); + accountApiService.registerFinish.mockResolvedValue(); acceptOrgInviteService.getOrganizationInvite.mockResolvedValue(null); - const result = await service.finishRegistration( - email, - passwordInputResult, - emailVerificationToken, - ); - - expect(result).toEqual(capchaBypassToken); + await service.finishRegistration(email, passwordInputResult, emailVerificationToken); expect(keyService.makeUserKey).toHaveBeenCalledWith(masterKey); expect(keyService.makeKeyPair).toHaveBeenCalledWith(userKey); @@ -239,8 +231,8 @@ describe("WebRegistrationFinishService", () => { expect.objectContaining({ email, emailVerificationToken: emailVerificationToken, - masterPasswordHash: passwordInputResult.serverMasterKeyHash, - masterPasswordHint: passwordInputResult.hint, + masterPasswordHash: passwordInputResult.newServerMasterKeyHash, + masterPasswordHint: passwordInputResult.newPasswordHint, userSymmetricKey: userKeyEncString.encryptedString, userAsymmetricKeys: { publicKey: userKeyPair[0], @@ -261,15 +253,13 @@ describe("WebRegistrationFinishService", () => { ); }); - it("it registers the user and returns a captcha bypass token when given an org invite", async () => { + it("it registers the user when given an org invite", async () => { keyService.makeUserKey.mockResolvedValue([userKey, userKeyEncString]); keyService.makeKeyPair.mockResolvedValue(userKeyPair); - accountApiService.registerFinish.mockResolvedValue(capchaBypassToken); + accountApiService.registerFinish.mockResolvedValue(); acceptOrgInviteService.getOrganizationInvite.mockResolvedValue(orgInvite); - const result = await service.finishRegistration(email, passwordInputResult); - - expect(result).toEqual(capchaBypassToken); + await service.finishRegistration(email, passwordInputResult); expect(keyService.makeUserKey).toHaveBeenCalledWith(masterKey); expect(keyService.makeKeyPair).toHaveBeenCalledWith(userKey); @@ -277,8 +267,8 @@ describe("WebRegistrationFinishService", () => { expect.objectContaining({ email, emailVerificationToken: undefined, - masterPasswordHash: passwordInputResult.serverMasterKeyHash, - masterPasswordHint: passwordInputResult.hint, + masterPasswordHash: passwordInputResult.newServerMasterKeyHash, + masterPasswordHint: passwordInputResult.newPasswordHint, userSymmetricKey: userKeyEncString.encryptedString, userAsymmetricKeys: { publicKey: userKeyPair[0], @@ -299,29 +289,27 @@ describe("WebRegistrationFinishService", () => { ); }); - it("registers the user and returns a captcha bypass token when given an org sponsored free family plan token", async () => { + it("registers the user when given an org sponsored free family plan token", async () => { keyService.makeUserKey.mockResolvedValue([userKey, userKeyEncString]); keyService.makeKeyPair.mockResolvedValue(userKeyPair); - accountApiService.registerFinish.mockResolvedValue(capchaBypassToken); + accountApiService.registerFinish.mockResolvedValue(); acceptOrgInviteService.getOrganizationInvite.mockResolvedValue(null); - const result = await service.finishRegistration( + await service.finishRegistration( email, passwordInputResult, undefined, orgSponsoredFreeFamilyPlanToken, ); - expect(result).toEqual(capchaBypassToken); - expect(keyService.makeUserKey).toHaveBeenCalledWith(masterKey); expect(keyService.makeKeyPair).toHaveBeenCalledWith(userKey); expect(accountApiService.registerFinish).toHaveBeenCalledWith( expect.objectContaining({ email, emailVerificationToken: undefined, - masterPasswordHash: passwordInputResult.serverMasterKeyHash, - masterPasswordHint: passwordInputResult.hint, + masterPasswordHash: passwordInputResult.newServerMasterKeyHash, + masterPasswordHint: passwordInputResult.newPasswordHint, userSymmetricKey: userKeyEncString.encryptedString, userAsymmetricKeys: { publicKey: userKeyPair[0], @@ -342,13 +330,13 @@ describe("WebRegistrationFinishService", () => { ); }); - it("registers the user and returns a captcha bypass token when given an emergency access invite token", async () => { + it("registers the user when given an emergency access invite token", async () => { keyService.makeUserKey.mockResolvedValue([userKey, userKeyEncString]); keyService.makeKeyPair.mockResolvedValue(userKeyPair); - accountApiService.registerFinish.mockResolvedValue(capchaBypassToken); + accountApiService.registerFinish.mockResolvedValue(); acceptOrgInviteService.getOrganizationInvite.mockResolvedValue(null); - const result = await service.finishRegistration( + await service.finishRegistration( email, passwordInputResult, undefined, @@ -357,16 +345,14 @@ describe("WebRegistrationFinishService", () => { emergencyAccessId, ); - expect(result).toEqual(capchaBypassToken); - expect(keyService.makeUserKey).toHaveBeenCalledWith(masterKey); expect(keyService.makeKeyPair).toHaveBeenCalledWith(userKey); expect(accountApiService.registerFinish).toHaveBeenCalledWith( expect.objectContaining({ email, emailVerificationToken: undefined, - masterPasswordHash: passwordInputResult.serverMasterKeyHash, - masterPasswordHint: passwordInputResult.hint, + masterPasswordHash: passwordInputResult.newServerMasterKeyHash, + masterPasswordHint: passwordInputResult.newPasswordHint, userSymmetricKey: userKeyEncString.encryptedString, userAsymmetricKeys: { publicKey: userKeyPair[0], @@ -387,13 +373,13 @@ describe("WebRegistrationFinishService", () => { ); }); - it("registers the user and returns a captcha bypass token when given a provider invite token", async () => { + it("registers the user when given a provider invite token", async () => { keyService.makeUserKey.mockResolvedValue([userKey, userKeyEncString]); keyService.makeKeyPair.mockResolvedValue(userKeyPair); - accountApiService.registerFinish.mockResolvedValue(capchaBypassToken); + accountApiService.registerFinish.mockResolvedValue(); acceptOrgInviteService.getOrganizationInvite.mockResolvedValue(null); - const result = await service.finishRegistration( + await service.finishRegistration( email, passwordInputResult, undefined, @@ -404,16 +390,14 @@ describe("WebRegistrationFinishService", () => { providerUserId, ); - expect(result).toEqual(capchaBypassToken); - expect(keyService.makeUserKey).toHaveBeenCalledWith(masterKey); expect(keyService.makeKeyPair).toHaveBeenCalledWith(userKey); expect(accountApiService.registerFinish).toHaveBeenCalledWith( expect.objectContaining({ email, emailVerificationToken: undefined, - masterPasswordHash: passwordInputResult.serverMasterKeyHash, - masterPasswordHint: passwordInputResult.hint, + masterPasswordHash: passwordInputResult.newServerMasterKeyHash, + masterPasswordHint: passwordInputResult.newPasswordHint, userSymmetricKey: userKeyEncString.encryptedString, userAsymmetricKeys: { publicKey: userKeyPair[0], diff --git a/apps/web/src/app/auth/core/services/rotateable-key-set.service.ts b/apps/web/src/app/auth/core/services/rotateable-key-set.service.ts index ef78e09e6b9..0a150b26ae2 100644 --- a/apps/web/src/app/auth/core/services/rotateable-key-set.service.ts +++ b/apps/web/src/app/auth/core/services/rotateable-key-set.service.ts @@ -58,7 +58,7 @@ export class RotateableKeySetService { throw new Error("failed to rotate key set: newUserKey is required"); } - const publicKey = await this.encryptService.decryptToBytes( + const publicKey = await this.encryptService.unwrapEncapsulationKey( keySet.encryptedPublicKey, oldUserKey, ); diff --git a/apps/web/src/app/auth/core/services/two-factor-auth/index.ts b/apps/web/src/app/auth/core/services/two-factor-auth/index.ts index ba2697fdee4..4ca57b34737 100644 --- a/apps/web/src/app/auth/core/services/two-factor-auth/index.ts +++ b/apps/web/src/app/auth/core/services/two-factor-auth/index.ts @@ -1,2 +1 @@ -export * from "./web-two-factor-auth-component.service"; export * from "./web-two-factor-auth-duo-component.service"; diff --git a/apps/web/src/app/auth/core/services/two-factor-auth/web-two-factor-auth-component.service.ts b/apps/web/src/app/auth/core/services/two-factor-auth/web-two-factor-auth-component.service.ts deleted file mode 100644 index 451cec57ddd..00000000000 --- a/apps/web/src/app/auth/core/services/two-factor-auth/web-two-factor-auth-component.service.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { - DefaultTwoFactorAuthComponentService, - TwoFactorAuthComponentService, - LegacyKeyMigrationAction, -} from "@bitwarden/auth/angular"; - -export class WebTwoFactorAuthComponentService - extends DefaultTwoFactorAuthComponentService - implements TwoFactorAuthComponentService -{ - override determineLegacyKeyMigrationAction(): LegacyKeyMigrationAction { - return LegacyKeyMigrationAction.NAVIGATE_TO_MIGRATION_COMPONENT; - } -} diff --git a/apps/web/src/app/auth/emergency-access/enums/emergency-access-status-type.ts b/apps/web/src/app/auth/emergency-access/enums/emergency-access-status-type.ts index 94400f34e6e..16aa2546101 100644 --- a/apps/web/src/app/auth/emergency-access/enums/emergency-access-status-type.ts +++ b/apps/web/src/app/auth/emergency-access/enums/emergency-access-status-type.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum EmergencyAccessStatusType { Invited = 0, Accepted = 1, diff --git a/apps/web/src/app/auth/emergency-access/enums/emergency-access-type.ts b/apps/web/src/app/auth/emergency-access/enums/emergency-access-type.ts index 61a366c433e..ecb0c5a3d07 100644 --- a/apps/web/src/app/auth/emergency-access/enums/emergency-access-type.ts +++ b/apps/web/src/app/auth/emergency-access/enums/emergency-access-type.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum EmergencyAccessType { View = 0, Takeover = 1, diff --git a/apps/web/src/app/auth/guards/deep-link.guard.ts b/apps/web/src/app/auth/guards/deep-link.guard.ts deleted file mode 100644 index 387e7b17e88..00000000000 --- a/apps/web/src/app/auth/guards/deep-link.guard.ts +++ /dev/null @@ -1,58 +0,0 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore -import { inject } from "@angular/core"; -import { CanActivateFn, Router } from "@angular/router"; - -import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; -import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; -import { Utils } from "@bitwarden/common/platform/misc/utils"; - -import { RouterService } from "../../core/router.service"; - -/** - * Guard to persist and apply deep links to handle users who are not unlocked. - * @returns returns true. If user is not Unlocked will store URL to state for redirect once - * user is unlocked/Authenticated. - */ -export function deepLinkGuard(): CanActivateFn { - return async (route, routerState) => { - // Inject Services - const authService = inject(AuthService); - const router = inject(Router); - const routerService = inject(RouterService); - - // Fetch State - const currentUrl = routerState.url; - const transientPreviousUrl = routerService.getPreviousUrl(); - const authStatus = await authService.getAuthStatus(); - - // Evaluate State - /** before anything else, check if the user is already unlocked. */ - if (authStatus === AuthenticationStatus.Unlocked) { - const persistedPreLoginUrl = await routerService.getAndClearLoginRedirectUrl(); - if (!Utils.isNullOrEmpty(persistedPreLoginUrl)) { - return router.navigateByUrl(persistedPreLoginUrl); - } - return true; - } - /** - * At this point the user is either `locked` or `loggedOut`, it doesn't matter. - * We opt to persist the currentUrl over the transient previousUrl. This supports - * the case where a user is locked out of their vault and they deep link from - * the "lock" page. - * - * When the user is locked out of their vault the currentUrl contains "lock" so it will - * not be persisted, the previousUrl will be persisted instead. - */ - if (isValidUrl(currentUrl)) { - await routerService.persistLoginRedirectUrl(currentUrl); - } else if (isValidUrl(transientPreviousUrl)) { - await routerService.persistLoginRedirectUrl(transientPreviousUrl); - } - return true; - }; - - function isValidUrl(url: string | null | undefined): boolean { - return !Utils.isNullOrEmpty(url) && !url?.toLocaleLowerCase().includes("/lock"); - } -} diff --git a/apps/web/src/app/auth/guards/deep-link.guard.spec.ts b/apps/web/src/app/auth/guards/deep-link/deep-link.guard.spec.ts similarity index 91% rename from apps/web/src/app/auth/guards/deep-link.guard.spec.ts rename to apps/web/src/app/auth/guards/deep-link/deep-link.guard.spec.ts index f9ced556e47..dba4dbd8357 100644 --- a/apps/web/src/app/auth/guards/deep-link.guard.spec.ts +++ b/apps/web/src/app/auth/guards/deep-link/deep-link.guard.spec.ts @@ -7,22 +7,25 @@ import { MockProxy, mock } from "jest-mock-extended"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; -import { RouterService } from "../../core/router.service"; +import { RouterService } from "../../../core/router.service"; import { deepLinkGuard } from "./deep-link.guard"; @Component({ template: "", + standalone: false, }) export class GuardedRouteTestComponent {} @Component({ template: "", + standalone: false, }) export class LockTestComponent {} @Component({ template: "", + standalone: false, }) export class RedirectTestComponent {} @@ -96,6 +99,18 @@ describe("Deep Link Guard", () => { expect(routerService.persistLoginRedirectUrl).not.toHaveBeenCalled(); }); + it('should not persist routerService.previousUrl when routerService.previousUrl contains "login-initiated"', async () => { + // Arrange + authService.getAuthStatus.mockResolvedValue(AuthenticationStatus.Locked); + routerService.getPreviousUrl.mockReturnValue("/login-initiated"); + + // Act + await routerHarness.navigateByUrl("/lock-route"); + + // Assert + expect(routerService.persistLoginRedirectUrl).not.toHaveBeenCalled(); + }); + // Story: User's vault times out and previousUrl is undefined it("should not persist routerService.previousUrl when routerService.previousUrl is undefined", async () => { // Arrange diff --git a/apps/web/src/app/auth/guards/deep-link/deep-link.guard.ts b/apps/web/src/app/auth/guards/deep-link/deep-link.guard.ts new file mode 100644 index 00000000000..003f0580969 --- /dev/null +++ b/apps/web/src/app/auth/guards/deep-link/deep-link.guard.ts @@ -0,0 +1,99 @@ +import { inject } from "@angular/core"; +import { CanActivateFn, Router } from "@angular/router"; + +import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; +import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; +import { Utils } from "@bitwarden/common/platform/misc/utils"; + +import { RouterService } from "../../../core/router.service"; + +/** + * Guard to persist and apply deep links to handle users who are not unlocked. + * @returns returns true. If user is not Unlocked will store URL to state for redirect once + * user is unlocked/Authenticated. + */ +export function deepLinkGuard(): CanActivateFn { + return async (route, routerState) => { + // Inject Services + const authService = inject(AuthService); + const router = inject(Router); + const routerService = inject(RouterService); + + // Fetch State + const currentUrl = routerState.url; + const transientPreviousUrl = routerService.getPreviousUrl(); + const authStatus = await authService.getAuthStatus(); + + // Evaluate State + /** before anything else, check if the user is already unlocked. */ + if (authStatus === AuthenticationStatus.Unlocked) { + const persistedPreLoginUrl: string | undefined = + await routerService.getAndClearLoginRedirectUrl(); + if (persistedPreLoginUrl === undefined) { + // Url us undefined, so there is nothing to navigate to. + return true; + } + // Check if the url is empty or null + if (!Utils.isNullOrEmpty(persistedPreLoginUrl)) { + // const urlTree: string | UrlTree = persistedPreLoginUrl; + return router.navigateByUrl(persistedPreLoginUrl); + } + return true; + } + /** + * At this point the user is either `locked` or `loggedOut`, it doesn't matter. + * We opt to persist the currentUrl over the transient previousUrl. This supports + * the case where a user is locked out of their vault and they deep link from + * the "lock" page. + * + * When the user is locked out of their vault the currentUrl contains "lock" so it will + * not be persisted, the previousUrl will be persisted instead. + */ + if (isValidUrl(currentUrl)) { + await routerService.persistLoginRedirectUrl(currentUrl); + } else if (isValidUrl(transientPreviousUrl) && transientPreviousUrl !== undefined) { + await routerService.persistLoginRedirectUrl(transientPreviousUrl); + } + return true; + }; + + /** + * Check if the URL is valid for deep linking. A valid url is described as not including + * "lock" or "login-initiated". Valid urls are only urls that are not part of login or + * decryption flows. + * We ignore the "lock" url because standard SSO flows will send users to the lock component. + * We ignore "login-initiated" because TDE users decrypting with master passwords are + * sent to the lock component. + * @param url The URL to check. + * @returns True if the URL is valid, false otherwise. + */ + function isValidUrl(url: string | null | undefined): boolean { + if (url === undefined || url === null) { + return false; + } + + if (Utils.isNullOrEmpty(url)) { + return false; + } + const lowerCaseUrl: string = url.toLocaleLowerCase(); + + /** + * "Login-initiated" ignored because it is used for TDE users decrypting from a new device. A TDE user + * can opt to decrypt using their password. Decrypting with a password will send the user to the lock component, + * which is protected by the deep link guard. We don't persist the `login-initiated` url because it is not a + * valid deep-link. We don't want users to be sent to the login-initiated url when they are unlocked. + * If we did navigate to the login-initiated url, the user would get caught by the TDE Guard and be sent + * to the vault and not the intended deep link. + * + * "Lock" is ignored because users cannot deep-link to the lock component if they are already unlocked. + * Users logging in with SSO will be sent to the lock component after they are authenticated with their IdP. + * SSO users would be navigated to the "lock" component loop if we persisted the "lock" url. + */ + + if (lowerCaseUrl.includes("/login-initiated") || lowerCaseUrl.includes("/lock")) { + return false; + } + + return true; + } +} diff --git a/apps/web/src/app/auth/guards/deep-link/readme.md b/apps/web/src/app/auth/guards/deep-link/readme.md new file mode 100644 index 00000000000..82aebf95476 --- /dev/null +++ b/apps/web/src/app/auth/guards/deep-link/readme.md @@ -0,0 +1,23 @@ +# Deep-link Guard + +The `deep-link.guard.ts` supports users who are trying to access a protected route from an unauthenticated or locked state. + +This guard will persist the protected URL to session state when a user is either unauthenticated or in an encrypted/locked state. This allows users to have multiple tabs of the application running simultaneously without interfering with 'previousUrl` functionality. + +Writing to session state allows users who are authenticating through SSO to be routed to their identity provider and back without losing the protected route they were trying to access in the first place. + +The deep link guard will not persist Urls that are in the middle of authentication or decryption. SSO users will sometimes have to decrypt their vault after a successful authentication. This is why we do not persist the `/lock` route. + +## General operation + +The `deep-link.guard.ts` will always return true. The `deep-link.guard.ts` will only persist a URL if the user is in an unauthenticated or locked state. The URL cannot contain `/lock` or `/login-initiated`. The persisted URL is cleared from state when it is read. + +## Routes to protect + +The deep link guards should be used on routes where a user will be navigated to a protected route but may not be authenticated, decrypted, or have an account. + +A use cases is the `emergency-access` route which is a link that is sent to the user's email address, and in order for them to accept the request, they must first authenticate and decrypt. + +## TDE Users decrypting/unlocking with password + +For TDE users opting to decrypt with a password they will be routed from the `login-initiated` to the `lock` route. We ignore the `login-initiated` route for this reason allowing TDE users who decrypt/unlock with a password to still be navigated to the initial request. diff --git a/apps/web/src/app/auth/login/login-via-webauthn/login-via-webauthn.component.ts b/apps/web/src/app/auth/login/login-via-webauthn/login-via-webauthn.component.ts index 8f3a5ca3c37..d4a381159ab 100644 --- a/apps/web/src/app/auth/login/login-via-webauthn/login-via-webauthn.component.ts +++ b/apps/web/src/app/auth/login/login-via-webauthn/login-via-webauthn.component.ts @@ -7,6 +7,7 @@ import { CreatePasskeyIcon } from "@bitwarden/angular/auth/icons/create-passkey. @Component({ selector: "app-login-via-webauthn", templateUrl: "login-via-webauthn.component.html", + standalone: false, }) export class LoginViaWebAuthnComponent extends BaseLoginViaWebAuthnComponent { protected readonly Icons = { CreatePasskeyIcon, CreatePasskeyFailedIcon }; diff --git a/apps/web/src/app/auth/organization-invite/accept-organization.component.ts b/apps/web/src/app/auth/organization-invite/accept-organization.component.ts index 197b4031998..838a3029711 100644 --- a/apps/web/src/app/auth/organization-invite/accept-organization.component.ts +++ b/apps/web/src/app/auth/organization-invite/accept-organization.component.ts @@ -14,6 +14,7 @@ import { OrganizationInvite } from "./organization-invite"; @Component({ templateUrl: "accept-organization.component.html", + standalone: false, }) export class AcceptOrganizationComponent extends BaseAcceptComponent { orgName$ = this.acceptOrganizationInviteService.orgName$; diff --git a/apps/web/src/app/auth/organization-invite/accept-organization.service.spec.ts b/apps/web/src/app/auth/organization-invite/accept-organization.service.spec.ts index 0a30aa16478..253328b0c04 100644 --- a/apps/web/src/app/auth/organization-invite/accept-organization.service.spec.ts +++ b/apps/web/src/app/auth/organization-invite/accept-organization.service.spec.ts @@ -95,7 +95,7 @@ describe("AcceptOrganizationInviteService", () => { encryptService.wrapDecapsulationKey.mockResolvedValue({ encryptedString: "string", } as EncString); - encryptService.encrypt.mockResolvedValue({ encryptedString: "string" } as EncString); + encryptService.encryptString.mockResolvedValue({ encryptedString: "string" } as EncString); const invite = createOrgInvite({ initOrganization: true }); const result = await sut.validateAndAcceptInvite(invite); diff --git a/apps/web/src/app/auth/organization-invite/accept-organization.service.ts b/apps/web/src/app/auth/organization-invite/accept-organization.service.ts index b6a7719c548..c68b174166d 100644 --- a/apps/web/src/app/auth/organization-invite/accept-organization.service.ts +++ b/apps/web/src/app/auth/organization-invite/accept-organization.service.ts @@ -145,7 +145,7 @@ export class AcceptOrganizationInviteService { const [encryptedOrgKey, orgKey] = await this.keyService.makeOrgKey(); const [orgPublicKey, encryptedOrgPrivateKey] = await this.keyService.makeKeyPair(orgKey); - const collection = await this.encryptService.encrypt( + const collection = await this.encryptService.encryptString( this.i18nService.t("defaultCollection"), orgKey, ); diff --git a/apps/web/src/app/auth/recover-delete.component.ts b/apps/web/src/app/auth/recover-delete.component.ts index 6b45421911d..7381d526879 100644 --- a/apps/web/src/app/auth/recover-delete.component.ts +++ b/apps/web/src/app/auth/recover-delete.component.ts @@ -13,6 +13,7 @@ import { ToastService } from "@bitwarden/components"; @Component({ selector: "app-recover-delete", templateUrl: "recover-delete.component.html", + standalone: false, }) export class RecoverDeleteComponent { protected recoverDeleteForm = new FormGroup({ diff --git a/apps/web/src/app/auth/recover-two-factor.component.spec.ts b/apps/web/src/app/auth/recover-two-factor.component.spec.ts index bf6d47e09e5..5977d994521 100644 --- a/apps/web/src/app/auth/recover-two-factor.component.spec.ts +++ b/apps/web/src/app/auth/recover-two-factor.component.spec.ts @@ -16,7 +16,6 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl import { ToastService } from "@bitwarden/components"; import { KeyService } from "@bitwarden/key-management"; import { I18nPipe } from "@bitwarden/ui-common"; -import { NewDeviceVerificationNoticeService } from "@bitwarden/vault"; import { RecoverTwoFactorComponent } from "./recover-two-factor.component"; @@ -35,7 +34,6 @@ describe("RecoverTwoFactorComponent", () => { let mockConfigService: MockProxy; let mockLoginSuccessHandlerService: MockProxy; let mockLogService: MockProxy; - let mockNewDeviceVerificationNoticeService: MockProxy; beforeEach(() => { mockRouter = mock(); @@ -48,7 +46,6 @@ describe("RecoverTwoFactorComponent", () => { mockConfigService = mock(); mockLoginSuccessHandlerService = mock(); mockLogService = mock(); - mockNewDeviceVerificationNoticeService = mock(); TestBed.configureTestingModule({ declarations: [RecoverTwoFactorComponent], @@ -63,10 +60,6 @@ describe("RecoverTwoFactorComponent", () => { { provide: ConfigService, useValue: mockConfigService }, { provide: LoginSuccessHandlerService, useValue: mockLoginSuccessHandlerService }, { provide: LogService, useValue: mockLogService }, - { - provide: NewDeviceVerificationNoticeService, - useValue: mockNewDeviceVerificationNoticeService, - }, ], imports: [I18nPipe], // FIXME(PM-18598): Replace unknownElements and unknownProperties with actual imports @@ -102,9 +95,6 @@ describe("RecoverTwoFactorComponent", () => { title: "", message: mockI18nService.t("youHaveBeenLoggedIn"), }); - expect( - mockNewDeviceVerificationNoticeService.updateNewDeviceVerificationSkipNoticeState, - ).toHaveBeenCalledWith(authResult.userId, true); expect(mockRouter.navigate).toHaveBeenCalledWith(["/settings/security/two-factor"]); }); diff --git a/apps/web/src/app/auth/recover-two-factor.component.ts b/apps/web/src/app/auth/recover-two-factor.component.ts index 35aa1aab7c1..a69da0a66bf 100644 --- a/apps/web/src/app/auth/recover-two-factor.component.ts +++ b/apps/web/src/app/auth/recover-two-factor.component.ts @@ -12,11 +12,11 @@ import { TokenTwoFactorRequest } from "@bitwarden/common/auth/models/request/ide import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { ToastService } from "@bitwarden/components"; -import { NewDeviceVerificationNoticeService } from "@bitwarden/vault"; @Component({ selector: "app-recover-two-factor", templateUrl: "recover-two-factor.component.html", + standalone: false, }) export class RecoverTwoFactorComponent implements OnInit { protected formGroup = new FormGroup({ @@ -37,7 +37,6 @@ export class RecoverTwoFactorComponent implements OnInit { private toastService: ToastService, private loginSuccessHandlerService: LoginSuccessHandlerService, private logService: LogService, - private newDeviceVerificationNoticeService: NewDeviceVerificationNoticeService, ) {} async ngOnInit() { @@ -82,12 +81,7 @@ export class RecoverTwoFactorComponent implements OnInit { remember: false, }; - const credentials = new PasswordLoginCredentials( - email, - this.masterPassword, - "", - twoFactorRequest, - ); + const credentials = new PasswordLoginCredentials(email, this.masterPassword, twoFactorRequest); try { const authResult = await this.loginStrategyService.logIn(credentials); @@ -104,13 +98,6 @@ export class RecoverTwoFactorComponent implements OnInit { await this.loginSuccessHandlerService.run(authResult.userId); - // Before routing, set the state to skip the new device notification. This is a temporary - // fix and will be cleaned up in PM-18485. - await this.newDeviceVerificationNoticeService.updateNewDeviceVerificationSkipNoticeState( - authResult.userId, - true, - ); - await this.router.navigate(["/settings/security/two-factor"]); } catch (error) { // If login errors, redirect to login page per product. Don't show error diff --git a/apps/web/src/app/auth/set-password.component.ts b/apps/web/src/app/auth/set-password.component.ts index ccd329dd640..e297426f2c1 100644 --- a/apps/web/src/app/auth/set-password.component.ts +++ b/apps/web/src/app/auth/set-password.component.ts @@ -11,6 +11,7 @@ import { AcceptOrganizationInviteService } from "./organization-invite/accept-or @Component({ selector: "app-set-password", templateUrl: "set-password.component.html", + standalone: false, }) export class SetPasswordComponent extends BaseSetPasswordComponent { routerService = inject(RouterService); diff --git a/apps/web/src/app/auth/settings/account/account.component.html b/apps/web/src/app/auth/settings/account/account.component.html index c5edc021614..74fa02f5f93 100644 --- a/apps/web/src/app/auth/settings/account/account.component.html +++ b/apps/web/src/app/auth/settings/account/account.component.html @@ -51,7 +51,4 @@ {{ "deleteAccount" | i18n }} - - - diff --git a/apps/web/src/app/auth/settings/account/account.component.ts b/apps/web/src/app/auth/settings/account/account.component.ts index 37bf535062f..c06df56e386 100644 --- a/apps/web/src/app/auth/settings/account/account.component.ts +++ b/apps/web/src/app/auth/settings/account/account.component.ts @@ -1,32 +1,34 @@ import { Component, OnInit, OnDestroy } from "@angular/core"; -import { - combineLatest, - firstValueFrom, - from, - lastValueFrom, - map, - Observable, - Subject, - takeUntil, -} from "rxjs"; +import { firstValueFrom, from, lastValueFrom, map, Observable, Subject, takeUntil } from "rxjs"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { getUserId } from "@bitwarden/common/auth/services/account.service"; -import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { DialogService } from "@bitwarden/components"; +import { HeaderModule } from "../../../layouts/header/header.module"; +import { SharedModule } from "../../../shared"; import { PurgeVaultComponent } from "../../../vault/settings/purge-vault.component"; +import { ChangeEmailComponent } from "./change-email.component"; +import { DangerZoneComponent } from "./danger-zone.component"; import { DeauthorizeSessionsComponent } from "./deauthorize-sessions.component"; import { DeleteAccountDialogComponent } from "./delete-account-dialog.component"; +import { ProfileComponent } from "./profile.component"; import { SetAccountVerifyDevicesDialogComponent } from "./set-account-verify-devices-dialog.component"; @Component({ - selector: "app-account", templateUrl: "account.component.html", + standalone: true, + imports: [ + SharedModule, + HeaderModule, + ProfileComponent, + ChangeEmailComponent, + DangerZoneComponent, + ], }) export class AccountComponent implements OnInit, OnDestroy { private destroy$ = new Subject(); @@ -47,10 +49,6 @@ export class AccountComponent implements OnInit, OnDestroy { async ngOnInit() { const userId = await firstValueFrom(getUserId(this.accountService.activeAccount$)); - const isAccountDeprovisioningEnabled$ = this.configService.getFeatureFlag$( - FeatureFlag.AccountDeprovisioning, - ); - const userIsManagedByOrganization$ = this.organizationService .organizations$(userId) .pipe( @@ -61,25 +59,14 @@ export class AccountComponent implements OnInit, OnDestroy { this.showChangeEmail$ = hasMasterPassword$; - this.showPurgeVault$ = combineLatest([ - isAccountDeprovisioningEnabled$, - userIsManagedByOrganization$, - ]).pipe( - map( - ([isAccountDeprovisioningEnabled, userIsManagedByOrganization]) => - !isAccountDeprovisioningEnabled || !userIsManagedByOrganization, - ), + this.showPurgeVault$ = userIsManagedByOrganization$.pipe( + map((userIsManagedByOrganization) => !userIsManagedByOrganization), ); - this.showDeleteAccount$ = combineLatest([ - isAccountDeprovisioningEnabled$, - userIsManagedByOrganization$, - ]).pipe( - map( - ([isAccountDeprovisioningEnabled, userIsManagedByOrganization]) => - !isAccountDeprovisioningEnabled || !userIsManagedByOrganization, - ), + this.showDeleteAccount$ = userIsManagedByOrganization$.pipe( + map((userIsManagedByOrganization) => !userIsManagedByOrganization), ); + this.accountService.accountVerifyNewDeviceLogin$ .pipe(takeUntil(this.destroy$)) .subscribe((verifyDevices) => { diff --git a/apps/web/src/app/auth/settings/account/change-avatar-dialog.component.ts b/apps/web/src/app/auth/settings/account/change-avatar-dialog.component.ts index ba2a34c7143..80fdb20954f 100644 --- a/apps/web/src/app/auth/settings/account/change-avatar-dialog.component.ts +++ b/apps/web/src/app/auth/settings/account/change-avatar-dialog.component.ts @@ -24,6 +24,10 @@ import { ToastService, } from "@bitwarden/components"; +import { SharedModule } from "../../../shared"; + +import { SelectableAvatarComponent } from "./selectable-avatar.component"; + type ChangeAvatarDialogData = { profile: ProfileResponse; }; @@ -31,6 +35,8 @@ type ChangeAvatarDialogData = { @Component({ templateUrl: "change-avatar-dialog.component.html", encapsulation: ViewEncapsulation.None, + standalone: true, + imports: [SharedModule, SelectableAvatarComponent], }) export class ChangeAvatarDialogComponent implements OnInit, OnDestroy { profile: ProfileResponse; diff --git a/apps/web/src/app/auth/settings/account/change-email.component.spec.ts b/apps/web/src/app/auth/settings/account/change-email.component.spec.ts index 838a50b5c2e..f5c0733e5b0 100644 --- a/apps/web/src/app/auth/settings/account/change-email.component.spec.ts +++ b/apps/web/src/app/auth/settings/account/change-email.component.spec.ts @@ -33,8 +33,7 @@ describe("ChangeEmailComponent", () => { accountService = mockAccountServiceWith("UserId" as UserId); await TestBed.configureTestingModule({ - declarations: [ChangeEmailComponent], - imports: [ReactiveFormsModule, SharedModule], + imports: [ReactiveFormsModule, SharedModule, ChangeEmailComponent], providers: [ { provide: AccountService, useValue: accountService }, { provide: ApiService, useValue: apiService }, diff --git a/apps/web/src/app/auth/settings/account/change-email.component.ts b/apps/web/src/app/auth/settings/account/change-email.component.ts index caf7e0933b0..98f704d6044 100644 --- a/apps/web/src/app/auth/settings/account/change-email.component.ts +++ b/apps/web/src/app/auth/settings/account/change-email.component.ts @@ -14,9 +14,13 @@ import { UserId } from "@bitwarden/common/types/guid"; import { ToastService } from "@bitwarden/components"; import { KdfConfigService, KeyService } from "@bitwarden/key-management"; +import { SharedModule } from "../../../shared"; + @Component({ selector: "app-change-email", templateUrl: "change-email.component.html", + standalone: true, + imports: [SharedModule], }) export class ChangeEmailComponent implements OnInit { tokenSent = false; diff --git a/apps/web/src/app/auth/settings/account/danger-zone.component.ts b/apps/web/src/app/auth/settings/account/danger-zone.component.ts index 1abea314b50..e07b6e6b8db 100644 --- a/apps/web/src/app/auth/settings/account/danger-zone.component.ts +++ b/apps/web/src/app/auth/settings/account/danger-zone.component.ts @@ -1,13 +1,10 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore import { CommonModule } from "@angular/common"; -import { Component, OnInit } from "@angular/core"; -import { Observable } from "rxjs"; +import { Component } from "@angular/core"; -import { JslibModule } from "@bitwarden/angular/jslib.module"; -import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; -import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { TypographyModule } from "@bitwarden/components"; +import { I18nPipe } from "@bitwarden/ui-common"; /** * Component for the Danger Zone section of the Account/Organization Settings page. @@ -16,15 +13,6 @@ import { TypographyModule } from "@bitwarden/components"; selector: "app-danger-zone", templateUrl: "danger-zone.component.html", standalone: true, - imports: [TypographyModule, JslibModule, CommonModule], + imports: [CommonModule, TypographyModule, I18nPipe], }) -export class DangerZoneComponent implements OnInit { - constructor(private configService: ConfigService) {} - accountDeprovisioningEnabled$: Observable; - - ngOnInit(): void { - this.accountDeprovisioningEnabled$ = this.configService.getFeatureFlag$( - FeatureFlag.AccountDeprovisioning, - ); - } -} +export class DangerZoneComponent {} diff --git a/apps/web/src/app/auth/settings/account/deauthorize-sessions.component.ts b/apps/web/src/app/auth/settings/account/deauthorize-sessions.component.ts index a7c466d4ffc..a48e968ab3e 100644 --- a/apps/web/src/app/auth/settings/account/deauthorize-sessions.component.ts +++ b/apps/web/src/app/auth/settings/account/deauthorize-sessions.component.ts @@ -1,6 +1,7 @@ import { Component } from "@angular/core"; import { FormBuilder } from "@angular/forms"; +import { UserVerificationFormInputComponent } from "@bitwarden/auth/angular"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { Verification } from "@bitwarden/common/auth/types/verification"; @@ -9,9 +10,12 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { DialogService, ToastService } from "@bitwarden/components"; +import { SharedModule } from "../../../shared"; + @Component({ - selector: "app-deauthorize-sessions", templateUrl: "deauthorize-sessions.component.html", + standalone: true, + imports: [SharedModule, UserVerificationFormInputComponent], }) export class DeauthorizeSessionsComponent { deauthForm = this.formBuilder.group({ diff --git a/apps/web/src/app/auth/settings/account/delete-account-dialog.component.ts b/apps/web/src/app/auth/settings/account/delete-account-dialog.component.ts index 07e6052e0a1..0fc2276b779 100644 --- a/apps/web/src/app/auth/settings/account/delete-account-dialog.component.ts +++ b/apps/web/src/app/auth/settings/account/delete-account-dialog.component.ts @@ -3,14 +3,19 @@ import { Component } from "@angular/core"; import { FormBuilder } from "@angular/forms"; +import { UserVerificationFormInputComponent } from "@bitwarden/auth/angular"; import { AccountApiService } from "@bitwarden/common/auth/abstractions/account-api.service"; import { Verification } from "@bitwarden/common/auth/types/verification"; import { ErrorResponse } from "@bitwarden/common/models/response/error.response"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { DialogRef, DialogService, ToastService } from "@bitwarden/components"; +import { SharedModule } from "../../../shared"; + @Component({ templateUrl: "delete-account-dialog.component.html", + standalone: true, + imports: [SharedModule, UserVerificationFormInputComponent], }) export class DeleteAccountDialogComponent { deleteForm = this.formBuilder.group({ diff --git a/apps/web/src/app/auth/settings/account/profile.component.ts b/apps/web/src/app/auth/settings/account/profile.component.ts index 72731363806..a33efd742aa 100644 --- a/apps/web/src/app/auth/settings/account/profile.component.ts +++ b/apps/web/src/app/auth/settings/account/profile.component.ts @@ -2,7 +2,7 @@ // @ts-strict-ignore import { Component, OnDestroy, OnInit } from "@angular/core"; import { FormControl, FormGroup } from "@angular/forms"; -import { firstValueFrom, map, Observable, of, Subject, switchMap, takeUntil } from "rxjs"; +import { firstValueFrom, map, Observable, Subject, takeUntil } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; @@ -10,17 +10,21 @@ import { Organization } from "@bitwarden/common/admin-console/models/domain/orga import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { UpdateProfileRequest } from "@bitwarden/common/auth/models/request/update-profile.request"; import { getUserId } from "@bitwarden/common/auth/services/account.service"; -import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ProfileResponse } from "@bitwarden/common/models/response/profile.response"; -import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { DialogService, ToastService } from "@bitwarden/components"; +import { DynamicAvatarComponent } from "../../../components/dynamic-avatar.component"; +import { SharedModule } from "../../../shared"; +import { AccountFingerprintComponent } from "../../../shared/components/account-fingerprint/account-fingerprint.component"; + import { ChangeAvatarDialogComponent } from "./change-avatar-dialog.component"; @Component({ selector: "app-profile", templateUrl: "profile.component.html", + standalone: true, + imports: [SharedModule, DynamicAvatarComponent, AccountFingerprintComponent], }) export class ProfileComponent implements OnInit, OnDestroy { loading = true; @@ -40,7 +44,6 @@ export class ProfileComponent implements OnInit, OnDestroy { private accountService: AccountService, private dialogService: DialogService, private toastService: ToastService, - private configService: ConfigService, private organizationService: OrganizationService, ) {} @@ -53,21 +56,12 @@ export class ProfileComponent implements OnInit, OnDestroy { const userId = await firstValueFrom(getUserId(this.accountService.activeAccount$)); - this.managingOrganization$ = this.configService - .getFeatureFlag$(FeatureFlag.AccountDeprovisioning) + this.managingOrganization$ = this.organizationService + .organizations$(userId) .pipe( - switchMap((isAccountDeprovisioningEnabled) => - isAccountDeprovisioningEnabled - ? this.organizationService - .organizations$(userId) - .pipe( - map((organizations) => - organizations.find((o) => o.userIsManagedByOrganization === true), - ), - ) - : of(null), - ), + map((organizations) => organizations.find((o) => o.userIsManagedByOrganization === true)), ); + this.formGroup.get("name").setValue(this.profile.name); this.formGroup.get("email").setValue(this.profile.email); diff --git a/apps/web/src/app/components/selectable-avatar.component.ts b/apps/web/src/app/auth/settings/account/selectable-avatar.component.ts similarity index 90% rename from apps/web/src/app/components/selectable-avatar.component.ts rename to apps/web/src/app/auth/settings/account/selectable-avatar.component.ts index 7a746481563..a53e3990090 100644 --- a/apps/web/src/app/components/selectable-avatar.component.ts +++ b/apps/web/src/app/auth/settings/account/selectable-avatar.component.ts @@ -1,7 +1,10 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore +import { NgClass } from "@angular/common"; import { Component, EventEmitter, Input, Output } from "@angular/core"; +import { AvatarModule } from "@bitwarden/components"; + @Component({ selector: "selectable-avatar", template: ` `, + standalone: true, + imports: [NgClass, AvatarModule], }) export class SelectableAvatarComponent { @Input() id: string; diff --git a/apps/web/src/app/auth/settings/change-password.component.ts b/apps/web/src/app/auth/settings/change-password.component.ts index ffa5247ad08..1d95a498694 100644 --- a/apps/web/src/app/auth/settings/change-password.component.ts +++ b/apps/web/src/app/auth/settings/change-password.component.ts @@ -29,9 +29,13 @@ import { KdfConfigService, KeyService } from "@bitwarden/key-management"; import { UserKeyRotationService } from "../../key-management/key-rotation/user-key-rotation.service"; +/** + * @deprecated use the auth `PasswordSettingsComponent` instead + */ @Component({ selector: "app-change-password", templateUrl: "change-password.component.html", + standalone: false, }) export class ChangePasswordComponent extends BaseChangePasswordComponent @@ -131,7 +135,7 @@ export class ChangePasswordComponent content: this.i18nService.t("updateEncryptionKeyWarning") + " " + - this.i18nService.t("updateEncryptionKeyExportWarning") + + this.i18nService.t("updateEncryptionKeyAccountExportWarning") + " " + this.i18nService.t("rotateEncKeyConfirmation"), type: "warning", diff --git a/apps/web/src/app/auth/settings/emergency-access/confirm/emergency-access-confirm.component.ts b/apps/web/src/app/auth/settings/emergency-access/confirm/emergency-access-confirm.component.ts index f3fd19a4e8b..cd7a585f3b1 100644 --- a/apps/web/src/app/auth/settings/emergency-access/confirm/emergency-access-confirm.component.ts +++ b/apps/web/src/app/auth/settings/emergency-access/confirm/emergency-access-confirm.component.ts @@ -8,6 +8,8 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { DialogConfig, DialogRef, DIALOG_DATA, DialogService } from "@bitwarden/components"; import { KeyService } from "@bitwarden/key-management"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum EmergencyAccessConfirmDialogResult { Confirmed = "confirmed", } @@ -24,6 +26,7 @@ type EmergencyAccessConfirmDialogData = { @Component({ selector: "emergency-access-confirm", templateUrl: "emergency-access-confirm.component.html", + standalone: false, }) export class EmergencyAccessConfirmComponent implements OnInit { loading = true; diff --git a/apps/web/src/app/auth/settings/emergency-access/emergency-access-add-edit.component.ts b/apps/web/src/app/auth/settings/emergency-access/emergency-access-add-edit.component.ts index cf52969c244..2f3f3a20b04 100644 --- a/apps/web/src/app/auth/settings/emergency-access/emergency-access-add-edit.component.ts +++ b/apps/web/src/app/auth/settings/emergency-access/emergency-access-add-edit.component.ts @@ -26,6 +26,8 @@ export type EmergencyAccessAddEditDialogData = { readOnly: boolean; }; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum EmergencyAccessAddEditDialogResult { Saved = "saved", Canceled = "canceled", @@ -34,6 +36,7 @@ export enum EmergencyAccessAddEditDialogResult { @Component({ selector: "emergency-access-add-edit", templateUrl: "emergency-access-add-edit.component.html", + standalone: false, }) export class EmergencyAccessAddEditComponent implements OnInit { loading = true; diff --git a/apps/web/src/app/auth/settings/emergency-access/emergency-access.component.html b/apps/web/src/app/auth/settings/emergency-access/emergency-access.component.html index ab93f0be3bc..8a802e4f6af 100644 --- a/apps/web/src/app/auth/settings/emergency-access/emergency-access.component.html +++ b/apps/web/src/app/auth/settings/emergency-access/emergency-access.component.html @@ -272,7 +272,3 @@ - - - - diff --git a/apps/web/src/app/auth/settings/emergency-access/emergency-access.component.ts b/apps/web/src/app/auth/settings/emergency-access/emergency-access.component.ts index dc464c18059..23bf0c22bc7 100644 --- a/apps/web/src/app/auth/settings/emergency-access/emergency-access.component.ts +++ b/apps/web/src/app/auth/settings/emergency-access/emergency-access.component.ts @@ -1,6 +1,6 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { Component, OnInit, ViewChild, ViewContainerRef } from "@angular/core"; +import { Component, OnInit } from "@angular/core"; import { lastValueFrom, Observable, firstValueFrom, switchMap } from "rxjs"; import { UserNamePipe } from "@bitwarden/angular/pipes/user-name.pipe"; @@ -42,14 +42,9 @@ import { @Component({ selector: "emergency-access", templateUrl: "emergency-access.component.html", + standalone: false, }) export class EmergencyAccessComponent implements OnInit { - @ViewChild("addEdit", { read: ViewContainerRef, static: true }) addEditModalRef: ViewContainerRef; - @ViewChild("takeoverTemplate", { read: ViewContainerRef, static: true }) - takeoverModalRef: ViewContainerRef; - @ViewChild("confirmTemplate", { read: ViewContainerRef, static: true }) - confirmModalRef: ViewContainerRef; - loaded = false; canAccessPremium$: Observable; trustedContacts: GranteeEmergencyAccess[]; diff --git a/apps/web/src/app/auth/settings/emergency-access/takeover/emergency-access-takeover.component.ts b/apps/web/src/app/auth/settings/emergency-access/takeover/emergency-access-takeover.component.ts index c80f82ae126..d683545db59 100644 --- a/apps/web/src/app/auth/settings/emergency-access/takeover/emergency-access-takeover.component.ts +++ b/apps/web/src/app/auth/settings/emergency-access/takeover/emergency-access-takeover.component.ts @@ -24,6 +24,8 @@ import { KdfType, KdfConfigService, KeyService } from "@bitwarden/key-management import { EmergencyAccessService } from "../../../emergency-access"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum EmergencyAccessTakeoverResultType { Done = "done", } @@ -38,6 +40,7 @@ type EmergencyAccessTakeoverDialogData = { @Component({ selector: "emergency-access-takeover", templateUrl: "emergency-access-takeover.component.html", + standalone: false, }) export class EmergencyAccessTakeoverComponent extends ChangePasswordComponent diff --git a/apps/web/src/app/auth/settings/emergency-access/view/emergency-access-view.component.html b/apps/web/src/app/auth/settings/emergency-access/view/emergency-access-view.component.html index 87e2643c178..20cc50c4d59 100644 --- a/apps/web/src/app/auth/settings/emergency-access/view/emergency-access-view.component.html +++ b/apps/web/src/app/auth/settings/emergency-access/view/emergency-access-view.component.html @@ -19,7 +19,7 @@ >