diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 9a9749e69ef..7b6d24aa8c0 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -29,12 +29,12 @@ 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 -## Localization/Crowdin (Tools team) -apps/browser/src/_locales @bitwarden/team-tools-dev -apps/browser/store/locales @bitwarden/team-tools-dev -apps/cli/src/locales @bitwarden/team-tools-dev -apps/desktop/src/locales @bitwarden/team-tools-dev -apps/web/src/locales @bitwarden/team-tools-dev +## Localization/Crowdin (Platform and Tools team) +apps/browser/src/_locales @bitwarden/team-tools-dev @bitwarden/team-platform-dev +apps/browser/store/locales @bitwarden/team-tools-dev @bitwarden/team-platform-dev +apps/cli/src/locales @bitwarden/team-tools-dev @bitwarden/team-platform-dev +apps/desktop/src/locales @bitwarden/team-tools-dev @bitwarden/team-platform-dev +apps/web/src/locales @bitwarden/team-tools-dev @bitwarden/team-platform-dev ## Vault team files ## apps/browser/src/vault @bitwarden/team-vault-dev @@ -86,9 +86,13 @@ apps/web/src/app/shared @bitwarden/team-platform-dev apps/web/src/translation-constants.ts @bitwarden/team-platform-dev # Workflows .github/workflows/brew-bump-desktop.yml @bitwarden/team-platform-dev +.github/workflows/build-browser-target.yml @bitwarden/team-platform-dev .github/workflows/build-browser.yml @bitwarden/team-platform-dev +.github/workflows/build-cli-target.yml @bitwarden/team-platform-dev .github/workflows/build-cli.yml @bitwarden/team-platform-dev +.github/workflows/build-desktop-target.yml @bitwarden/team-platform-dev .github/workflows/build-desktop.yml @bitwarden/team-platform-dev +.github/workflows/build-web-target.yml @bitwarden/team-platform-dev .github/workflows/build-web.yml @bitwarden/team-platform-dev .github/workflows/chromatic.yml @bitwarden/team-platform-dev .github/workflows/lint.yml @bitwarden/team-platform-dev @@ -97,25 +101,28 @@ apps/web/src/translation-constants.ts @bitwarden/team-platform-dev .github/workflows/scan.yml @bitwarden/team-platform-dev .github/workflows/test.yml @bitwarden/team-platform-dev .github/workflows/version-auto-bump.yml @bitwarden/team-platform-dev +# ESLint custom rules +libs/eslint @bitwarden/team-platform-dev ## Autofill team files ## apps/browser/src/autofill @bitwarden/team-autofill-dev apps/desktop/src/autofill @bitwarden/team-autofill-dev libs/common/src/autofill @bitwarden/team-autofill-dev apps/desktop/macos/autofill-extension @bitwarden/team-autofill-dev +apps/desktop/desktop_native/windows-plugin-authenticator @bitwarden/team-autofill-dev # DuckDuckGo integration apps/desktop/native-messaging-test-runner @bitwarden/team-autofill-dev apps/desktop/src/services/duckduckgo-message-handler.service.ts @bitwarden/team-autofill-dev # SSH Agent apps/desktop/desktop_native/core/src/ssh_agent @bitwarden/team-autofill-dev @bitwarden/wg-ssh-keys -## Component Library ## -.storybook @bitwarden/team-design-system -libs/components @bitwarden/team-design-system -libs/ui @bitwarden/team-design-system -apps/browser/src/platform/popup/layout @bitwarden/team-design-system -apps/browser/src/popup/app-routing.animations.ts @bitwarden/team-design-system -apps/web/src/app/layouts @bitwarden/team-design-system +## UI Foundation ## +.storybook @bitwarden/team-ui-foundation +libs/components @bitwarden/team-ui-foundation +libs/ui @bitwarden/team-ui-foundation +apps/browser/src/platform/popup/layout @bitwarden/team-ui-foundation +apps/browser/src/popup/app-routing.animations.ts @bitwarden/team-ui-foundation +apps/web/src/app/layouts @bitwarden/team-ui-foundation ## Desktop native module ## apps/desktop/desktop_native @bitwarden/team-platform-dev @@ -128,9 +135,10 @@ apps/web/src/app/key-management @bitwarden/team-key-management-dev apps/browser/src/key-management @bitwarden/team-key-management-dev apps/cli/src/key-management @bitwarden/team-key-management-dev libs/key-management @bitwarden/team-key-management-dev +libs/key-management-ui @bitwarden/team-key-management-dev libs/common/src/key-management @bitwarden/team-key-management-dev -apps/desktop/destkop_native/core/src/biometric/ @bitwarden/team-key-management-dev +apps/desktop/desktop_native/core/src/biometric/ @bitwarden/team-key-management-dev apps/desktop/src/services/native-messaging.service.ts @bitwarden/team-key-management-dev apps/browser/src/background/nativeMessaging.background.ts @bitwarden/team-key-management-dev apps/desktop/src/services/biometric-message-handler.service.ts @bitwarden/team-key-management-dev diff --git a/.github/codecov.yml b/.github/codecov.yml index b4774407206..0a6b3ceacff 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -1,2 +1,66 @@ ignore: - "**/*.spec.ts" # Tests + +component_management: + default_rules: + statuses: + - type: project + target: auto + individual_components: + - component_id: key-management-biometrics + name: Key Management - Biometrics + paths: + - apps/browser/src/key-management/biometrics/** + - apps/cli/src/key-management/cli-biometrics-service.ts + - apps/desktop/destkop_native/core/src/biometric/** + - apps/desktop/src/key-management/biometrics/** + - apps/desktop/src/services/biometric-message-handler.service.ts + - apps/web/src/app/key-management/web-biometric.service.ts + - libs/key-management/src/biometrics/** + - component_id: key-management-lock + name: Key Management - Lock + paths: + - apps/browser/src/key-management/lock/** + - apps/desktop/src/key-management/lock/** + - apps/web/src/app/key-management/lock/** + - libs/key-management-ui/src/lock/** + - component_id: key-management-ipc + name: Key Management - IPC + paths: + - apps/browser/src/background/nativeMessaging.background.ts + - apps/desktop/src/services/native-messaging.service.ts + - component_id: key-management-key-rotation + name: Key Management - Key Rotation + paths: + - apps/web/src/app/key-management/key-rotation/** + - apps/web/src/app/key-management/migrate-encryption/** + - libs/key-management/src/user-asymmetric-key-regeneration/** + - component_id: key-management-process-reload + name: Key Management - Process Reload + paths: + - apps/web/src/app/key-management/services/web-process-reload.service.ts + - libs/common/src/key-management/services/default-process-reload.service.ts + - component_id: key-management-keys + name: Key Management - Keys + paths: + - libs/key-management/src/kdf-config.service.ts + - libs/key-management/src/key.service.ts + - libs/common/src/key-management/master-password/** + - component_id: key-management-crypto + name: Key Management - Crypto + paths: + - libs/common/src/key-management/crypto/** + - component_id: key-management + name: Key Management + paths: + - apps/browser/src/key-management/** + - apps/browser/src/background/nativeMessaging.background.ts + - apps/cli/src/key-management/** + - apps/desktop/desktop_native/core/src/biometric/** + - apps/desktop/src/key-management/** + - apps/desktop/src/services/biometric-message-handler.service.ts + - apps/desktop/src/services/native-messaging.service.ts + - apps/web/src/app/key-management/** + - libs/common/src/key-management/** + - libs/key-management/** + - libs/key-management-ui/** diff --git a/.github/renovate.json b/.github/renovate.json index 9afe308b329..f1efcbaffbe 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -211,6 +211,8 @@ "@storybook/angular", "@storybook/manager-api", "@storybook/theming", + "@typescript-eslint/utils", + "@typescript-eslint/rule-tester", "@types/react", "autoprefixer", "bootstrap", @@ -225,9 +227,9 @@ "tailwindcss", "zone.js" ], - "description": "Component library owned dependencies", - "commitMessagePrefix": "[deps] Design System:", - "reviewers": ["team:team-design-system"] + "description": "UI Foundation owned dependencies", + "commitMessagePrefix": "[deps] UI Foundation:", + "reviewers": ["team:team-ui-foundation"] }, { "matchPackageNames": [ diff --git a/.github/workflows/build-browser-target.yml b/.github/workflows/build-browser-target.yml new file mode 100644 index 00000000000..3334326920c --- /dev/null +++ b/.github/workflows/build-browser-target.yml @@ -0,0 +1,33 @@ +name: Build Browser on PR Target + +on: + pull_request: + types: [opened, synchronize] + branches-ignore: + - 'l10n_master' + - 'cf-pages' + paths: + - 'apps/browser/**' + - 'libs/**' + - '*' + - '!*.md' + - '!*.txt' + workflow_call: + inputs: {} + +defaults: + run: + shell: bash + +jobs: + check-run: + name: Check PR run + uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main + + run-workflow: + name: Run Build Browser on PR Target + needs: check-run + if: ${{ github.event.pull_request.head.repo.full_name != github.repository }} + uses: ./.github/workflows/build-browser.yml + secrets: inherit + diff --git a/.github/workflows/build-browser.yml b/.github/workflows/build-browser.yml index c9e9f588c83..b9a26f68eeb 100644 --- a/.github/workflows/build-browser.yml +++ b/.github/workflows/build-browser.yml @@ -1,7 +1,7 @@ name: Build Browser on: - pull_request_target: + pull_request: types: [opened, synchronize] branches-ignore: - 'l10n_master' @@ -38,19 +38,14 @@ defaults: shell: bash jobs: - check-run: - name: Check PR run - uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main - setup: name: Setup runs-on: ubuntu-22.04 - needs: - - check-run outputs: repo_url: ${{ steps.gen_vars.outputs.repo_url }} adj_build_number: ${{ steps.gen_vars.outputs.adj_build_number }} node_version: ${{ steps.retrieve-node-version.outputs.node_version }} + has_secrets: ${{ steps.check-secrets.outputs.has_secrets }} steps: - name: Check out repo uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -74,6 +69,14 @@ jobs: NODE_VERSION=${NODE_NVMRC/v/''} echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT + - name: Check secrets + id: check-secrets + env: + AZURE_KV_CI_SERVICE_PRINCIPAL: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} + run: | + has_secrets=${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL != '' }} + echo "has_secrets=$has_secrets" >> $GITHUB_OUTPUT + locales-test: name: Locales Test @@ -197,22 +200,14 @@ jobs: npm_command: "dist:edge" archive_name: "dist-edge.zip" artifact_name: "dist-edge-MV3" - - name: "firefox" - npm_command: "dist:firefox" - archive_name: "dist-firefox.zip" - artifact_name: "dist-firefox" - name: "firefox-mv3" npm_command: "dist:firefox:mv3" archive_name: "dist-firefox.zip" - artifact_name: "DO-NOT-USE-FOR-PROD-dist-firefox-MV3" - - name: "opera" - npm_command: "dist:opera" - archive_name: "dist-opera.zip" - artifact_name: "dist-opera" + artifact_name: "dist-firefox-MV3" - name: "opera-mv3" npm_command: "dist:opera:mv3" archive_name: "dist-opera.zip" - artifact_name: "DO-NOT-USE-FOR-PROD-dist-opera-MV3" + artifact_name: "dist-opera-MV3" steps: - name: Check out repo uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -281,6 +276,7 @@ jobs: needs: - setup - locales-test + if: ${{ needs.setup.outputs.has_secrets == 'true' }} env: _BUILD_NUMBER: ${{ needs.setup.outputs.adj_build_number }} _NODE_VERSION: ${{ needs.setup.outputs.node_version }} diff --git a/.github/workflows/build-cli-target.yml b/.github/workflows/build-cli-target.yml new file mode 100644 index 00000000000..81ec4178681 --- /dev/null +++ b/.github/workflows/build-cli-target.yml @@ -0,0 +1,33 @@ +name: Build CLI on PR Target + +on: + pull_request: + types: [opened, synchronize] + branches-ignore: + - 'l10n_master' + - 'cf-pages' + paths: + - 'apps/cli/**' + - 'libs/**' + - '*' + - '!*.md' + - '!*.txt' + - '.github/workflows/build-cli.yml' + - 'bitwarden_license/bit-cli/**' + +defaults: + run: + shell: bash + +jobs: + check-run: + name: Check PR run + uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main + + run-workflow: + name: Run Build CLI on PR Target + needs: check-run + if: ${{ github.event.pull_request.head.repo.full_name != github.repository }} + uses: ./.github/workflows/build-cli.yml + secrets: inherit + diff --git a/.github/workflows/build-cli.yml b/.github/workflows/build-cli.yml index d5d78811cda..b3694ac423b 100644 --- a/.github/workflows/build-cli.yml +++ b/.github/workflows/build-cli.yml @@ -1,7 +1,7 @@ name: Build CLI on: - pull_request_target: + pull_request: types: [opened, synchronize] branches-ignore: - 'l10n_master' @@ -27,6 +27,8 @@ on: - '!*.txt' - '.github/workflows/build-cli.yml' - 'bitwarden_license/bit-cli/**' + workflow_call: + inputs: {} workflow_dispatch: inputs: sdk_branch: @@ -39,18 +41,13 @@ defaults: working-directory: apps/cli jobs: - check-run: - name: Check PR run - uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main - setup: name: Setup runs-on: ubuntu-22.04 - needs: - - check-run outputs: package_version: ${{ steps.retrieve-package-version.outputs.package_version }} node_version: ${{ steps.retrieve-node-version.outputs.node_version }} + has_secrets: ${{ steps.check-secrets.outputs.has_secrets }} steps: - name: Check out repo uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -71,6 +68,14 @@ jobs: NODE_VERSION=${NODE_NVMRC/v/''} echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT + - name: Check secrets + id: check-secrets + env: + AZURE_KV_CI_SERVICE_PRINCIPAL: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} + run: | + has_secrets=${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL != '' }} + echo "has_secrets=$has_secrets" >> $GITHUB_OUTPUT + cli: name: CLI ${{ matrix.os.base }} - ${{ matrix.license_type.readable }} strategy: @@ -117,7 +122,7 @@ jobs: working-directory: ./ - name: Download SDK Artifacts - if: ${{ inputs.sdk_branch != '' }} + if: ${{ inputs.sdk_branch != '' && needs.setup.outputs.has_secrets == 'true' }} uses: bitwarden/gh-actions/download-artifacts@main with: github_token: ${{secrets.GITHUB_TOKEN}} @@ -130,7 +135,7 @@ jobs: if_no_artifact_found: fail - name: Override SDK - if: ${{ inputs.sdk_branch != '' }} + if: ${{ inputs.sdk_branch != '' && needs.setup.outputs.has_secrets == 'true' }} working-directory: ./ run: | ls -l ../ @@ -272,7 +277,7 @@ jobs: working-directory: ./ - name: Download SDK Artifacts - if: ${{ inputs.sdk_branch != '' }} + if: ${{ inputs.sdk_branch != '' && needs.setup.outputs.has_secrets == 'true' }} uses: bitwarden/gh-actions/download-artifacts@main with: github_token: ${{secrets.GITHUB_TOKEN}} @@ -285,7 +290,7 @@ jobs: if_no_artifact_found: fail - name: Override SDK - if: ${{ inputs.sdk_branch != '' }} + if: ${{ inputs.sdk_branch != '' && needs.setup.outputs.has_secrets == 'true' }} working-directory: ./ run: | ls -l ../ diff --git a/.github/workflows/build-desktop-target.yml b/.github/workflows/build-desktop-target.yml new file mode 100644 index 00000000000..8c26f991174 --- /dev/null +++ b/.github/workflows/build-desktop-target.yml @@ -0,0 +1,32 @@ +name: Build Desktop on PR Target + +on: + pull_request: + types: [opened, synchronize] + branches-ignore: + - 'l10n_master' + - 'cf-pages' + paths: + - 'apps/desktop/**' + - 'libs/**' + - '*' + - '!*.md' + - '!*.txt' + - '.github/workflows/build-desktop.yml' + +defaults: + run: + shell: bash + +jobs: + check-run: + name: Check PR run + uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main + + run-workflow: + name: Run Build Desktop on PR Target + needs: check-run + if: ${{ github.event.pull_request.head.repo.full_name != github.repository }} + uses: ./.github/workflows/build-desktop.yml + secrets: inherit + diff --git a/.github/workflows/build-desktop.yml b/.github/workflows/build-desktop.yml index ca681dac6b0..23722e7c7df 100644 --- a/.github/workflows/build-desktop.yml +++ b/.github/workflows/build-desktop.yml @@ -1,7 +1,7 @@ name: Build Desktop on: - pull_request_target: + pull_request: types: [opened, synchronize] branches-ignore: - 'l10n_master' @@ -25,6 +25,8 @@ on: - '!*.md' - '!*.txt' - '.github/workflows/build-desktop.yml' + workflow_call: + inputs: {} workflow_dispatch: inputs: sdk_branch: @@ -37,15 +39,9 @@ defaults: shell: bash jobs: - check-run: - name: Check PR run - uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main - electron-verify: name: Verify Electron Version runs-on: ubuntu-22.04 - needs: - - check-run steps: - name: Check out repo uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -67,8 +63,6 @@ jobs: setup: name: Setup runs-on: ubuntu-22.04 - needs: - - check-run outputs: package_version: ${{ steps.retrieve-version.outputs.package_version }} release_channel: ${{ steps.release-channel.outputs.channel }} @@ -76,6 +70,7 @@ jobs: rc_branch_exists: ${{ steps.branch-check.outputs.rc_branch_exists }} hotfix_branch_exists: ${{ steps.branch-check.outputs.hotfix_branch_exists }} node_version: ${{ steps.retrieve-node-version.outputs.node_version }} + has_secrets: ${{ steps.check-secrets.outputs.has_secrets }} defaults: run: working-directory: apps/desktop @@ -138,6 +133,14 @@ jobs: NODE_VERSION=${NODE_NVMRC/v/''} echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT + - name: Check secrets + id: check-secrets + env: + AZURE_KV_CI_SERVICE_PRINCIPAL: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} + run: | + has_secrets=${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL != '' }} + echo "has_secrets=$has_secrets" >> $GITHUB_OUTPUT + linux: name: Linux Build # Note, before updating the ubuntu version of the workflow, ensure the snap base image @@ -333,12 +336,14 @@ jobs: rustup show - name: Login to Azure + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 with: creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} - name: Retrieve secrets id: retrieve-secrets + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: bitwarden/gh-actions/get-keyvault-secrets@main with: keyvault: "bitwarden-ci" @@ -353,7 +358,7 @@ jobs: working-directory: ./ - name: Download SDK Artifacts - if: ${{ inputs.sdk_branch != '' }} + if: ${{ inputs.sdk_branch != '' && needs.setup.outputs.has_secrets == 'true' }} uses: bitwarden/gh-actions/download-artifacts@main with: github_token: ${{secrets.GITHUB_TOKEN}} @@ -366,7 +371,7 @@ jobs: if_no_artifact_found: fail - name: Override SDK - if: ${{ inputs.sdk_branch != '' }} + if: ${{ inputs.sdk_branch != '' && needs.setup.outputs.has_secrets == 'true' }} working-directory: ./ run: | ls -l ../ @@ -386,7 +391,17 @@ jobs: working-directory: apps/desktop/desktop_native run: node build.js cross-platform - - name: Build & Sign (dev) + - name: Build + run: | + npm run build + + - name: Pack + if: ${{ needs.setup.outputs.has_secrets == 'false' }} + run: | + npm run pack:win + + - name: Pack & Sign (dev) + if: ${{ needs.setup.outputs.has_secrets == 'true' }} env: ELECTRON_BUILDER_SIGN: 1 SIGNING_VAULT_URL: ${{ steps.retrieve-secrets.outputs.code-signing-vault-url }} @@ -395,10 +410,10 @@ jobs: SIGNING_CLIENT_SECRET: ${{ steps.retrieve-secrets.outputs.code-signing-client-secret }} SIGNING_CERT_NAME: ${{ steps.retrieve-secrets.outputs.code-signing-cert-name }} run: | - npm run build npm run pack:win - name: Rename appx files for store + if: ${{ needs.setup.outputs.has_secrets == 'true' }} run: | Copy-Item "./dist/Bitwarden-${{ env._PACKAGE_VERSION }}-ia32.appx" ` -Destination "./dist/Bitwarden-${{ env._PACKAGE_VERSION }}-ia32-store.appx" @@ -408,6 +423,7 @@ jobs: -Destination "./dist/Bitwarden-${{ env._PACKAGE_VERSION }}-arm64-store.appx" - name: Package for Chocolatey + if: ${{ needs.setup.outputs.has_secrets == 'true' }} run: | Copy-Item -Path ./stores/chocolatey -Destination ./dist/chocolatey -Recurse Copy-Item -Path ./dist/nsis-web/Bitwarden-Installer-${{ env._PACKAGE_VERSION }}.exe ` @@ -419,6 +435,7 @@ jobs: choco pack ./dist/chocolatey/bitwarden.nuspec --version "$env:_PACKAGE_VERSION" --out ./dist/chocolatey - name: Fix NSIS artifact names for auto-updater + if: ${{ needs.setup.outputs.has_secrets == 'true' }} run: | Rename-Item -Path .\dist\nsis-web\Bitwarden-${{ env._PACKAGE_VERSION }}-ia32.nsis.7z ` -NewName bitwarden-${{ env._PACKAGE_VERSION }}-ia32.nsis.7z @@ -435,6 +452,7 @@ jobs: if-no-files-found: error - name: Upload installer exe artifact + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: name: Bitwarden-Installer-${{ env._PACKAGE_VERSION }}.exe @@ -442,6 +460,7 @@ jobs: if-no-files-found: error - name: Upload appx ia32 artifact + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-ia32.appx @@ -449,6 +468,7 @@ jobs: if-no-files-found: error - name: Upload store appx ia32 artifact + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-ia32-store.appx @@ -456,6 +476,7 @@ jobs: if-no-files-found: error - name: Upload NSIS ia32 artifact + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: name: bitwarden-${{ env._PACKAGE_VERSION }}-ia32.nsis.7z @@ -463,6 +484,7 @@ jobs: if-no-files-found: error - name: Upload appx x64 artifact + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-x64.appx @@ -470,6 +492,7 @@ jobs: if-no-files-found: error - name: Upload store appx x64 artifact + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-x64-store.appx @@ -477,6 +500,7 @@ jobs: if-no-files-found: error - name: Upload NSIS x64 artifact + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: name: bitwarden-${{ env._PACKAGE_VERSION }}-x64.nsis.7z @@ -484,6 +508,7 @@ jobs: if-no-files-found: error - name: Upload appx ARM64 artifact + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-arm64.appx @@ -491,6 +516,7 @@ jobs: if-no-files-found: error - name: Upload store appx ARM64 artifact + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-arm64-store.appx @@ -498,6 +524,7 @@ jobs: if-no-files-found: error - name: Upload NSIS ARM64 artifact + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: name: bitwarden-${{ env._PACKAGE_VERSION }}-arm64.nsis.7z @@ -505,6 +532,7 @@ jobs: if-no-files-found: error - name: Upload nupkg artifact + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: name: bitwarden.${{ env._PACKAGE_VERSION }}.nupkg @@ -512,6 +540,7 @@ jobs: if-no-files-found: error - name: Upload auto-update artifact + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: name: ${{ needs.setup.outputs.release_channel }}.yml @@ -574,11 +603,13 @@ jobs: key: ${{ runner.os }}-${{ github.run_id }}-safari-extension - name: Login to Azure + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 with: creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} - name: Download Provisioning Profiles secrets + if: ${{ needs.setup.outputs.has_secrets == 'true' }} env: ACCOUNT_NAME: bitwardenci CONTAINER_NAME: profiles @@ -591,6 +622,7 @@ jobs: --output none - name: Get certificates + if: ${{ needs.setup.outputs.has_secrets == 'true' }} run: | mkdir -p $HOME/certificates @@ -613,6 +645,7 @@ jobs: jq -r .value | base64 -d > $HOME/certificates/macdev-cert.p12 - name: Set up keychain + if: ${{ needs.setup.outputs.has_secrets == 'true' }} env: KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} run: | @@ -642,6 +675,7 @@ jobs: security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k $KEYCHAIN_PASSWORD build.keychain - name: Set up provisioning profiles + if: ${{ needs.setup.outputs.has_secrets == 'true' }} run: | cp $HOME/secrets/bitwarden_desktop_appstore.provisionprofile \ $GITHUB_WORKSPACE/apps/desktop/bitwarden_desktop_appstore.provisionprofile @@ -661,7 +695,7 @@ jobs: working-directory: ./ - name: Download SDK Artifacts - if: ${{ inputs.sdk_branch != '' }} + if: ${{ inputs.sdk_branch != '' && needs.setup.outputs.has_secrets == 'true' }} uses: bitwarden/gh-actions/download-artifacts@main with: github_token: ${{secrets.GITHUB_TOKEN}} @@ -674,7 +708,7 @@ jobs: if_no_artifact_found: fail - name: Override SDK - if: ${{ inputs.sdk_branch != '' }} + if: ${{ inputs.sdk_branch != '' && needs.setup.outputs.has_secrets == 'true' }} working-directory: ./ run: | ls -l ../ @@ -701,6 +735,7 @@ jobs: browser-build: name: Browser Build needs: setup + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: ./.github/workflows/build-browser.yml secrets: inherit @@ -708,6 +743,7 @@ jobs: macos-package-github: name: MacOS Package GitHub Release Assets runs-on: macos-13 + if: ${{ needs.setup.outputs.has_secrets == 'true' }} needs: - browser-build - macos-build @@ -949,6 +985,7 @@ jobs: macos-package-mas: name: MacOS Package Prod Release Asset runs-on: macos-13 + if: ${{ needs.setup.outputs.has_secrets == 'true' }} needs: - browser-build - macos-build @@ -1217,6 +1254,7 @@ jobs: macos-package-dev: name: MacOS Package Dev Release Asset runs-on: macos-13 + if: ${{ needs.setup.outputs.has_secrets == 'true' }} needs: - browser-build - macos-build diff --git a/.github/workflows/build-web-target.yml b/.github/workflows/build-web-target.yml new file mode 100644 index 00000000000..fb7074292b5 --- /dev/null +++ b/.github/workflows/build-web-target.yml @@ -0,0 +1,32 @@ +name: Build Web on PR Target + +on: + pull_request: + types: [opened, synchronize] + branches-ignore: + - 'l10n_master' + - 'cf-pages' + paths: + - 'apps/web/**' + - 'libs/**' + - '*' + - '!*.md' + - '!*.txt' + - '.github/workflows/build-web.yml' + +defaults: + run: + shell: bash + +jobs: + check-run: + name: Check PR run + uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main + + run-workflow: + name: Run Build Web on PR Target + needs: check-run + if: ${{ github.event.pull_request.head.repo.full_name != github.repository }} + uses: ./.github/workflows/build-web.yml + secrets: inherit + diff --git a/.github/workflows/build-web.yml b/.github/workflows/build-web.yml index b7e8a51897c..423b15372ae 100644 --- a/.github/workflows/build-web.yml +++ b/.github/workflows/build-web.yml @@ -1,7 +1,7 @@ name: Build Web on: - pull_request_target: + pull_request: types: [opened, synchronize] branches-ignore: - 'l10n_master' @@ -27,6 +27,8 @@ on: - '.github/workflows/build-web.yml' release: types: [published] + workflow_call: + inputs: {} workflow_dispatch: inputs: custom_tag_extension: @@ -41,18 +43,13 @@ env: _AZ_REGISTRY: bitwardenprod.azurecr.io jobs: - check-run: - name: Check PR run - uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main - setup: name: Setup runs-on: ubuntu-22.04 - needs: - - check-run outputs: version: ${{ steps.version.outputs.value }} node_version: ${{ steps.retrieve-node-version.outputs.node_version }} + has_secrets: ${{ steps.check-secrets.outputs.has_secrets }} steps: - name: Check out repo uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -70,6 +67,14 @@ jobs: NODE_VERSION=${NODE_NVMRC/v/''} echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT + - name: Check secrets + id: check-secrets + env: + AZURE_KV_CI_SERVICE_PRINCIPAL: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} + run: | + has_secrets=${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL != '' }} + echo "has_secrets=$has_secrets" >> $GITHUB_OUTPUT + build-artifacts: name: Build artifacts runs-on: ubuntu-22.04 @@ -128,7 +133,7 @@ jobs: run: npm ci - name: Download SDK Artifacts - if: ${{ inputs.sdk_branch != '' }} + if: ${{ inputs.sdk_branch != '' && needs.setup.outputs.has_secrets == 'true' }} uses: bitwarden/gh-actions/download-artifacts@main with: github_token: ${{secrets.GITHUB_TOKEN}} @@ -141,7 +146,7 @@ jobs: if_no_artifact_found: fail - name: Override SDK - if: ${{ inputs.sdk_branch != '' }} + if: ${{ inputs.sdk_branch != '' && needs.setup.outputs.has_secrets == 'true' }} working-directory: ./ run: | ls -l ../ @@ -213,19 +218,23 @@ jobs: ########## ACRs ########## - name: Login to Prod Azure + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 with: creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }} - name: Log into Prod container registry + if: ${{ needs.setup.outputs.has_secrets == 'true' }} run: az acr login -n bitwardenprod - name: Login to Azure - CI Subscription + if: ${{ needs.setup.outputs.has_secrets == 'true' }} uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 with: creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} - name: Retrieve github PAT secrets + if: ${{ needs.setup.outputs.has_secrets == 'true' }} id: retrieve-secret-pat uses: bitwarden/gh-actions/get-keyvault-secrets@main with: @@ -273,6 +282,7 @@ jobs: run: echo "name=$_AZ_REGISTRY/${PROJECT_NAME}:${IMAGE_TAG}" >> $GITHUB_OUTPUT - name: Build Docker image + if: ${{ needs.setup.outputs.has_secrets == 'true' }} id: build-docker uses: docker/build-push-action@67a2d409c0a876cbe6b11854e3e25193efe4e62d # v6.12.0 with: @@ -283,7 +293,7 @@ jobs: tags: ${{ steps.image-name.outputs.name }} secrets: | "GH_PAT=${{ steps.retrieve-secret-pat.outputs.github-pat-bitwarden-devops-bot-repo-scope }}" - + - name: Install Cosign if: github.event_name != 'pull_request_target' && github.ref == 'refs/heads/main' uses: sigstore/cosign-installer@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da # v3.7.0 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 5bc566202c6..4fbef027c7c 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,12 +1,20 @@ name: Lint on: - push: + pull_request: + types: [opened, synchronize] branches-ignore: - 'l10n_master' - 'cf-pages' paths-ignore: - '.github/workflows/**' + push: + branches: + - 'main' + - 'rc' + - 'hotfix-rc-*' + paths-ignore: + - '.github/workflows/**' workflow_dispatch: inputs: {} diff --git a/.github/workflows/scan.yml b/.github/workflows/scan.yml index ac7f0ae6f71..c5e189c4666 100644 --- a/.github/workflows/scan.yml +++ b/.github/workflows/scan.yml @@ -77,3 +77,4 @@ jobs: -Dsonar.sources=. -Dsonar.test.inclusions=**/*.spec.ts -Dsonar.exclusions=**/*.spec.ts + -Dsonar.pullrequest.key=${{ github.event.pull_request.number }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6b297e9344f..8c214b99ed3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -88,7 +88,7 @@ jobs: uses: codecov/codecov-action@1e68e06f1dbfde0e4cefc87efeba9e4643565303 # v5.1.2 - name: Upload results to codecov.io - uses: codecov/test-results-action@9739113ad922ea0a9abb4b2c0f8bf6a4aa8ef820 # v1.0.1 + uses: codecov/test-results-action@4e79e65778be1cecd5df25e14af1eafb6df80ea9 # v1.0.2 if: ${{ needs.check-test-secrets.outputs.available == 'true' }} env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} @@ -103,15 +103,15 @@ jobs: matrix: os: - ubuntu-22.04 - - macos-latest - - windows-latest + - macos-14 + - windows-2022 steps: - name: Check Rust version run: rustup --version - name: Install gnome-keyring - if: ${{ matrix.os=='ubuntu-latest' }} + if: ${{ matrix.os=='ubuntu-22.04' }} run: | sudo apt-get update sudo apt-get install -y gnome-keyring dbus-x11 @@ -124,7 +124,7 @@ jobs: run: cargo build - name: Test Ubuntu - if: ${{ matrix.os=='ubuntu-latest' }} + if: ${{ matrix.os=='ubuntu-22.04' }} working-directory: ./apps/desktop/desktop_native run: | eval "$(dbus-launch --sh-syntax)" @@ -135,11 +135,41 @@ jobs: cargo test -- --test-threads=1 - name: Test macOS - if: ${{ matrix.os=='macos-latest' }} + if: ${{ matrix.os=='macos-14' }} working-directory: ./apps/desktop/desktop_native run: cargo test -- --test-threads=1 - name: Test Windows - if: ${{ matrix.os=='windows-latest'}} + if: ${{ matrix.os=='windows-2022'}} working-directory: ./apps/desktop/desktop_native/core run: cargo test -- --test-threads=1 + + rust-coverage: + name: Rust Coverage + runs-on: macos-14 + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Install rust + uses: dtolnay/rust-toolchain@a54c7afa936fefeb4456b2dd8068152669aa8203 # stable + with: + toolchain: stable + components: llvm-tools + + - name: Cache cargo registry + uses: Swatinem/rust-cache@82a92a6e8fbeee089604da2575dc567ae9ddeaab # v2.7.5 + with: + workspaces: "apps/desktop/desktop_native -> target" + + - name: Install cargo-llvm-cov + run: cargo install cargo-llvm-cov --version 0.6.16 + + - name: Generate coverage + 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 + with: + files: ./apps/desktop/desktop_native/lcov.info diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index d1ba27e108d..85515068b3a 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -7,46 +7,25 @@ setCompodocJson(docJson); const decorator = componentWrapperDecorator( (story) => { - return ` - + return /*html*/ `
${story}
-
- -
- ${story} -
-
- -
- ${story} -
-
- -
- ${story} -
-
- - - - - `; }, ({ globals }) => { + // We need to add the theme class to the body to support body-appended content like popovers and menus + document.body.classList.remove("theme_light"); + document.body.classList.remove("theme_dark"); + + document.body.classList.add(`theme_${globals["theme"]}`); + return { theme: `${globals["theme"]}` }; }, ); @@ -56,16 +35,11 @@ const preview: Preview = { globalTypes: { theme: { description: "Global theme for components", - defaultValue: "both", + defaultValue: "light", toolbar: { title: "Theme", icon: "circlehollow", items: [ - { - title: "Light & Dark", - value: "both", - icon: "sidebyside", - }, { title: "Light", value: "light", @@ -76,16 +50,6 @@ const preview: Preview = { value: "dark", icon: "moon", }, - { - title: "Nord", - value: "nord", - left: "⛰", - }, - { - title: "Solarized", - value: "solarized", - left: "☯", - }, ], dynamicTitle: true, }, diff --git a/apps/browser/package.json b/apps/browser/package.json index 8fc1d733921..4cd1b36bd60 100644 --- a/apps/browser/package.json +++ b/apps/browser/package.json @@ -1,12 +1,12 @@ { "name": "@bitwarden/browser", - "version": "2025.1.4", + "version": "2025.2.1", "scripts": { "build": "npm run build:chrome", "build:chrome": "cross-env BROWSER=chrome MANIFEST_VERSION=3 NODE_OPTIONS=\"--max-old-space-size=8192\" webpack", "build:edge": "cross-env BROWSER=edge MANIFEST_VERSION=3 NODE_OPTIONS=\"--max-old-space-size=8192\" webpack", - "build:firefox": "cross-env BROWSER=firefox NODE_OPTIONS=\"--max-old-space-size=8192\" webpack", - "build:opera": "cross-env BROWSER=opera NODE_OPTIONS=\"--max-old-space-size=8192\" webpack", + "build:firefox": "cross-env BROWSER=firefox MANIFEST_VERSION=3 NODE_OPTIONS=\"--max-old-space-size=8192\" webpack", + "build:opera": "cross-env BROWSER=opera MANIFEST_VERSION=3 NODE_OPTIONS=\"--max-old-space-size=8192\" webpack", "build:safari": "cross-env BROWSER=safari NODE_OPTIONS=\"--max-old-space-size=8192\" webpack", "build:watch": "npm run build:watch:chrome", "build:watch:chrome": "npm run build:chrome -- --watch", diff --git a/apps/browser/scripts/package-safari.ps1 b/apps/browser/scripts/package-safari.ps1 index 075ed606070..ce208478098 100755 --- a/apps/browser/scripts/package-safari.ps1 +++ b/apps/browser/scripts/package-safari.ps1 @@ -52,7 +52,7 @@ foreach ($subBuildPath in $subBuildPaths) { "--verbose", "--force", "--sign", - "E7C9978F6FBCE0553429185C405E61F5380BE8EB", + "4B9662CAB74E8E4F4ECBDD9EDEF2543659D95E3C", "--entitlements", $entitlementsPath ) diff --git a/apps/browser/src/_locales/ar/messages.json b/apps/browser/src/_locales/ar/messages.json index fb618e49d31..de432971e83 100644 --- a/apps/browser/src/_locales/ar/messages.json +++ b/apps/browser/src/_locales/ar/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "شراء العضوية المميزة" }, - "premiumPurchaseAlert": { - "message": "يمكنك شراء العضوية المتميزة على bitwarden.com على خزانة الويب. هل تريد زيارة الموقع الآن؟" - }, "premiumPurchaseAlertV2": { "message": "You can purchase Premium from your account settings on the Bitwarden web app." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "مولد اسم المستخدم" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "استخدم كلمة المرور هذه" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "الموقع $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "تم إرسال إشعار إلى جهازك." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "You will be notified once the request is approved" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "بَدْء تسجيل الدخول" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "كلمة المرور الرئيسية مكشوفة" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organization is deactivated" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra wide" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/az/messages.json b/apps/browser/src/_locales/az/messages.json index c5875377ecd..00f2a9e4253 100644 --- a/apps/browser/src/_locales/az/messages.json +++ b/apps/browser/src/_locales/az/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Premium satın al" }, - "premiumPurchaseAlert": { - "message": "Premium üzvlüyü bitwarden.com veb seyfində satın ala bilərsiniz. İndi saytı ziyarət etmək istəyirsiniz?" - }, "premiumPurchaseAlertV2": { "message": "Bitwarden veb tətbiqindəki hesab ayarlarınızda Premium satın ala bilərsiniz." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "İstifadəçi adı yaradıcı" }, + "useThisEmail": { + "message": "Bu e-poçtu istifadə et" + }, "useThisPassword": { "message": "Bu parolu istifadə et" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Bunu ayarlarda dəyişdir" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Veb sayt $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "Cihazınıza bir bildiriş göndərildi." }, + "notificationSentDevicePart1": { + "message": "Cihazınızda Bitwarden kilidini açın, ya da " + }, + "notificationSentDeviceAnchor": { + "message": "veb tətbiqinizdə" + }, + "notificationSentDevicePart2": { + "message": "Təsdiqləməzdən əvvəl Barmaq izi ifadəsinin aşağıdakı ifadə ilə uyuşduğuna əmin olun." + }, "aNotificationWasSentToYourDevice": { "message": "Cihazınıza bir bildiriş göndərildi" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Hesabınızın kilidinin açıq olduğuna və barmaq izi ifadəsinin digər cihazda uyuşduğuna əmin olun" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "Tələbiniz təsdiqləndikdə bildiriş alacaqsınız" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Giriş başladıldı" }, + "logInRequestSent": { + "message": "Tələb göndərildi" + }, "exposedMasterPassword": { "message": "İfşa olunmuş ana parol" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Element adı" }, - "cannotRemoveViewOnlyCollections": { - "message": "\"Yalnız baxma\" icazələrinə sahib kolleksiyaları silə bilməzsiniz: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Təşkilat deaktiv edildi" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Ekstra enli" }, + "cannotRemoveViewOnlyCollections": { + "message": "\"Yalnız baxma\" icazələrinə sahib kolleksiyaları silə bilməzsiniz: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Lütfən masaüstü tətbiqinizi güncəlləyin" }, diff --git a/apps/browser/src/_locales/be/messages.json b/apps/browser/src/_locales/be/messages.json index 8c0d35a216c..075afecde51 100644 --- a/apps/browser/src/_locales/be/messages.json +++ b/apps/browser/src/_locales/be/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Купіць прэміум" }, - "premiumPurchaseAlert": { - "message": "Вы можаце купіць прэміяльны статус на bitwarden.com. Перайсці на вэб-сайт зараз?" - }, "premiumPurchaseAlertV2": { "message": "You can purchase Premium from your account settings on the Bitwarden web app." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Генератар імені карыстальніка" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Выкарыстоўваць гэты пароль" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Вэб-сайт $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "Апавяшчэнне было адпраўлена на вашу прыладу." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "You will be notified once the request is approved" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Ініцыяваны ўваход" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Скампраметаваны асноўны пароль" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Назва элемента" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organization is deactivated" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra wide" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/bg/messages.json b/apps/browser/src/_locales/bg/messages.json index 00f17c40267..d1006e85d49 100644 --- a/apps/browser/src/_locales/bg/messages.json +++ b/apps/browser/src/_locales/bg/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Покупка на платен абонамент" }, - "premiumPurchaseAlert": { - "message": "Може да платите абонамента си през сайта bitwarden.com. Искате ли да го посетите сега?" - }, "premiumPurchaseAlertV2": { "message": "Можете да закупите платената версия от настройките на регистрацията си, в приложението по уеб на Битуорден." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Генератор на потребителски имена" }, + "useThisEmail": { + "message": "Използване на тази е-поща" + }, "useThisPassword": { "message": "Използване на тази парола" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Променете това в настройките" }, + "change": { + "message": "Промяна" + }, + "changeButtonTitle": { + "message": "Промяна на паролата – $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "Пароли в риск" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ изисква да промените $COUNT$ пароли, тъй като са в риск.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Вашата организация изисква да промените $COUNT$ пароли, тъй като са в риск.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Преглед и промяна на една парола в риск" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Преглед и промяна на $COUNT$ пароли в риск", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "По-бърза промяна на паролите в риск" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Променете настройките си, така че да можете бързо да попълвате автоматично паролите си, както и да генерирате нови" + }, + "turnOnAutofill": { + "message": "Включване на автоматичното попълване" + }, + "turnedOnAutofill": { + "message": "Автоматичното попълване беше включено" + }, + "dismiss": { + "message": "Отхвърляне" + }, "websiteItemLabel": { "message": "Уеб сайт $number$ (адрес)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "Към устройството Ви е изпратено известие." }, + "notificationSentDevicePart1": { + "message": "Отключете Битоурден на устройството си или в" + }, + "notificationSentDeviceAnchor": { + "message": "приложението по уеб" + }, + "notificationSentDevicePart2": { + "message": "Уверете се, че уникалната фраза съвпада с тази по-долу, преди да одобрите." + }, "aNotificationWasSentToYourDevice": { "message": "Към устройството Ви е изпратено известие" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Уверете се, че регистрацията Ви е отключена и че уникалната фраза съвпада с другото устройство" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "Ще получите уведомление когато заявката бъде одобрена" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Вписването е стартирано" }, + "logInRequestSent": { + "message": "Заявката е изпратена" + }, "exposedMasterPassword": { "message": "Разобличена главна парола" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Име на елемента" }, - "cannotRemoveViewOnlyCollections": { - "message": "Не можете да премахвате колекции с права „Само за преглед“: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Организацията е деактивирана" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Много широко" }, + "cannotRemoveViewOnlyCollections": { + "message": "Не можете да премахвате колекции с права „Само за преглед“: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Моля, обновете самостоятелното приложение" }, diff --git a/apps/browser/src/_locales/bn/messages.json b/apps/browser/src/_locales/bn/messages.json index 3428bf7bf72..4ab178cc021 100644 --- a/apps/browser/src/_locales/bn/messages.json +++ b/apps/browser/src/_locales/bn/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "প্রিমিয়াম কিনুন" }, - "premiumPurchaseAlert": { - "message": "আপনি bitwarden.com ওয়েব ভল্টে প্রিমিয়াম সদস্যতা কিনতে পারেন। আপনি কি এখনই ওয়েবসাইটটি দেখতে চান?" - }, "premiumPurchaseAlertV2": { "message": "You can purchase Premium from your account settings on the Bitwarden web app." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Username generator" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Use this password" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Website $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "You will be notified once the request is approved" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Login initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Exposed Master Password" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organization is deactivated" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra wide" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/bs/messages.json b/apps/browser/src/_locales/bs/messages.json index ef1565a387c..f95512b0952 100644 --- a/apps/browser/src/_locales/bs/messages.json +++ b/apps/browser/src/_locales/bs/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Purchase Premium" }, - "premiumPurchaseAlert": { - "message": "You can purchase Premium membership on the bitwarden.com web vault. Do you want to visit the website now?" - }, "premiumPurchaseAlertV2": { "message": "You can purchase Premium from your account settings on the Bitwarden web app." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Username generator" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Use this password" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Website $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "You will be notified once the request is approved" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Login initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Exposed Master Password" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organization is deactivated" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra wide" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/ca/messages.json b/apps/browser/src/_locales/ca/messages.json index 66611001a57..5349e244c45 100644 --- a/apps/browser/src/_locales/ca/messages.json +++ b/apps/browser/src/_locales/ca/messages.json @@ -542,7 +542,7 @@ "description": "Label for the avoid ambiguous characters checkbox." }, "generatorPolicyInEffect": { - "message": "Enterprise policy requirements have been applied to your generator options.", + "message": "Els requisits de la política empresarial s'han aplicat a les opcions del generador.", "description": "Indicates that a policy limits the credential generator screen." }, "searchVault": { @@ -612,7 +612,7 @@ "message": "Obri la web" }, "launchWebsiteName": { - "message": "Launch website $ITEMNAME$", + "message": "Inicia el lloc web $ITEMNAME$", "placeholders": { "itemname": { "content": "$1", @@ -660,7 +660,7 @@ "message": "Verifica identitat" }, "weDontRecognizeThisDevice": { - "message": "We don't recognize this device. Enter the code sent to your email to verify your identity." + "message": "No reconeixem aquest dispositiu. Introduïu el codi que us hem enviat al correu electrònic per verificar la identitat." }, "continueLoggingIn": { "message": "Continua l'inici de sessió" @@ -797,7 +797,7 @@ "message": "El vostre compte s'ha creat correctament. Ara ja podeu iniciar sessió." }, "newAccountCreated2": { - "message": "Your new account has been created!" + "message": "S'ha creat el vostre compte nou!" }, "youHaveBeenLoggedIn": { "message": "Heu iniciat sessió!" @@ -849,10 +849,10 @@ "message": "Bitwarden pot emmagatzemar i omplir codis de verificació en dos passos. Copieu i enganxeu la clau en aquest camp." }, "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 pot emmagatzemar i omplir codis de verificació en dos passos. Seleccioneu la icona de la càmera per fer una captura de pantalla del codi QR de l'autenticador d'aquest lloc web o copieu i enganxeu la clau en aquest camp." }, "learnMoreAboutAuthenticators": { - "message": "Learn more about authenticators" + "message": "Més informació sobre els autenticadors" }, "copyTOTP": { "message": "Copia la clau de l'autenticador (TOTP)" @@ -861,7 +861,7 @@ "message": "Sessió tancada" }, "loggedOutDesc": { - "message": "You have been logged out of your account." + "message": "Heu tancat la sessió del compte." }, "loginExpired": { "message": "La vostra sessió ha caducat." @@ -879,7 +879,7 @@ "message": "Enllaç caducat" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Reinicieu el registre o proveu d'iniciar sessió." }, "youMayAlreadyHaveAnAccount": { "message": "És possible que ja tingueu un compte" @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Compra Premium" }, - "premiumPurchaseAlert": { - "message": "Podeu comprar la vostra subscripció a la caixa forta web de bitwarden.com. Voleu visitar el lloc web ara?" - }, "premiumPurchaseAlertV2": { "message": "You can purchase Premium from your account settings on the Bitwarden web app." }, @@ -1338,7 +1335,7 @@ "message": "Temps d'espera d'autenticació" }, "authenticationSessionTimedOut": { - "message": "The authentication session timed out. Please restart the login process." + "message": "La sessió d'autenticació s'ha esgotat. Reinicieu el procés d'inici de sessió." }, "enterVerificationCodeEmail": { "message": "Introduïu el codi de verificació de 6 dígits que s'ha enviat per correu electrònic a $EMAIL$.", @@ -2064,11 +2061,14 @@ "usernameGenerator": { "message": "Generador de nom d'usuari" }, + "useThisEmail": { + "message": "Utilitza aquest correu" + }, "useThisPassword": { "message": "Utilitzeu aquesta contrasenya" }, "useThisUsername": { - "message": "Use this username" + "message": "Utilitzeu aquest nom d'usuari" }, "securePasswordGenerated": { "message": "Secure password generated! Don't forget to also update your password on the website." @@ -2085,7 +2085,7 @@ "message": "Acció quan acabe el temps d'espera de la caixa forta" }, "vaultTimeoutAction1": { - "message": "Timeout action" + "message": "Acció després del temps d'espera" }, "lock": { "message": "Bloqueja", @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Canvieu-ho a la configuració" }, + "change": { + "message": "Canvia" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Descarta" + }, "websiteItemLabel": { "message": "Website $number$ (URI)", "placeholders": { @@ -2826,7 +2890,7 @@ "message": "Error de desxifrat" }, "couldNotDecryptVaultItemsBelow": { - "message": "Bitwarden could not decrypt the vault item(s) listed below." + "message": "Bitwarden no ha pogut desxifrar els elements de la caixa forta que s'indiquen a continuació." }, "contactCSToAvoidDataLossPart1": { "message": "Contacteu amb el servei d'atenció al client", @@ -3123,14 +3187,20 @@ "notificationSentDevice": { "message": "S'ha enviat una notificació al vostre dispositiu." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "aplicació web" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "S'ha enviat una notificació al vostre dispositiu" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Assegureu-vos que la vostra caixa forta estiga desbloquejada i que la frase d'empremta digital coincidisca en l'altre dispositiu" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { - "message": "You will be notified once the request is approved" + "message": "Se us notificarà un vegada s'haja aprovat la sol·licitud" }, "needAnotherOptionV1": { "message": "Necessiteu una altra opció?" @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "S'ha iniciat la sessió" }, + "logInRequestSent": { + "message": "Sol·licitud enviada" + }, "exposedMasterPassword": { "message": "Contrasenya mestra exposada" }, @@ -3268,7 +3341,7 @@ "message": "Seguiu l'enllaç del correu electrònic enviat a" }, "andContinueCreatingYourAccount": { - "message": "and continue creating your account." + "message": "i continua creant el compte." }, "noEmail": { "message": "Sense correu electrònic?" @@ -3277,7 +3350,7 @@ "message": "Torna arrere" }, "toEditYourEmailAddress": { - "message": "to edit your email address." + "message": "per editar l'adreça de correu electrònic." }, "eu": { "message": "UE", @@ -3459,7 +3532,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": "Canvia a la navegació lateral" }, "skipToContent": { "message": "Vés al contingut" @@ -3537,7 +3610,7 @@ "description": "Screen reader text (aria-label) for new card button within inline menu" }, "newIdentity": { - "message": "New identity", + "message": "Identitat nova", "description": "Button text to display within inline menu when there are no matching items on an identity field" }, "addNewIdentityItemAria": { @@ -3631,7 +3704,7 @@ } }, "duoHealthCheckResultsInNullAuthUrlError": { - "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." + "message": "S'ha produït un error en connectar amb el servei Duo. Utilitzeu un mètode d'inici de sessió en dos passos diferent o poseu-vos en contacte amb Duo per obtenir ajuda." }, "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Inicieu DUO i seguiu els passos per finalitzar la sessió." @@ -3726,7 +3799,7 @@ "message": "Clau de pas" }, "accessing": { - "message": "Accessing" + "message": "Accedint a" }, "loggedInExclamation": { "message": "Connectat!" @@ -3741,7 +3814,7 @@ "message": "Verificació requerida pel lloc iniciador. Aquesta funció encara no s'ha implementat per als comptes sense contrasenya mestra." }, "logInWithPasskeyQuestion": { - "message": "Log in with passkey?" + "message": "Inici de sessió amb clau de pas?" }, "passkeyAlreadyExists": { "message": "Ja hi ha una clau de pas per a aquesta aplicació." @@ -3756,7 +3829,7 @@ "message": "No matching logins for this site" }, "searchSavePasskeyNewLogin": { - "message": "Search or save passkey as new login" + "message": "Cerca o guarda la clau de pas com a nou inici de sessió" }, "confirm": { "message": "Confirma-ho" @@ -3768,7 +3841,7 @@ "message": "Guarda la clau de pas com a nou inici de sessió" }, "chooseCipherForPasskeySave": { - "message": "Choose a login to save this passkey to" + "message": "Trieu un inici de sessió per guardar aquesta clau de pas" }, "chooseCipherForPasskeyAuth": { "message": "Choose a passkey to log in with" @@ -3917,11 +3990,11 @@ "description": "Label indicating the most common import formats" }, "confirmContinueToBrowserSettingsTitle": { - "message": "Continue to browser settings?", + "message": "Voleu continuar a la configuració del navegador?", "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" }, "confirmContinueToHelpCenter": { - "message": "Continue to Help Center?", + "message": "Voleu continuar cap al Centre d'ajuda?", "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" }, "confirmContinueToHelpCenterPasswordManagementContent": { @@ -4075,13 +4148,13 @@ "message": "No values to copy" }, "assignToCollections": { - "message": "Assign to collections" + "message": "Assigna a col·leccions" }, "copyEmail": { "message": "Copia el correu electrònic" }, "copyPhone": { - "message": "Copy phone" + "message": "Copia telèfon" }, "copyAddress": { "message": "Copia l'adreça" @@ -4105,7 +4178,7 @@ "message": "S'ha produït un error en assignar la carpeta de destinació." }, "viewItemsIn": { - "message": "View items in $NAME$", + "message": "Mostra elements en $NAME$", "description": "Button to view the contents of a folder or collection", "placeholders": { "name": { @@ -4115,7 +4188,7 @@ } }, "backTo": { - "message": "Back to $NAME$", + "message": "Torna a $NAME$", "description": "Navigate back to a previous folder or collection", "placeholders": { "name": { @@ -4128,7 +4201,7 @@ "message": "Nou" }, "removeItem": { - "message": "Remove $NAME$", + "message": "Suprimeix $NAME$", "description": "Remove a selected option, such as a folder or collection", "placeholders": { "name": { @@ -4146,15 +4219,6 @@ "itemName": { "message": "Nom d'element" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organization is deactivated" }, @@ -4172,7 +4236,7 @@ "message": "Informació addicional" }, "itemHistory": { - "message": "Item history" + "message": "Historial d'elements" }, "lastEdited": { "message": "Última edició" @@ -4184,7 +4248,7 @@ "message": "Enllaçat" }, "copySuccessful": { - "message": "Copy Successful" + "message": "Còpia correcta" }, "upload": { "message": "Puja" @@ -4196,7 +4260,7 @@ "message": "La mida màxima del fitxer és de 500 MB" }, "deleteAttachmentName": { - "message": "Delete attachment $NAME$", + "message": "Suprimeix adjunt $NAME$", "placeholders": { "name": { "content": "$1", @@ -4214,7 +4278,7 @@ } }, "permanentlyDeleteAttachmentConfirmation": { - "message": "Are you sure you want to permanently delete this attachment?" + "message": "Esteu segur que voleu suprimir definitivament aquest adjunt?" }, "premium": { "message": "Premium" @@ -4511,13 +4575,13 @@ } }, "successfullyAssignedCollections": { - "message": "Successfully assigned collections" + "message": "Col·leccions assignades correctament" }, "nothingSelected": { - "message": "You have not selected anything." + "message": "No heu seleccionat res." }, "movedItemsToOrg": { - "message": "Selected items moved to $ORGNAME$", + "message": "Els elements seleccionats s'han desplaçat a $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -4526,7 +4590,7 @@ } }, "itemsMovedToOrg": { - "message": "Items moved to $ORGNAME$", + "message": "S'han desplaçat elements a $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -4535,7 +4599,7 @@ } }, "itemMovedToOrg": { - "message": "Item moved to $ORGNAME$", + "message": "S'ha desplaçat un element a $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -4564,19 +4628,19 @@ "message": "Item Location" }, "fileSend": { - "message": "File Send" + "message": "Send de fitxer" }, "fileSends": { - "message": "File Sends" + "message": "Sends de fitxer" }, "textSend": { - "message": "Text Send" + "message": "Send de text" }, "textSends": { - "message": "Text Sends" + "message": "Sends de text" }, "accountActions": { - "message": "Account actions" + "message": "Accions del compte" }, "showNumberOfAutofillSuggestions": { "message": "Mostra el nombre de suggeriments d'emplenament automàtic d'inici de sessió a la icona d'extensió" @@ -4585,10 +4649,10 @@ "message": "Mostra accions de còpia ràpida a la caixa forta" }, "systemDefault": { - "message": "System default" + "message": "Per defecte del sistema" }, "enterprisePolicyRequirementsApplied": { - "message": "Enterprise policy requirements have been applied to this setting" + "message": "Els requisits de la política empresarial s'han aplicat a aquesta configuració" }, "sshPrivateKey": { "message": "Clau privada" @@ -4597,7 +4661,7 @@ "message": "Clau pública" }, "sshFingerprint": { - "message": "Fingerprint" + "message": "Empremta digital" }, "sshKeyAlgorithm": { "message": "Tipus de clau" @@ -4618,7 +4682,7 @@ "message": "Torneu-ho a provar" }, "vaultCustomTimeoutMinimum": { - "message": "Minimum custom timeout is 1 minute." + "message": "El temps d'espera personalitzat mínim és d'1 minut." }, "additionalContentAvailable": { "message": "Additional content is available" @@ -4627,10 +4691,10 @@ "message": "File saved to device. Manage from your device downloads." }, "showCharacterCount": { - "message": "Show character count" + "message": "Mostra el recompte de caràcters" }, "hideCharacterCount": { - "message": "Hide character count" + "message": "Amaga el recompte de caràcters" }, "itemsInTrash": { "message": "Items in trash" @@ -4642,16 +4706,16 @@ "message": "Items you delete will appear here and be permanently deleted after 30 days" }, "trashWarning": { - "message": "Items that have been in trash more than 30 days will automatically be deleted" + "message": "Els elements que porten més de 30 dies a la paperera se suprimiran automàticament" }, "restore": { - "message": "Restore" + "message": "Restaura" }, "deleteForever": { "message": "Suprimeix per sempre" }, "noEditPermissions": { - "message": "You don't have permission to edit this item" + "message": "No tens permisos per editar aquest fitxer" }, "biometricsStatusHelptextUnlockNeeded": { "message": "Biometric unlock is unavailable because PIN or password unlock is required first." @@ -4681,14 +4745,14 @@ "message": "Biometric unlock is currently unavailable for an unknown reason." }, "authenticating": { - "message": "Authenticating" + "message": "S'està autenticant" }, "fillGeneratedPassword": { "message": "Fill generated password", "description": "Heading for the password generator within the inline menu" }, "passwordRegenerated": { - "message": "Password regenerated", + "message": "Contrasenya regenerada", "description": "Notification message for when a password has been regenerated" }, "saveLoginToBitwarden": { @@ -4696,7 +4760,7 @@ "description": "Confirmation message for saving a login to Bitwarden" }, "spaceCharacterDescriptor": { - "message": "Space", + "message": "Espai", "description": "Represents the space key in screen reader content as a readable word" }, "tildeCharacterDescriptor": { @@ -4708,7 +4772,7 @@ "description": "Represents the ` key in screen reader content as a readable word" }, "exclamationCharacterDescriptor": { - "message": "Exclamation mark", + "message": "Signe d'exclamació", "description": "Represents the ! key in screen reader content as a readable word" }, "atSignCharacterDescriptor": { @@ -4728,7 +4792,7 @@ "description": "Represents the % key in screen reader content as a readable word" }, "caretCharacterDescriptor": { - "message": "Caret", + "message": "Circumflex", "description": "Represents the ^ key in screen reader content as a readable word" }, "ampersandCharacterDescriptor": { @@ -4748,11 +4812,11 @@ "description": "Represents the ) key in screen reader content as a readable word" }, "hyphenCharacterDescriptor": { - "message": "Underscore", + "message": "Subratllat", "description": "Represents the _ key in screen reader content as a readable word" }, "underscoreCharacterDescriptor": { - "message": "Hyphen", + "message": "Guió", "description": "Represents the - key in screen reader content as a readable word" }, "plusCharacterDescriptor": { @@ -4764,19 +4828,19 @@ "description": "Represents the = key in screen reader content as a readable word" }, "braceLeftCharacterDescriptor": { - "message": "Left brace", + "message": "Clau esquerra", "description": "Represents the { key in screen reader content as a readable word" }, "braceRightCharacterDescriptor": { - "message": "Right brace", + "message": "Clau dreta", "description": "Represents the } key in screen reader content as a readable word" }, "bracketLeftCharacterDescriptor": { - "message": "Left bracket", + "message": "Claudàtor esquerra", "description": "Represents the [ key in screen reader content as a readable word" }, "bracketRightCharacterDescriptor": { - "message": "Right bracket", + "message": "Claudàtor dret", "description": "Represents the ] key in screen reader content as a readable word" }, "pipeCharacterDescriptor": { @@ -4867,25 +4931,34 @@ } }, "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" + "message": "No, jo no" }, "newDeviceVerificationNoticePageOneEmailAccessYes": { "message": "Yes, I can reliably access my email" }, "turnOnTwoStepLogin": { - "message": "Turn on two-step login" + "message": "Activa l'inici de sessió en dos passos" }, "changeAcctEmail": { "message": "Change account email" }, "extensionWidth": { - "message": "Extension width" + "message": "Amplada d'extensió" }, "wide": { "message": "Ample" }, "extraWide": { - "message": "Extra wide" + "message": "Extra ample" + }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" diff --git a/apps/browser/src/_locales/cs/messages.json b/apps/browser/src/_locales/cs/messages.json index b58ea149a1c..389a74e42fd 100644 --- a/apps/browser/src/_locales/cs/messages.json +++ b/apps/browser/src/_locales/cs/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Zakoupit členství Premium" }, - "premiumPurchaseAlert": { - "message": "Prémiové členství můžete zakoupit na webové stránce bitwarden.com. Chcete tuto stránku nyní otevřít?" - }, "premiumPurchaseAlertV2": { "message": "Premium si můžete zakoupit v nastavení účtu ve webové aplikaci Bitwarden." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Generátor uživatelského jména" }, + "useThisEmail": { + "message": "Použít tento e-mail" + }, "useThisPassword": { "message": "Použít toto heslo" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Změňte to v nastavení" }, + "change": { + "message": "Změnit" + }, + "changeButtonTitle": { + "message": "Změnit heslo - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "Ohrožená hesla" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ Vás žádá o změnu $COUNT$ hesel, protože jsou v ohrožení.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Vaše organizace Vás žádají o změnu $COUNT$ hesel, protože jsou v ohrožení.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Zkontrolovat a změnit jedno ohrožené heslo" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Zkontrolovat a změnit $COUNT$ ohrožených hesel", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Změnit ohrožená hesla rychleji" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Aktualizujte svá nastavení, abyste mohli rychle automaticky vyplňovat hesla a generovat nová hesla." + }, + "turnOnAutofill": { + "message": "Zapnout automatické vyplňování" + }, + "turnedOnAutofill": { + "message": "Automatické vyplňování bylo zapnuto" + }, + "dismiss": { + "message": "Zavřít" + }, "websiteItemLabel": { "message": "Webová stránka $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "Na Vaše zařízení bylo odesláno oznámení." }, + "notificationSentDevicePart1": { + "message": "Odemknout Bitwarden na Vašem zařízení nebo na" + }, + "notificationSentDeviceAnchor": { + "message": "webová aplikace" + }, + "notificationSentDevicePart2": { + "message": "Před schválením se ujistěte, že fráze otisku prstu odpovídá frázi níže." + }, "aNotificationWasSentToYourDevice": { "message": "Na Vaše zařízení bylo odesláno oznámení" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Ujistěte se, že je Váš trezor odemčen a fráze otisku prstu se shodují s druhým zařízením" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "Budete upozorněni, jakmile bude žádost schválena" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Bylo zahájeno přihlášení" }, + "logInRequestSent": { + "message": "Požadavek odeslán" + }, "exposedMasterPassword": { "message": "Odhalené hlavní heslo" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Název položky" }, - "cannotRemoveViewOnlyCollections": { - "message": "Nemůžete odebrat kolekce s oprávněními jen pro zobrazení: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organizace je deaktivována" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra široký" }, + "cannotRemoveViewOnlyCollections": { + "message": "Nemůžete odebrat kolekce s oprávněními jen pro zobrazení: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Aktualizujte aplikaci pro stolní počítač" }, diff --git a/apps/browser/src/_locales/cy/messages.json b/apps/browser/src/_locales/cy/messages.json index dcc81081148..b44bfa3ce6d 100644 --- a/apps/browser/src/_locales/cy/messages.json +++ b/apps/browser/src/_locales/cy/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Prynu aelodaeth uwch" }, - "premiumPurchaseAlert": { - "message": "You can purchase Premium membership on the bitwarden.com web vault. Do you want to visit the website now?" - }, "premiumPurchaseAlertV2": { "message": "You can purchase Premium from your account settings on the Bitwarden web app." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Username generator" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Use this password" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Website $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "You will be notified once the request is approved" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Login initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Exposed Master Password" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organization is deactivated" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra wide" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/da/messages.json b/apps/browser/src/_locales/da/messages.json index be857787d96..009864512a8 100644 --- a/apps/browser/src/_locales/da/messages.json +++ b/apps/browser/src/_locales/da/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Køb premium" }, - "premiumPurchaseAlert": { - "message": "Du kan købe premium-medlemskab i bitwarden.com web-boksen. Vil du besøge hjemmesiden nu?" - }, "premiumPurchaseAlertV2": { "message": "Der kan købes Premium fra kontoindstillingerne via Bitwarden web-appen." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Brugernavngenerator" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Anvend denne adgangskode" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Ændr dette i Indstillinger" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Websted $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "En notifikation er sendt til din enhed." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "En notifikation er sendt til enheden" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Sørg for, at boksen er oplåst, samt at fingeraftrykssætningen matcher på den anden enhed" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "Man vil få besked, når anmodningen er godkendt" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Indlogning påbegyndt" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Kompromitteret hovedadgangskode" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Emnenavn" }, - "cannotRemoveViewOnlyCollections": { - "message": "Samlinger med kun tilladelsen Vis kan ikke fjernes: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organisation er deaktiveret" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Ekstra bred" }, + "cannotRemoveViewOnlyCollections": { + "message": "Samlinger med kun tilladelsen Vis kan ikke fjernes: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Opdatér venligst computerapplikationen" }, diff --git a/apps/browser/src/_locales/de/messages.json b/apps/browser/src/_locales/de/messages.json index 6d00761b9f0..c27bc1ec862 100644 --- a/apps/browser/src/_locales/de/messages.json +++ b/apps/browser/src/_locales/de/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Premium-Mitgliedschaft kaufen" }, - "premiumPurchaseAlert": { - "message": "Du kannst deine Premium-Mitgliedschaft im Bitwarden.com Web-Tresor kaufen. Möchtest du die Website jetzt besuchen?" - }, "premiumPurchaseAlertV2": { "message": "Du kannst Premium über deine Kontoeinstellungen in der Bitwarden Web-App kaufen." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Benutzernamen-Generator" }, + "useThisEmail": { + "message": "Diese E-Mail-Adresse verwenden" + }, "useThisPassword": { "message": "Dieses Passwort verwenden" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Dies in den Einstellungen ändern" }, + "change": { + "message": "Ändern" + }, + "changeButtonTitle": { + "message": "Passwort ändern - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "Risikoreiche Passwörter" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ fordert dich auf, diese $COUNT$ Passwörter zu ändern, da diese in risikoreich sind.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Deine Organisationen fordern dich auf, diese $COUNT$ Passwörter zu ändern, da diese risikoreich sind.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Überprüfe und ändere ein risikoreiches Passwort" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Überprüfe und ändere $COUNT$ risikoreiche Passwörter", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Ändere risikoreiche Passwörter schneller" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Aktualisiere deine Einstellungen, damit du deine Passwörter schnell automatisch ausfüllen kannst und neue generieren kannst" + }, + "turnOnAutofill": { + "message": "Auto-Ausfüllen aktivieren" + }, + "turnedOnAutofill": { + "message": "Auto-Ausfüllen aktiviert" + }, + "dismiss": { + "message": "Verwerfen" + }, "websiteItemLabel": { "message": "Website $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "Eine Benachrichtigung wurde an dein Gerät gesendet." }, + "notificationSentDevicePart1": { + "message": "Entsperre Bitwarden auf deinem Gerät oder mit der" + }, + "notificationSentDeviceAnchor": { + "message": "Web-App" + }, + "notificationSentDevicePart2": { + "message": "Stelle vor der Genehmigung sicher, dass die Fingerabdruck-Phrase mit der unten stehenden übereinstimmt." + }, "aNotificationWasSentToYourDevice": { "message": "Eine Benachrichtigung wurde an dein Gerät gesendet" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Stelle sicher, dass dein Konto entsperrt ist und die Fingerabdruck-Phrase mit der vom anderen Gerät übereinstimmt" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "Du wirst benachrichtigt, sobald die Anfrage genehmigt wurde" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Anmeldung eingeleitet" }, + "logInRequestSent": { + "message": "Anfrage gesendet" + }, "exposedMasterPassword": { "message": "Kompromittiertes Master-Passwort" }, @@ -3945,7 +4018,7 @@ "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Das Ignorieren dieser Option kann zu Konflikten zwischen dem Bitwarden Auto-Ausfüllen Menü und dem Browser führen.", + "message": "Das Ignorieren dieser Option kann zu Konflikten zwischen den Bitwarden Vorschlägen zum Auto-Ausfüllen und denen deines Browsers führen.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3994,7 +4067,7 @@ "message": "Passkey entfernt" }, "autofillSuggestions": { - "message": "Vorschläge zum Auto-Ausfüllen" + "message": "Auto-Ausfüllen-Vorschläge" }, "itemSuggestions": { "message": "Vorgeschlagene Einträge" @@ -4146,15 +4219,6 @@ "itemName": { "message": "Eintrags-Name" }, - "cannotRemoveViewOnlyCollections": { - "message": "Du kannst Sammlungen mit Leseberechtigung nicht entfernen: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organisation ist deaktiviert" }, @@ -4579,7 +4643,7 @@ "message": "Konto-Aktionen" }, "showNumberOfAutofillSuggestions": { - "message": "Anzahl der Vorschläge zum Auto-Ausfüllen von Zugangsdaten auf dem Erweiterungssymbol anzeigen" + "message": "Anzahl der Auto-Ausfüllen-Vorschläge von Zugangsdaten auf dem Erweiterungssymbol anzeigen" }, "showQuickCopyActions": { "message": "Schnellkopier-Aktionen im Tresor anzeigen" @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra breit" }, + "cannotRemoveViewOnlyCollections": { + "message": "Du kannst Sammlungen mit Leseberechtigung nicht entfernen: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Bitte aktualisiere deine Desktop-Anwendung" }, diff --git a/apps/browser/src/_locales/el/messages.json b/apps/browser/src/_locales/el/messages.json index fbdd2f00a1a..b659718b412 100644 --- a/apps/browser/src/_locales/el/messages.json +++ b/apps/browser/src/_locales/el/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Αγορά Premium έκδοσης" }, - "premiumPurchaseAlert": { - "message": "Μπορείτε να αγοράσετε συνδρομή Premium στο διαδικτυακό θησαυ/κιο του bitwarden.com. Θέλετε να επισκεφθείτε την ιστοσελίδα τώρα;" - }, "premiumPurchaseAlertV2": { "message": "Μπορείτε να αγοράσετε το Premium από τις ρυθμίσεις του λογαριασμού σας στην διαδικτυακή εφαρμογή Bitwarden." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Γεννήτρια ονόματος χρήστη" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Χρήση αυτού του κωδικού πρόσβασης" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Ιστοσελίδα $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "Μια ειδοποίηση έχει σταλεί στη συσκευή σας." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "Μια ειδοποίηση στάλθηκε στη συσκευή σας" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Βεβαιωθείτε ότι ο λογαριασμός σας είναι ξεκλείδωτος και ότι η φράση δακτυλικού αποτυπώματος ταιριάζει στην άλλη συσκευή" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "Θα ειδοποιηθείτε μόλις εγκριθεί η αίτηση" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Η σύνδεση ξεκίνησε" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Εκτεθειμένος Κύριος Κωδικός Πρόσβασης" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Όνομα αντικειμένου" }, - "cannotRemoveViewOnlyCollections": { - "message": "Δεν μπορείτε να αφαιρέσετε συλλογές που έχουν μόνο δικαιώματα Προβολής: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Ο οργανισμός απενεργοποιήθηκε" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Εξαιρετικά φαρδύ" }, + "cannotRemoveViewOnlyCollections": { + "message": "Δεν μπορείτε να αφαιρέσετε συλλογές που έχουν μόνο δικαιώματα Προβολής: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index 9a06db4ed73..7eec2804ece 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Website $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "You will be notified once the request is approved" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Login initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Exposed Master Password" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organization is deactivated" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra wide" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/en_GB/messages.json b/apps/browser/src/_locales/en_GB/messages.json index 4e8774fc2f5..8a7e0a10afd 100644 --- a/apps/browser/src/_locales/en_GB/messages.json +++ b/apps/browser/src/_locales/en_GB/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Purchase premium" }, - "premiumPurchaseAlert": { - "message": "You can purchase Premium membership on the bitwarden.com web vault. Do you want to visit the website now?" - }, "premiumPurchaseAlertV2": { "message": "You can purchase Premium from your account settings on the Bitwarden web app." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Username generator" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Use this password" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organisations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Website $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "You will be notified once the request is approved" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Login initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Exposed Master Password" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organisation is deactivated" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra wide" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/en_IN/messages.json b/apps/browser/src/_locales/en_IN/messages.json index 421a5839467..0189404c002 100644 --- a/apps/browser/src/_locales/en_IN/messages.json +++ b/apps/browser/src/_locales/en_IN/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Purchase premium" }, - "premiumPurchaseAlert": { - "message": "You can purchase premium membership on the bitwarden.com web vault. Do you want to visit the website now?" - }, "premiumPurchaseAlertV2": { "message": "You can purchase Premium from your account settings on the Bitwarden web app." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Username generator" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Use this password" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organisations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Website $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "You will be notified once the request is approved" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Login initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Exposed Master Password" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organisation is deactivated" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra wide" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/es/messages.json b/apps/browser/src/_locales/es/messages.json index ea47db2c26c..9fcdc4acf2b 100644 --- a/apps/browser/src/_locales/es/messages.json +++ b/apps/browser/src/_locales/es/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Comprar Premium" }, - "premiumPurchaseAlert": { - "message": "Puedes comprar la membresía Premium en la caja fuerte web de bitwarden.com. ¿Quieres visitar el sitio web ahora?" - }, "premiumPurchaseAlertV2": { "message": "You can purchase Premium from your account settings on the Bitwarden web app." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Generador de nombres de usuario" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Usar esta contraseña" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Website $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "Se ha enviado una notificación a tu dispositivo." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "You will be notified once the request is approved" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Inicio de sesión en proceso" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Contraseña maestra comprometida" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Nombre del elemento" }, - "cannotRemoveViewOnlyCollections": { - "message": "No puedes eliminar colecciones con permisos de solo visualización: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "La organización está desactivada" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra wide" }, + "cannotRemoveViewOnlyCollections": { + "message": "No puedes eliminar colecciones con permisos de solo visualización: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/et/messages.json b/apps/browser/src/_locales/et/messages.json index 78bc92a7ec1..ac6945461fa 100644 --- a/apps/browser/src/_locales/et/messages.json +++ b/apps/browser/src/_locales/et/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Osta Premium" }, - "premiumPurchaseAlert": { - "message": "Bitwardeni premium versiooni saab osta bitwarden.com veebihoidlas. Avan veebihoidla?" - }, "premiumPurchaseAlertV2": { "message": "You can purchase Premium from your account settings on the Bitwarden web app." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Kasutajanime genereerija" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Kasuta seda parooli" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Website $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "Sinu seadmesse saadeti teavitus." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "You will be notified once the request is approved" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Sisselogimine on käivitatud" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Ülemparool on haavatav" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organization is deactivated" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra wide" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/eu/messages.json b/apps/browser/src/_locales/eu/messages.json index d3ec813c5f5..23060f7b5c3 100644 --- a/apps/browser/src/_locales/eu/messages.json +++ b/apps/browser/src/_locales/eu/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Premium erosi" }, - "premiumPurchaseAlert": { - "message": "Zure premium bazkidetza bitwarden.com webguneko kutxa gotorrean ordaindu dezakezu. Orain bisitatu nahi duzu webgunea?" - }, "premiumPurchaseAlertV2": { "message": "You can purchase Premium from your account settings on the Bitwarden web app." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Username generator" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Use this password" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Website $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "You will be notified once the request is approved" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Login initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Exposed Master Password" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organization is deactivated" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra wide" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/fa/messages.json b/apps/browser/src/_locales/fa/messages.json index 68b1ad74a5b..3ee7770dcfe 100644 --- a/apps/browser/src/_locales/fa/messages.json +++ b/apps/browser/src/_locales/fa/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "خرید پرمیوم" }, - "premiumPurchaseAlert": { - "message": "شما می‌توانید عضویت پرمیوم را از گاوصندوق وب bitwarden.com خریداری کنید. مایلید اکنون از وب‌سایت بازید کنید؟" - }, "premiumPurchaseAlertV2": { "message": "You can purchase Premium from your account settings on the Bitwarden web app." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Username generator" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Use this password" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Website $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "یک اعلان به دستگاه شما ارسال شده است." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "You will be notified once the request is approved" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "ورود به سیستم آغاز شد" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "کلمه عبور اصلی افشا شده" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organization is deactivated" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra wide" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/fi/messages.json b/apps/browser/src/_locales/fi/messages.json index 6283714ed21..ae6e780a00f 100644 --- a/apps/browser/src/_locales/fi/messages.json +++ b/apps/browser/src/_locales/fi/messages.json @@ -120,7 +120,7 @@ "message": "Kopioi salasana" }, "copyPassphrase": { - "message": "Kopioi salalause" + "message": "Kopioi salauslauseke" }, "copyNote": { "message": "Kopioi merkinnät" @@ -443,19 +443,19 @@ "message": "Luo salasana" }, "generatePassphrase": { - "message": "Luo salalause" + "message": "Luo salauslauseke" }, "passwordGenerated": { - "message": "Password generated" + "message": "Salasana luotiin" }, "passphraseGenerated": { - "message": "Passphrase generated" + "message": "Salauslauseke luotiin" }, "usernameGenerated": { - "message": "Username generated" + "message": "Käyttäjätunnus luotiin" }, "emailGenerated": { - "message": "Email generated" + "message": "Sähköpostiosoite luotu" }, "regeneratePassword": { "message": "Luo uusi salasana" @@ -660,10 +660,10 @@ "message": "Vahvista henkilöllisyytesi" }, "weDontRecognizeThisDevice": { - "message": "We don't recognize this device. Enter the code sent to your email to verify your identity." + "message": "Emme tunnista tätä laitetta. Anna sähköpostiisi lähetetty koodi henkilöllisyytesi vahvistamiseksi." }, "continueLoggingIn": { - "message": "Continue logging in" + "message": "Jatka kirjautumista" }, "yourVaultIsLocked": { "message": "Holvisi on lukittu. Jatka vahvistamalla henkilöllisyytesi." @@ -1005,7 +1005,7 @@ "message": "Ehdota kohteen tallennusta, jos holvistasi ei vielä löydy vastaavaa kohdetta. Koskee kaikkia kirjautuneita tilejä." }, "showCardsInVaultViewV2": { - "message": "Always show cards as Autofill suggestions on Vault view" + "message": "Näytä aina kortit automaattisen täytön ehdotuksina Holvi-näkymässä" }, "showCardsCurrentTab": { "message": "Näytä kortit välilehtiosiossa" @@ -1014,7 +1014,7 @@ "message": "Näytä kortit Välilehti-sivulla automaattitäytön helpottamiseksi." }, "showIdentitiesInVaultViewV2": { - "message": "Always show identities as Autofill suggestions on Vault view" + "message": "Näytä aina identiteetit automaattisen täytön ehdotuksina Holvi-näkymässä" }, "showIdentitiesCurrentTab": { "message": "Näytä henkilöllisyydet välilehtiosiossa" @@ -1023,7 +1023,7 @@ "message": "Näytä henkilöllisyydet Välilehti-sivulla automaattitäytön helpottamiseksi." }, "clickToAutofillOnVault": { - "message": "Click items to autofill on Vault view" + "message": "Valitse kohteita täyttääksesi tiedot automaattisesti Holvi-näkymässä" }, "clearClipboard": { "message": "Tyhjennä leikepöytä", @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Osta Premium" }, - "premiumPurchaseAlert": { - "message": "Voit ostaa Premium-jäsenyyden bitwarden.com-verkkoholvista. Haluatko avata sivuston nyt?" - }, "premiumPurchaseAlertV2": { "message": "Voit ostaa Premiumin tiliasetuksistasi Bitwardenin verkkosovelluksen kautta." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Käyttäjätunnusgeneraattori" }, + "useThisEmail": { + "message": "Käytä tätä sähköpostia" + }, "useThisPassword": { "message": "Käytä tätä salasanaa" }, @@ -2355,13 +2355,77 @@ "message": "Bitwarden ei pyydä kirjautumistietojen tallennusta näillä verkkotunnuksilla. Koskee kaikkia kirjautuneita tilejä. Ota muutokset käyttöön päivittämällä sivu." }, "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": "Näille sivustoille ei tarjota automaattista täyttöä eikä muita siihen liittyviä ominaisuuksia. Sinun on päivitettävä sivu, jotta muutokset tulevat voimaan." }, "autofillBlockedNoticeV2": { "message": "Automaattitäyttö on estetty tällä sivustolla." }, "autofillBlockedNoticeGuidance": { - "message": "Change this in settings" + "message": "Muuta tätä asetuksissa" + }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" }, "websiteItemLabel": { "message": "Verkkotunnus $number$ (URI)", @@ -2382,7 +2446,7 @@ } }, "blockedDomainsSavedSuccess": { - "message": "Blocked domain changes saved" + "message": "Estetyn verkkotunnuksen muutokset tallennettu" }, "excludedDomainsSavedSuccess": { "message": "Rajoitettujen verkkotunnusten muutokset tallennettiin" @@ -2826,14 +2890,14 @@ "message": "Salauksen purkuvirhe" }, "couldNotDecryptVaultItemsBelow": { - "message": "Bitwarden could not decrypt the vault item(s) listed below." + "message": "Bitwarden ei pystynyt purkamaan alla lueteltuja holvin kohteita." }, "contactCSToAvoidDataLossPart1": { - "message": "Contact customer success", + "message": "Ota yhteyttä asiakkaaseen", "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": "lisätietojen menettämisen välttämiseksi.", "description": "This is part of a larger sentence. The full sentence will read 'Contact customer success to avoid additional data loss.'" }, "generateUsername": { @@ -2867,7 +2931,7 @@ } }, "passphraseNumWordsRecommendationHint": { - "message": " Käytä $RECOMMENDED$ tai useampaa sanaa vahvan salalauseen luomiseen.", + "message": " Käytä $RECOMMENDED$ tai useampaa sanaa vahvan salauslausekkeen luomiseen.", "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": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "Laitteellesi on lähetetty ilmoitus." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "Laitteeseesi lähetettiin ilmoitus" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Varmista, että vahvistavan laitteen holvi on avattu ja että se näyttää saman tunnistelausekkeen" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "Sinulle ilmoitetaan, kun pyyntö on hyväksytty" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Kirjautuminen aloitettu" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Paljastunut pääsalasana" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Kohteen nimi" }, - "cannotRemoveViewOnlyCollections": { - "message": "Et voi poistaa kokoelmia, joihin sinulla on vain tarkasteluoikeus: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organisaatio on poistettu käytöstä" }, @@ -4654,22 +4718,22 @@ "message": "Sinulla ei ole oikeutta muokata tätä kohdetta" }, "biometricsStatusHelptextUnlockNeeded": { - "message": "Biometric unlock is unavailable because PIN or password unlock is required first." + "message": "Biometrinen avaus ei ole käytettävissä, koska PIN-koodi tai salasanan lukituksen avaus vaaditaan ensin." }, "biometricsStatusHelptextHardwareUnavailable": { - "message": "Biometric unlock is currently unavailable." + "message": "Biometrinen avaus ei tällä hetkellä ole käytettävissä." }, "biometricsStatusHelptextAutoSetupNeeded": { - "message": "Biometric unlock is unavailable due to misconfigured system files." + "message": "Biometrinen avaus ei ole käytettävissä, koska järjestelmätiedostoja ei ole määritetty." }, "biometricsStatusHelptextManualSetupNeeded": { - "message": "Biometric unlock is unavailable due to misconfigured system files." + "message": "Biometrinen avaus ei ole käytettävissä, koska järjestelmätiedostoja ei ole määritetty." }, "biometricsStatusHelptextDesktopDisconnected": { - "message": "Biometric unlock is unavailable because the Bitwarden desktop app is closed." + "message": "Biometrinen avaus ei ole käytettävissä, koska Bitwardenin työpöytäsovellus on suljettu." }, "biometricsStatusHelptextNotEnabledInDesktop": { - "message": "Biometric unlock is unavailable because it is not enabled for $EMAIL$ in the Bitwarden desktop app.", + "message": "Biometrinen avaus ei ole käytettävissä, koska sitä ei ole otettu käyttöön osoitteelle $EMAIL$ Bitwardenin työpöytäsovelluksessa.", "placeholders": { "email": { "content": "$1", @@ -4678,7 +4742,7 @@ } }, "biometricsStatusHelptextUnavailableReasonUnknown": { - "message": "Biometric unlock is currently unavailable for an unknown reason." + "message": "Biometrinen avaus ei ole tällä hetkellä käytettävissä tuntemattomasta syystä." }, "authenticating": { "message": "Todennetaan" @@ -4852,13 +4916,13 @@ "message": "Bitwarden lähettää tilisi sähköpostiosoitteeseen koodin, jolla voit vahvistaa kirjautumiset uusista laitteista helmikuusta 2025 alkaen." }, "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + "message": "Voit ottaa käyttöön kaksivaiheisen kirjautumisen vaihtoehtoisena tapana suojata tilisi, tai vaihtaa sähköpostisi sellaiseen, johon sinulla on pääsy." }, "remindMeLater": { "message": "Muistuta myöhemmin" }, "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", + "message": "Onko sinulla luotettava pääsy sähköpostiisi, $EMAIL$?", "placeholders": { "email": { "content": "$1", @@ -4867,10 +4931,10 @@ } }, "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" + "message": "Ei ole" }, "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" + "message": "Kyllä on" }, "turnOnTwoStepLogin": { "message": "Ota kaksivaiheinen kirjautuminen käyttöön" @@ -4887,10 +4951,19 @@ "extraWide": { "message": "Erittäin leveä" }, + "cannotRemoveViewOnlyCollections": { + "message": "Et voi poistaa kokoelmia, joihin sinulla on vain tarkasteluoikeus: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { - "message": "Please update your desktop application" + "message": "Päivitä työpöytäsovellus" }, "updateDesktopAppOrDisableFingerprintDialogMessage": { - "message": "To use biometric unlock, please update your desktop application, or disable fingerprint unlock in the desktop settings." + "message": "Käyttääksesi biometristä avausta, päivitä työpöytäsovelluksesi tai poista tunnistelauseke käytöstä työpöydän asetuksista." } } diff --git a/apps/browser/src/_locales/fil/messages.json b/apps/browser/src/_locales/fil/messages.json index 8008d0595c3..01587793c32 100644 --- a/apps/browser/src/_locales/fil/messages.json +++ b/apps/browser/src/_locales/fil/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Bilhin ang Premium" }, - "premiumPurchaseAlert": { - "message": "Maaari kang mamili ng membership sa Premium sa website ng bitwarden.com. Gusto mo bang bisitahin ang website ngayon?" - }, "premiumPurchaseAlertV2": { "message": "You can purchase Premium from your account settings on the Bitwarden web app." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Username generator" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Use this password" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Website $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "Naipadala na ang notification sa iyong device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "You will be notified once the request is approved" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Login initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Nakalantad na Master Password" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organization is deactivated" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra wide" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/fr/messages.json b/apps/browser/src/_locales/fr/messages.json index e6b06bbcb9d..270499ab506 100644 --- a/apps/browser/src/_locales/fr/messages.json +++ b/apps/browser/src/_locales/fr/messages.json @@ -446,16 +446,16 @@ "message": "Générer une phrase de passe" }, "passwordGenerated": { - "message": "Password generated" + "message": "Mot de passe généré" }, "passphraseGenerated": { - "message": "Passphrase generated" + "message": "Phrase de passe générée" }, "usernameGenerated": { - "message": "Username generated" + "message": "Nom d'utilisateur généré" }, "emailGenerated": { - "message": "Email generated" + "message": "Courriel généré" }, "regeneratePassword": { "message": "Régénérer un mot de passe" @@ -663,7 +663,7 @@ "message": "We don't recognize this device. Enter the code sent to your email to verify your identity." }, "continueLoggingIn": { - "message": "Continue logging in" + "message": "Continuer à se connecter" }, "yourVaultIsLocked": { "message": "Votre coffre est verrouillé. Vérifiez votre identité pour continuer." @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Acheter Premium" }, - "premiumPurchaseAlert": { - "message": "Vous pouvez acheter une adhésion Premium sur le coffre web de bitwarden.com. Voulez-vous visiter le site web maintenant ?" - }, "premiumPurchaseAlertV2": { "message": "Vous pouvez acheter la version Premium depuis les paramètres de votre compte dans l'application web Bitwarden." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Générateur de nom d'utilisateur" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Utiliser ce mot de passe" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Site web $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "Une notification a été envoyée à votre appareil." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "Une notification a été envoyée à votre appareil" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Assurez-vous que votre compte est déverrouillé et que la phrase d'empreinte correspond à l'autre appareil" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "Vous serez notifié une fois que la demande sera approuvée" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Connexion initiée" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Mot de passe principal exposé" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Nom de l’élément" }, - "cannotRemoveViewOnlyCollections": { - "message": "Vous ne pouvez pas supprimer des collections avec les autorisations d'affichage uniquement : $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "L'organisation est désactivée" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Très large" }, + "cannotRemoveViewOnlyCollections": { + "message": "Vous ne pouvez pas supprimer des collections avec les autorisations d'affichage uniquement : $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/gl/messages.json b/apps/browser/src/_locales/gl/messages.json index 075fd93319e..a5b22ae7932 100644 --- a/apps/browser/src/_locales/gl/messages.json +++ b/apps/browser/src/_locales/gl/messages.json @@ -382,7 +382,7 @@ "message": "Aniñar un cartafol engadindo o nome do cartafol pai seguido dun \"/\". Exemplo: Social/Foros" }, "noFoldersAdded": { - "message": "Sen cartafois" + "message": "Sen cartafoles" }, "createFoldersToOrganize": { "message": "Crea cartafoles para organizar as entradas da túa caixa forte" @@ -394,10 +394,10 @@ "message": "Eliminar cartafol" }, "folders": { - "message": "Cartafois" + "message": "Cartafoles" }, "noFolders": { - "message": "Non hai cartafois que listar." + "message": "Non hai cartafoles que listar." }, "helpFeedback": { "message": "Axuda e comentarios" @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Adquirir Prémium" }, - "premiumPurchaseAlert": { - "message": "Podes adquirir o plan Prémium na aplicación web de bitwarden.com. Queres visitala agora mesmo?" - }, "premiumPurchaseAlertV2": { "message": "Podes adquirir o plan Prémium dende os axustes de conta da aplicación web de Bitwarden." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Xerador de nomes de usuario" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Usar este contrasinal" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Cambia isto en axustes" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Web $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "Enviouse unha notificación ó teu dispositivo." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "Enviouse unha notificación ó teu dispositivo" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Por favor asegúrate de que a sesión está aberta e a frase de pegada dixital coincide ca do outro dispositivo" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "Serás notificado unha vez se aprobe a solicitude" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Inicio de sesión comezado" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Contrasinal mestre filtrado" }, @@ -3810,7 +3883,7 @@ "message": "Autenticación multifactor fallida" }, "includeSharedFolders": { - "message": "Incluír cartafois compartidos" + "message": "Incluír cartafoles compartidos" }, "lastPassEmail": { "message": "Correo de LastPass" @@ -4146,15 +4219,6 @@ "itemName": { "message": "Nome da entrada" }, - "cannotRemoveViewOnlyCollections": { - "message": "Non podes eliminar coleccións con permisos de Só lectura: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "A organización está desactivada" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Moi ancho" }, + "cannotRemoveViewOnlyCollections": { + "message": "Non podes eliminar coleccións con permisos de Só lectura: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/he/messages.json b/apps/browser/src/_locales/he/messages.json index abaa5620a4a..58e8cd1e36a 100644 --- a/apps/browser/src/_locales/he/messages.json +++ b/apps/browser/src/_locales/he/messages.json @@ -3,42 +3,42 @@ "message": "Bitwarden" }, "extName": { - "message": "Bitwarden Password Manager", + "message": "מנהל הסיסמאות Bitwarden", "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "message": "בבית, בעבודה, או בדרך, Bitwarden מאבטח בקלות את כל הסיסמאות, מפתחות הגישה, והמידע הרגיש שלך", "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "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": "Set a strong password" + "message": "הגדר סיסמה חזקה" }, "finishCreatingYourAccountBySettingAPassword": { - "message": "Finish creating your account by setting a password" + "message": "סיים ליצור את החשבון שלך על ידי הגדרת סיסמה" }, "enterpriseSingleSignOn": { - "message": "כניסה ארגונית אחידה" + "message": "כניסה יחידה ארגונית" }, "cancel": { "message": "בטל" @@ -62,7 +62,7 @@ "message": "ניתן להשתמש ברמז לסיסמה הראשית אם שכחת אותה." }, "masterPassHintText": { - "message": "If you forget your password, the password hint can be sent to your email. $CURRENT$/$MAXIMUM$ character maximum.", + "message": "אם תשכח את הסיסמה שלך, רמז לסיסמה יכול להישלח לדוא\"ל שלך. $CURRENT$/$MAXIMUM$ תווים לכל היותר.", "placeholders": { "current": { "content": "$1", @@ -78,10 +78,10 @@ "message": "הקלד שוב סיסמה ראשית" }, "masterPassHint": { - "message": "רמז לסיסמה ראשית (אופציונאלי)" + "message": "רמז לסיסמה ראשית (אופציונלי)" }, "joinOrganization": { - "message": "Join organization" + "message": "הצטרף לארגון" }, "joinOrganizationName": { "message": "הצטרפות אל $ORGANIZATIONNAME$", @@ -93,7 +93,7 @@ } }, "finishJoiningThisOrganizationBySettingAMasterPassword": { - "message": "Finish joining this organization by setting a master password." + "message": "סיים להצטרף לארגון זה על ידי הגדרת סיסמה ראשית." }, "tab": { "message": "לשונית" @@ -114,16 +114,16 @@ "message": "הגדרות" }, "currentTab": { - "message": "לשונית נוכחית" + "message": "כרטיסייה נוכחית" }, "copyPassword": { "message": "העתק סיסמה" }, "copyPassphrase": { - "message": "Copy passphrase" + "message": "העתק ביטוי סיסמה" }, "copyNote": { - "message": "העתק פתק" + "message": "העתק הערה" }, "copyUri": { "message": "העתק שורת כתובת" @@ -138,31 +138,31 @@ "message": "העתק קוד אבטחה" }, "copyName": { - "message": "Copy name" + "message": "העתק שם" }, "copyCompany": { - "message": "Copy company" + "message": "העתק חברה" }, "copySSN": { - "message": "Copy Social Security number" + "message": "העתק מספר תעודת זהות" }, "copyPassportNumber": { - "message": "Copy passport number" + "message": "העתק מספר דרכון" }, "copyLicenseNumber": { - "message": "Copy license number" + "message": "העתק מספר רישיון" }, "copyPrivateKey": { - "message": "Copy private key" + "message": "העתק מפתח פרטי" }, "copyPublicKey": { - "message": "Copy public key" + "message": "העתק מפתח ציבורי" }, "copyFingerprint": { - "message": "Copy fingerprint" + "message": "העתק טביעת אצבע" }, "copyCustomField": { - "message": "Copy $FIELD$", + "message": "העתק $FIELD$", "placeholders": { "field": { "content": "$1", @@ -171,42 +171,42 @@ } }, "copyWebsite": { - "message": "Copy website" + "message": "העתק אתר אינטרנט" }, "copyNotes": { - "message": "Copy notes" + "message": "העתק הערות" }, "fill": { - "message": "Fill", + "message": "מילוי", "description": "This string is used on the vault page to indicate autofilling. Horizontal space is limited in the interface here so try and keep translations as concise as possible." }, "autoFill": { - "message": "השלמה אוטומטית" + "message": "מילוי אוטומטי" }, "autoFillLogin": { - "message": "מילוי פרטי כניסה אוטומטית" + "message": "מילוי כניסה אוטומטי" }, "autoFillCard": { - "message": "מילוי פרטי כרטיס אוטומטית" + "message": "מילוי כרטיס אוטומטי" }, "autoFillIdentity": { - "message": "מילוי פרטי זיהוי אוטומטית" + "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": { - "message": "צור סיסמה (העתק)" + "message": "צור סיסמה (והעתק)" }, "copyElementIdentifier": { - "message": "העתקת שם שדה מותאם אישית" + "message": "העתק שם שדה מותאם אישית" }, "noMatchingLogins": { - "message": "לא נמצאו פרטי כניסה תואמים." + "message": "אין כניסות תואמות" }, "noCards": { "message": "אין כרטיסים" @@ -215,40 +215,40 @@ "message": "אין זהויות" }, "addLoginMenu": { - "message": "הוספת פרטי כניסה" + "message": "הוסף כניסה" }, "addCardMenu": { - "message": "הוספת כרטיס" + "message": "הוסף כרטיס" }, "addIdentityMenu": { - "message": "הוספת זהות" + "message": "הוסף זהות" }, "unlockVaultMenu": { - "message": "שחרור הכספת שלך" + "message": "פתח את הכספת שלך" }, "loginToVaultMenu": { "message": "כניסה לכספת שלך" }, "autoFillInfo": { - "message": "לא נמצאו פרטי כניסה להשלמה אוטומטית בלשונית הנוכחית בדפדפן." + "message": "לא נמצאו כניסות למילוי אוטומטי בכרטיסיית הדפדפן הנוכחית." }, "addLogin": { - "message": "הוסף פרטי כניסה" + "message": "הוסף כניסה" }, "addItem": { "message": "הוסף פריט" }, "accountEmail": { - "message": "Account email" + "message": "דוא\"ל חשבון" }, "requestHint": { - "message": "Request hint" + "message": "בקש רמז" }, "requestPasswordHint": { - "message": "Request password hint" + "message": "בקש רמז לסיסמה" }, "enterYourAccountEmailAddressAndYourPasswordHintWillBeSentToYou": { - "message": "Enter your account email address and your password hint will be sent to you" + "message": "הזן את כתובת דוא\"ל החשבון שלך והרמז לסיסמה שלך יישלח אליך" }, "passwordHint": { "message": "רמז לסיסמה" @@ -263,10 +263,10 @@ "message": "המשך" }, "sendVerificationCode": { - "message": "שליחת קוד אימות לדוא״ל שלך" + "message": "שלח קוד אימות לדוא\"ל שלך" }, "sendCode": { - "message": "שליחת קוד" + "message": "שלח קוד" }, "codeSent": { "message": "קוד נשלח" @@ -281,28 +281,28 @@ "message": "החלף סיסמה ראשית" }, "continueToWebApp": { - "message": "Continue to web app?" + "message": "להמשיך ליישום רשת?" }, "continueToWebAppDesc": { - "message": "Explore more features of your Bitwarden account on the web app." + "message": "גלה עוד תכונות של חשבון ה־Bitwarden שלך ביישום הרשת." }, "continueToHelpCenter": { - "message": "Continue to Help Center?" + "message": "להמשיך למרכז עזרה?" }, "continueToHelpCenterDesc": { - "message": "Learn more about how to use Bitwarden on the Help Center." + "message": "למד עוד אודות אופן השימוש ב־Bitwarden במרכז העזרה." }, "continueToBrowserExtensionStore": { - "message": "Continue to browser extension store?" + "message": "להמשיך לחנות הרחבות דפדפן?" }, "continueToBrowserExtensionStoreDesc": { - "message": "Help others find out if Bitwarden is right for them. Visit your browser's extension store and leave a rating now." + "message": "עזור לאחרים לגלות אם Bitwarden מתאים להם. בקר בחנות הרחבות הדפדפן שלך והשאר דירוג עכשיו." }, "changeMasterPasswordOnWebConfirmation": { - "message": "You can change your master password on the Bitwarden web app." + "message": "אתה יכול לשנות את הסיסמה הראשית שלך ביישום הרשת של Bitwarden." }, "fingerprintPhrase": { - "message": "סיסמת טביעת אצבע", + "message": "ביטוי טביעת אצבע", "description": "A 'fingerprint phrase' is a unique word phrase (similar to a passphrase) that a user can use to authenticate their public key with another user, for the purposes of sharing." }, "yourAccountsFingerprint": { @@ -310,49 +310,49 @@ "description": "A 'fingerprint phrase' is a unique word phrase (similar to a passphrase) that a user can use to authenticate their public key with another user, for the purposes of sharing." }, "twoStepLogin": { - "message": "התחברות בשני-שלבים" + "message": "כניסה דו-שלבית" }, "logOut": { "message": "התנתק" }, "aboutBitwarden": { - "message": "About Bitwarden" + "message": "אודות Bitwarden" }, "about": { "message": "אודות" }, "moreFromBitwarden": { - "message": "More from Bitwarden" + "message": "עוד מאת Bitwarden" }, "continueToBitwardenDotCom": { - "message": "Continue to bitwarden.com?" + "message": "להמשיך אל bitwarden.com?" }, "bitwardenForBusiness": { - "message": "Bitwarden for Business" + "message": "Bitwarden לעסקים" }, "bitwardenAuthenticator": { - "message": "Bitwarden Authenticator" + "message": "מאמת Bitwarden" }, "continueToAuthenticatorPageDesc": { - "message": "Bitwarden Authenticator allows you to store authenticator keys and generate TOTP codes for 2-step verification flows. Learn more on the bitwarden.com website" + "message": "מאמת Bitwarden מאפשר לך לאחסון מפתחות מאמת וליצור קודי 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": "Free Bitwarden Families" + "message": "משפחות Bitwarden בחינם" }, "freeBitwardenFamiliesPageDesc": { - "message": "You are eligible for Free Bitwarden Families. Redeem this offer today in the web app." + "message": "אתה זכאי למשפחות Bitwarden בחינם. ממש הצעה זו היום ביישום הרשת." }, "version": { "message": "גירסה" @@ -361,7 +361,7 @@ "message": "שמור" }, "move": { - "message": "העברה" + "message": "העבר" }, "addFolder": { "message": "הוסף תיקייה" @@ -373,22 +373,22 @@ "message": "ערוך תיקייה" }, "newFolder": { - "message": "New folder" + "message": "תיקיה חדשה" }, "folderName": { - "message": "Folder name" + "message": "שם תיקיה" }, "folderHintText": { - "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + "message": "קונן תיקיה על ידי הוספת שם תיקיית האב ואחריו “/”. דוגמה: חברתי/פורומים" }, "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": "מחק תיקייה" @@ -400,16 +400,16 @@ "message": "אין תיקיות להצגה." }, "helpFeedback": { - "message": "עזרה ומשוב" + "message": "עזרה & משוב" }, "helpCenter": { "message": "מרכז העזרה של Bitwarden" }, "communityForums": { - "message": "Explore Bitwarden community forums" + "message": "גלה את פורומי קהילת Bitwarden" }, "contactSupport": { - "message": "Contact Bitwarden support" + "message": "פנה לתמיכת Bitwarden" }, "sync": { "message": "סנכרן" @@ -421,7 +421,7 @@ "message": "סנכרון אחרון:" }, "passGen": { - "message": "יוצר הסיסמאות" + "message": "מחולל סיסמאות" }, "generator": { "message": "מייצר", @@ -431,10 +431,10 @@ "message": "צור אוטומטית סיסמאות חזקות ויחודיות עבור פרטי הכניסה שלך." }, "bitWebVaultApp": { - "message": "Bitwarden web app" + "message": "יישום רשת Bitwarden" }, "importItems": { - "message": "יבא פריטים" + "message": "ייבא פריטים" }, "select": { "message": "בחר" @@ -443,22 +443,22 @@ "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": "צור סיסמה חדשה" + "message": "צור סיסמה מחדש" }, "options": { "message": "אפשרויות" @@ -467,27 +467,27 @@ "message": "אורך" }, "uppercase": { - "message": "Uppercase (A-Z)", + "message": "אות גדולה (A-Z)", "description": "deprecated. Use uppercaseLabel instead." }, "lowercase": { - "message": "Lowercase (a-z)", + "message": "אות קטנה (a-z)", "description": "deprecated. Use lowercaseLabel instead." }, "numbers": { - "message": "Numbers (0-9)", + "message": "מספרים (0-9)", "description": "deprecated. Use numbersLabel instead." }, "specialCharacters": { - "message": "Special characters (!@#$%^&*)", + "message": "תווים מיוחדים (*&^%$#@!)", "description": "deprecated. Use specialCharactersLabel instead." }, "include": { - "message": "Include", + "message": "כלול", "description": "Card header for password generator include block" }, "uppercaseDescription": { - "message": "Include uppercase characters", + "message": "כלול תווי אות גדולה", "description": "Tooltip for the password generator uppercase character checkbox" }, "uppercaseLabel": { @@ -495,7 +495,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": { @@ -503,7 +503,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": { @@ -511,15 +511,15 @@ "description": "Label for the password generator numbers checkbox" }, "specialCharactersDescription": { - "message": "Include special characters", + "message": "כלול תווים מיוחדים", "description": "Full description for the password generator special characters checkbox" }, "specialCharactersLabel": { - "message": "!@#$%^&*", + "message": "*&^%$#@!", "description": "Label for the password generator special characters checkbox" }, "numWords": { - "message": "מספר מילים" + "message": "מספר המילים" }, "wordSeparator": { "message": "מפריד מילים" @@ -535,14 +535,14 @@ "message": "מינימום ספרות" }, "minSpecial": { - "message": "מינימום תוים מיוחדים" + "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": { @@ -567,7 +567,7 @@ "message": "סיסמה" }, "totp": { - "message": "Authenticator secret" + "message": "סוד מאמת" }, "passphrase": { "message": "משפט סיסמה" @@ -576,7 +576,7 @@ "message": "מועדף" }, "unfavorite": { - "message": "Unfavorite" + "message": "מחק ממועדפים" }, "itemAddedToFavorites": { "message": "פריט נוסף למועדפים" @@ -588,7 +588,7 @@ "message": "הערות" }, "privateNote": { - "message": "Private note" + "message": "הערה פרטית" }, "note": { "message": "הערה" @@ -609,10 +609,10 @@ "message": "הפעל" }, "launchWebsite": { - "message": "Launch website" + "message": "פתח אתר" }, "launchWebsiteName": { - "message": "Launch website $ITEMNAME$", + "message": "פתח אתר $ITEMNAME$", "placeholders": { "itemname": { "content": "$1", @@ -624,7 +624,7 @@ "message": "אתר" }, "toggleVisibility": { - "message": "הצג או הסתר" + "message": "שנה נראות" }, "manage": { "message": "נהל" @@ -633,49 +633,49 @@ "message": "אחר" }, "unlockMethods": { - "message": "Unlock options" + "message": "אפשרויות ביטול נעילה" }, "unlockMethodNeededToChangeTimeoutActionDesc": { - "message": "Set up an unlock method to change your vault timeout action." + "message": "הגדר שיטת ביטול נעילה כדי לשנות את פעולת פסק זמן הכספת שלך." }, "unlockMethodNeeded": { - "message": "Set up an unlock method in Settings" + "message": "הגדר שיטת ביטול נעילה בהגדרות" }, "sessionTimeoutHeader": { - "message": "Session timeout" + "message": "זמן קצוב להפעלה" }, "vaultTimeoutHeader": { - "message": "Vault timeout" + "message": "זמן קצוב לכספת" }, "otherOptions": { - "message": "Other options" + "message": "אפשרויות אחרות" }, "rateExtension": { - "message": "דירוג הרחבה" + "message": "דרג את ההרחבה" }, "browserNotSupportClipboard": { "message": "הדפדפן שלך לא תומך בהעתקה ללוח. אנא העתק בצורה ידנית." }, "verifyIdentity": { - "message": "אימות זהות" + "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": "הכספת שלך נעולה. הזן את הסיסמה הראשית שלך כדי להמשיך." + "message": "הכספת שלך נעולה. אמת את זהותך כדי להמשיך." }, "yourVaultIsLockedV2": { - "message": "Your vault is locked" + "message": "הכספת שלך נעולה" }, "yourAccountIsLocked": { - "message": "Your account is locked" + "message": "החשבון שלך נעול" }, "or": { - "message": "or" + "message": "או" }, "unlock": { "message": "בטל נעילה" @@ -697,16 +697,16 @@ "message": "סיסמה ראשית שגויה" }, "vaultTimeout": { - "message": "משך זמן מירבי עבור חיבור לכספת" + "message": "פסק זמן כספת" }, "vaultTimeout1": { - "message": "Timeout" + "message": "פסק זמן" }, "lockNow": { "message": "נעל עכשיו" }, "lockAll": { - "message": "Lock all" + "message": "נעל הכל" }, "immediately": { "message": "באופן מיידי" @@ -742,7 +742,7 @@ "message": "4 שעות" }, "onLocked": { - "message": "בזמן נעילת המערכת" + "message": "בנעילת המערכת" }, "onRestart": { "message": "בהפעלת הדפדפן מחדש" @@ -754,16 +754,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": "אירעה שגיאה" @@ -775,13 +775,13 @@ "message": "כתובת אימייל לא תקינה." }, "masterPasswordRequired": { - "message": "Master password is required." + "message": "דרושה סיסמה ראשית." }, "confirmMasterPasswordRequired": { - "message": "Master password retype is required." + "message": "דרושה הקלדה מחדש של הסיסמה הראשית." }, "masterPasswordMinlength": { - "message": "Master password must be at least $VALUE$ characters long.", + "message": "סיסמה ראשית חייבת להיות לפחות באורך $VALUE$ תווים.", "description": "The Master Password must be at least a specific number of characters long.", "placeholders": { "value": { @@ -797,16 +797,16 @@ "message": "החשבון שלך נוצר בהצלחה! כעת ניתן להכנס למערכת." }, "newAccountCreated2": { - "message": "Your new account has been created!" + "message": "החשבון החדש שלך נוצר!" }, "youHaveBeenLoggedIn": { - "message": "You have been logged in!" + "message": "התחברת!" }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "התחברת בהצלחה" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "אתה רשאי לסגור חלון זה" }, "masterPassSent": { "message": "שלחנו לך אימייל עם רמז לסיסמה הראשית." @@ -815,7 +815,7 @@ "message": "נדרש קוד אימות." }, "webauthnCancelOrTimeout": { - "message": "The authentication was cancelled or took too long. Please try again." + "message": "האימות בוטל או לקח יותר מדי זמן. נא לנסות שוב." }, "invalidVerificationCode": { "message": "קוד אימות שגוי" @@ -831,58 +831,58 @@ } }, "autofillError": { - "message": "לא הצלחנו לבצע פעולת השלמה האוטומטית בעמוד זה. אנא העתק והדבק את המידע הנחוץ בצורה ידנית." + "message": "לא ניתן למלא אוטומטית את הפריט שנבחר בדף זה. העתק והדבק את המידע במקום זאת." }, "totpCaptureError": { - "message": "Unable to scan QR code from the current webpage" + "message": "אי אפשר לסרוק קוד QR מהדף הנוכחי" }, "totpCaptureSuccess": { - "message": "Authenticator key added" + "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" }, "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": "האם אתה בטוח שברצונך להתנתק?" @@ -900,28 +900,28 @@ "message": "דרוש שם." }, "addedFolder": { - "message": "נוספה תיקייה" + "message": "התיקייה נוספה" }, "twoStepLoginConfirmation": { - "message": "התחברות בשני-שלבים הופכת את החשבון שלך למאובטח יותר בכך שאתה נדרש לוודא בכל כניסה בעזרת מכשיר אחר כדוגמת מפתח אבטחה, תוכנת אימות, SMS, שיחת טלפון, או אימייל. ניתן להפעיל את \"התחברות בשני-שלבים\" בכספת שבאתר bitwarden.com. האם ברצונך לפתוח את האתר כעת?" + "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": "תיקייה שנערכה" + "message": "התיקייה נשמרה" }, "deleteFolderConfirmation": { "message": "האם אתה בטוח שברצונך למחוק את התיקייה?" }, "deletedFolder": { - "message": "תיקייה שנמחקה" + "message": "התיקייה נמחקה" }, "gettingStartedTutorial": { - "message": "מדריך שימוש ראשוני" + "message": "מדריך תחילת עבודה" }, "gettingStartedTutorialVideo": { "message": "צפה במדריך השימוש הראשוני כדי ללמוד איך לנצל את המקסימום שהתוסף לדפדפן יכול להציע." @@ -952,20 +952,20 @@ "message": "כתובת חדשה" }, "addDomain": { - "message": "Add domain", + "message": "הוסף דומיין", "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." }, "addedItem": { - "message": "פריט שהתווסף" + "message": "פריט נוסף" }, "editedItem": { - "message": "פריט שנערך" + "message": "פריט נשמר" }, "deleteItemConfirmation": { "message": "האם אתה בטוח שברצונך למחוק פריט זה?" }, "deletedItem": { - "message": "פריט נשלח לסל המחזור" + "message": "פריט נשלח לאשפה" }, "overwritePassword": { "message": "דרוס סיסמה" @@ -974,10 +974,10 @@ "message": "האם אתה בטוח שברצונך לדרוס את הסיסמה הנוכחית?" }, "overwriteUsername": { - "message": "Overwrite username" + "message": "החלף שם משתמש" }, "overwriteUsernameConfirmation": { - "message": "Are you sure you want to overwrite the current username?" + "message": "האם אתה בטוח שברצונך להחליף את שם המשתמש הנוכחי?" }, "searchFolder": { "message": "חפש תיקייה" @@ -993,37 +993,37 @@ "description": "This is the folder for uncategorized items" }, "enableAddLoginNotification": { - "message": "Ask to add login" + "message": "שאל אם לשמור פרטי כניסה" }, "vaultSaveOptionsTitle": { - "message": "Save to vault options" + "message": "שמור בהגדרות כספת" }, "addLoginNotificationDesc": { - "message": "ההודעה \"שמור פרטי כניסה\" מופיעה בכל פעם שתכנס לאתר חדש בפעם הראשונה." + "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": "Show cards on Tab page" + "message": "הצג כרטיסים בדף הכרטיסיות" }, "showCardsCurrentTabDesc": { - "message": "List card items on the Tab page for easy autofill." + "message": "רשום פריטי כרטיס בדף הכרטיסיות עבור מילוי אוטומטי קל." }, "showIdentitiesInVaultViewV2": { - "message": "Always show identities as Autofill suggestions on Vault view" + "message": "הצג תמיד זהויות כהצעות למילוי אוטומטי בתצוגת כספת" }, "showIdentitiesCurrentTab": { - "message": "Show identities on Tab page" + "message": "הצג זהויות בדף הכרטיסיות" }, "showIdentitiesCurrentTabDesc": { - "message": "List identity items on the Tab page for easy autofill." + "message": "הצג פריטי זהות בדף הכרטיסיות עבור מילוי אוטומטי קל." }, "clickToAutofillOnVault": { - "message": "Click items to autofill on Vault view" + "message": "לחץ על פריטים כדי למלא אוטומטית בתצוגת כספת" }, "clearClipboard": { "message": "נקה לוח העתקות", @@ -1037,53 +1037,53 @@ "message": "האם ברצונך שתוכנת Bitwarden תזכור סיסמה זו עבורך?" }, "notificationAddSave": { - "message": "כן, שמור עכשיו" + "message": "שמור" }, "enableChangedPasswordNotification": { - "message": "Ask to update existing login" + "message": "שאל אם לעדכן פרטי כניסה קיימת" }, "changedPasswordNotificationDesc": { - "message": "Ask to update a login's password when a change is detected on a website." + "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": "Ask to save and use passkeys" + "message": "שאל אם לשמור ולהשתמש במפתחות גישה" }, "usePasskeysDesc": { - "message": "Ask to save new passkeys or log in with passkeys stored in your vault. Applies to all logged in accounts." + "message": "שאל אם לשמור מפתחות גישה חדשים או להתחבר עם מפתחות גישה השמורים בכספת שלך. חל על כל המשתמשים המחוברים." }, "notificationChangeDesc": { "message": "האם ברצונך לעדכן את הסיסמה הזו בתוכנת Bitwarden?" }, "notificationChangeSave": { - "message": "כן, עדכן עכשיו" + "message": "עדכן" }, "notificationUnlockDesc": { - "message": "Unlock your Bitwarden vault to complete the autofill request." + "message": "בטל נעילת כספת ה־Bitwarden שלך כדי להשלים את בקשת המילוי האוטומטי." }, "notificationUnlock": { - "message": "Unlock" + "message": "בטל נעילה" }, "additionalOptions": { - "message": "Additional options" + "message": "אפשרויות נוספות" }, "enableContextMenuItem": { - "message": "Show context menu options" + "message": "הצג אפשרויות תפריט הקשר" }, "contextMenuItemDesc": { - "message": "Use a secondary click to access password generation and matching logins for the website." + "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": "ברירת מחדל לזיהוי התאמת כתובות", + "message": "ברירת מחדל לזיהוי התאמת URI", "description": "Default URI match detection for autofill." }, "defaultUriMatchDetectionDesc": { - "message": "בחר את שיטת ברירת המחדל עבור זיהוי התאמת כתובות כשמבצעים פעולות השלמה אוטומטית." + "message": "בחר את דרך ברירת המחדל לטיפול בזיהוי התאמת URI עבור כניסות כשמבצעים פעולות כגון מילוי אוטומטי." }, "theme": { "message": "ערכת נושא" @@ -1092,7 +1092,7 @@ "message": "שנה את ערכת הצבע של האפליקציה." }, "themeDescAlt": { - "message": "Change the application's color theme. Applies to all logged in accounts." + "message": "שנה את צבעי ערכת הנושא של היישום. חל על כל החשבונות המחוברים." }, "dark": { "message": "כהה", @@ -1103,52 +1103,52 @@ "description": "Light color" }, "solarizedDark": { - "message": "Solarized dark", + "message": "כהה סולארי", "description": "'Solarized' is a noun and the name of a color scheme. It should not be translated." }, "exportFrom": { - "message": "Export from" + "message": "ייצוא מ-" }, "exportVault": { - "message": "יצוא כספת" + "message": "ייצוא כספת" }, "fileFormat": { - "message": "פורמט קובץ" + "message": "פורמט הקובץ" }, "fileEncryptedExportWarningDesc": { - "message": "This file export will be password protected and require the file password to decrypt." + "message": "קובץ ייצוא זה יהיה מוגן סיסמה ודורש את סיסמת הקובץ כדי לפענח." }, "filePassword": { - "message": "File password" + "message": "סיסמת קובץ" }, "exportPasswordDescription": { - "message": "This password will be used to export and import this file" + "message": "סיסמה זו תשמש כדי לייצא ולייבא קובץ זה" }, "accountRestrictedOptionDescription": { - "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account." + "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": "Export type" + "message": "סוג ייצוא" }, "accountRestricted": { - "message": "Account restricted" + "message": "מוגבל חשבון" }, "filePasswordAndConfirmFilePasswordDoNotMatch": { - "message": "“File password” and “Confirm file password“ do not match." + "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": { - "message": "אישור ייצוא כספת" + "message": "אשר ייצוא הכספת" }, "exportWarningDesc": { "message": "הקובץ מכיל את פרטי הכספת שלך בפורמט לא מוצפן. מומלץ להעביר את הקובץ רק בדרכים מוצפנות, ומאוד לא מומלץ לשמור או לשלוח את הקובץ הזה בדרכים לא מוצפנות (כדוגמת סתם אימייל). מחק את הקובץ מיד לאחר שסיימת את השימוש בו." @@ -1157,7 +1157,7 @@ "message": "ייצוא זה מצפין את המידע שלך באמצעות שימוש במפתח ההצפנה של חשבונך. אם אי-פעם תבצע החלפה (רוטציה) למפתח ההצפנה של חשבונך, עליך לבצע ייצוא זה שוב אחרת לא תוכל לפענח קובץ ייצוא זה." }, "encExportAccountWarningDesc": { - "message": "Account encryption keys are unique to each Bitwarden user account, so you can't import an encrypted export into a different account." + "message": "מפתחות הצפנת חשבון הם ייחודים לכל חשבון משתמש Bitwarden, לכן אינך יכול לייבא ייצוא מוצפן לתוך חשבון אחר." }, "exportMasterPassword": { "message": "הזן את הסיסמה הראשית שלך עבור יצוא המידע מהכספת." @@ -1166,13 +1166,13 @@ "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 לעסקים מאפשר לך לשתף את פריטי הכספת שלך עם אחרים על ידי שימוש בארגון. למד עוד באתר האינטרנט bitwarden.com." }, "moveToOrganization": { - "message": "Move to organization" + "message": "העבר לארגון" }, "movedItemToOrg": { - "message": "$ITEMNAME$ הועבר ל- $ORGNAME$", + "message": "$ITEMNAME$ הועבר ל־$ORGNAME$", "placeholders": { "itemname": { "content": "$1", @@ -1185,13 +1185,13 @@ } }, "moveToOrgDesc": { - "message": "Choose an organization that you wish to move this item to. Moving to an organization transfers ownership of the item to that organization. You will no longer be the direct owner of this item once it has been moved." + "message": "בחר ארגון שאליו ברצונך להעביר פריט זה. העברה אל ארגון מעבירה בעלות של הפריט אל אותו ארגון. לא תוכל להיות הבעלים הישיר של פריט זה ברגע שהוא הועבר." }, "learnMore": { "message": "למידע נוסף" }, "authenticatorKeyTotp": { - "message": "מפתח אימות (TOTP)" + "message": "מפתח מאמת (TOTP)" }, "verificationCodeTotp": { "message": "קוד אימות (TOTP)" @@ -1209,61 +1209,61 @@ "message": "האם אתה בטוח שברצונך למחוק קובץ מצורף זה?" }, "deletedAttachment": { - "message": "קובץ מצורף שנמחק" + "message": "הקובץ המצורף נמחק" }, "newAttachment": { - "message": "צרף קובץ חדש" + "message": "צרף קובץ מצורף חדש" }, "noAttachments": { "message": "אין קבצים מצורפים." }, "attachmentSaved": { - "message": "הקובץ המצורף נשמר." + "message": "הקובץ המצורף נשמר" }, "file": { "message": "קובץ" }, "fileToShare": { - "message": "File to share" + "message": "קובץ לשיתוף" }, "selectFile": { - "message": "בחר קובץ." + "message": "בחר קובץ" }, "maxFileSize": { - "message": "גודל הקובץ המירבי הוא 500 מגה." + "message": "גודל הקובץ המרבי הוא 500MB." }, "featureUnavailable": { - "message": "יכולת זו לא זמינה" + "message": "תכונה זו לא זמינה" }, "encryptionKeyMigrationRequired": { - "message": "Encryption key migration required. Please login through the web vault to update your encryption key." + "message": "דרושה הגירת מפתח הצפנה. נא להתחבר דרך כספת הרשת כדי לעדכן את מפתח ההצפנה שלך." }, "premiumMembership": { - "message": "חשבון פרימיום" + "message": "חברות פרימיום" }, "premiumManage": { - "message": "נהל חשבון" + "message": "נהל חברות" }, "premiumManageAlert": { "message": "באפשרותך לנהל את החשבון שלך דרך הכספת באתר bitwarden.com. האם ברצונך לפתוח את האתר כעת?" }, "premiumRefresh": { - "message": "רענן פרטי חשבון" + "message": "רענן חברות" }, "premiumNotCurrentMember": { - "message": "חשבונך אינו חשבון פרמיום כרגע." + "message": "אתה לא כרגע חבר פרימיום." }, "premiumSignUpAndGet": { - "message": "צור חשבון פרמיום לשנה, וקבל:" + "message": "הרשם לחברות פרימיום וקבל:" }, "ppremiumSignUpStorage": { "message": "1 ג'יגה של מקום אחסון עבור קבצים מצורפים." }, "premiumSignUpEmergency": { - "message": "Emergency access." + "message": "גישת חירום." }, "premiumSignUpTwoStepOptions": { - "message": "Proprietary two-step login options such as YubiKey and Duo." + "message": "אפשרויות כניסה דו-שלבית קנייניות כגון YubiKey ו־Duo." }, "ppremiumSignUpReports": { "message": "היגיינת סיסמאות, מצב בריאות החשבון, ודיווחים מעודכנים על פרצות חדשות בכדי לשמור על הכספת שלך בטוחה." @@ -1275,25 +1275,22 @@ "message": "קדימות בתמיכה הטכנית." }, "ppremiumSignUpFuture": { - "message": "כל יכולות הפרימיום העתידיות שנפתח. עוד יכולות מגיעות בקרוב!" + "message": "כל תכונות הפרימיום העתידיות. עוד מגיעות בקרוב!" }, "premiumPurchase": { "message": "רכוש פרימיום" }, - "premiumPurchaseAlert": { - "message": "באפשרותך לרכוש מנוי פרימיום בכספת באתר bitwarden.com. האם ברצונך לפתוח את האתר כעת?" - }, "premiumPurchaseAlertV2": { - "message": "You can purchase Premium from your account settings on the Bitwarden web app." + "message": "אתה יכול לרכוש פרימיום מהגדרות החשבון שלך ביישום הרשת Bitwarden." }, "premiumCurrentMember": { - "message": "אתה מנוי פרימיום!" + "message": "אתה חבר פרימיום!" }, "premiumCurrentMemberThanks": { "message": "תודה על תמיכתך בBitwarden." }, "premiumFeatures": { - "message": "Upgrade to Premium and receive:" + "message": "שדרג לפרימיום וקבל:" }, "premiumPrice": { "message": "הכל רק ב$PRICE$ לשנה!", @@ -1305,7 +1302,7 @@ } }, "premiumPriceV2": { - "message": "All for just $PRICE$ per year!", + "message": "הכל תמורת $PRICE$ בלבד לשנה!", "placeholders": { "price": { "content": "$1", @@ -1317,28 +1314,28 @@ "message": "הרענון הושלם" }, "enableAutoTotpCopy": { - "message": "Copy TOTP automatically" + "message": "העתק TOTP אוטומטי" }, "disableAutoTotpCopyDesc": { - "message": "אם פרטי הכניסה שלך מקושרים לאפליקציית אימות, קוד האימות TOTP מועתק אוטומטית ללוח שלך ברגע שמתבצעת ההשלמה האוטומטית לטופס הכניסה." + "message": "אם לכניסה שלך יש מפתח מאמת, העתק את קוד האימות TOTP ללוח ההעתקה שלך כאשר אתה ממלא אוטומטית את הכניסה." }, "enableAutoBiometricsPrompt": { - "message": "Ask for biometrics on launch" + "message": "בקש זיהוי ביומטרי בפתיחה" }, "premiumRequired": { - "message": "נדרש חשבון פרימיום" + "message": "נדרש פרימיום" }, "premiumRequiredDesc": { - "message": "בכדי להשתמש ביכולת זו יש צורך בחשבון פרימיום." + "message": "יש צורך בחברות פרימיום כדי להשתמש בתכונה זו." }, "enterVerificationCodeApp": { "message": "הכנס את קוד האימות בן 6 הספרות מאפליקציית האימות שלך." }, "authenticationTimeout": { - "message": "Authentication timeout" + "message": "זמן קצוב לאימות" }, "authenticationSessionTimedOut": { - "message": "The authentication session timed out. Please restart the login process." + "message": "תם הזמן הקצוב לאימות ההפעלה. נא להתחיל מחדש את תהליך הכניסה." }, "enterVerificationCodeEmail": { "message": "הכנס את קוד האימות בן 6 הספרות שנשלח ל-$EMAIL$.", @@ -1374,47 +1371,47 @@ "message": "הכנס את מפתח האבטחה שלך אל כניסת ה-USB במחשבך. אם יש לו כפתור, לחץ עליו." }, "webAuthnNewTab": { - "message": "To start the WebAuthn 2FA verification. Click the button below to open a new tab and follow the instructions provided in the new tab." + "message": "על מנת להתחיל אימות WebAuthn דו-שלבי. לחץ על הכפתור למטה כדי לפתוח כרטיסייה חדשה ועקוב אחר ההוראות המסופקת בכרטיסייה החדשה." }, "webAuthnNewTabOpen": { - "message": "פתיחת לשונית חדשה" + "message": "פתח כרטיסייה חדשה" }, "webAuthnAuthenticate": { - "message": "Authenticate WebAuthn" + "message": "אמת WebAuthn" }, "loginUnavailable": { - "message": "פרטי כניסה לא זמינים" + "message": "כניסה לא זמינה" }, "noTwoStepProviders": { - "message": "כניסה דו-שלבית פעילה בחשבון זה, אך אף אחד מספקי הכניסה הדו-שלבית לא נתמכים בדפדפן זה." + "message": "לחשבון זה מוגדרת כניסה דו-שלבית, עם זאת, אף אחד מהספקים הדו-שלביים המוגדרים אינו נתמך על ידי דפדפן זה." }, "noTwoStepProviders2": { "message": "אנא השתמש בדפדפן נתמך (כמו לדוגמא Chrome) ו\\או הוסף ספק כניסה דו-שלבית הנתמך בדפדפן זה (כמו לדוגמא אפליקצית אימות)." }, "twoStepOptions": { - "message": "אפשרויות כניסה דו שלבית" + "message": "אפשרויות כניסה דו-שלבית" }, "recoveryCodeDesc": { - "message": "איבדת גישה לכל ספקי האימות הדו-שלבי שלך? השתמש בקוד השחזור בכדי לבטל את כל ספקי האימות הדו-שלבי דרך החשבון שלך." + "message": "איבדת גישה לכל הספקים הדו-שלביים שלך? השתמש בקוד השחזור שלך בכדי לבטל את כל ספקי האימות הדו-שלבי מהחשבון שלך." }, "recoveryCodeTitle": { "message": "קוד שחזור" }, "authenticatorAppTitle": { - "message": "אפליקציית אימות" + "message": "יישום מאמת" }, "authenticatorAppDescV2": { - "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "message": "הזן קוד שנוצר על ידי יישום מאמת כמו מאמת Bitwarden.", "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, "yubiKeyTitleV2": { - "message": "Yubico OTP Security Key" + "message": "מפתח אבטחה OTP של YubiKey" }, "yubiKeyDesc": { "message": "השתמש בYubiKey עבור גישה לחשבון שלך. עובד עם YubiKey בגירסאות 4, 4C, 4Nano, ומכשירי 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": { @@ -1425,28 +1422,28 @@ "message": "FIDO2 WebAuthn" }, "webAuthnDesc": { - "message": "Use any WebAuthn compatible security key to access your account." + "message": "השתמש בכל מפתח אבטחה תואם WebAuthn כדי לגשת לחשבונך." }, "emailTitle": { "message": "אימייל" }, "emailDescV2": { - "message": "Enter a code sent to your email." + "message": "הזן קוד שנשלח לדוא\"ל שלך." }, "selfHostedEnvironment": { - "message": "סביבה על שרתים מקומיים" + "message": "סביבה באירוח עצמי" }, "selfHostedEnvironmentFooter": { "message": "הזן את כתובת השרת המקומי של Bitwarden." }, "selfHostedBaseUrlHint": { - "message": "Specify the base URL of your on-premises hosted Bitwarden installation. Example: https://bitwarden.company.com" + "message": "ציין את בסיס ה־URL של התקנת Bitwarden באירוח מקומי שלך. דוגמה: https://bitwarden.company.com" }, "selfHostedCustomEnvHeader": { - "message": "For advanced configuration, you can specify the base URL of each service independently." + "message": "עבור תצורות מתקדמות, באפשרותך לציין את בסיס ה־URL של כל שירות בנפרד." }, "selfHostedEnvFormInvalid": { - "message": "You must add either the base Server URL or at least one custom environment." + "message": "אתה מוכרח להוסיף או את בסיס ה־URL של השרת או לפחות סביבה מותאמת אישית אחת." }, "customEnvironment": { "message": "סביבה מותאמת אישית" @@ -1458,102 +1455,102 @@ "message": "כתובת שרת" }, "selfHostBaseUrl": { - "message": "Self-host server URL", + "message": "URL שרת אירוח עצמי", "description": "Label for field requesting a self-hosted integration service URL" }, "apiUrl": { - "message": "כתובת שרת הAPI" + "message": "URL של שרת ה־API" }, "webVaultUrl": { - "message": "כתובת שרת הכספת" + "message": "URL של שרת כספת הרשת" }, "identityUrl": { - "message": "כתובת שרת הזהות" + "message": "URL של שרת הזהות" }, "notificationsUrl": { - "message": "כתובת שרת הודעות" + "message": "URL של שרת ההודעות" }, "iconsUrl": { - "message": "כתובת שרת אייקונים" + "message": "URL של שרת הסמלים" }, "environmentSaved": { - "message": "כתובות הסביבה נשמרו." + "message": "URL־ים של הסביבה נשמרו" }, "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": "הצעות למילוי אוטומטי" }, "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": "Edit browser settings." + "message": "ערוך הגדרות דפדפן." }, "autofillOverlayVisibilityOff": { - "message": "Off", + "message": "כבוי", "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": "הפעל השלמה אוטומטית בזמן טעינת העמוד" + "message": "מילוי אוטומטי בעת טעינת עמוד" }, "enableAutoFillOnPageLoadDesc": { - "message": "אם זוהה טופס כניסה, בצע אוטומטית מילוי-אוטומטי כשהעמוד נטען." + "message": "אם זוהה טופס כניסה, בצע מילוי אוטומטי כשהעמוד נטען." }, "experimentalFeature": { - "message": "Compromised or untrusted websites can exploit autofill on page load." + "message": "אתרים פרוצים או לא מהימנים יכולים לנצל מילוי אוטומטי בעת טעינת עמוד." }, "learnMoreAboutAutofillOnPageLoadLinkText": { - "message": "Learn more about risks" + "message": "למד עוד על סיכונים" }, "learnMoreAboutAutofill": { - "message": "Learn more about autofill" + "message": "למד עוד על מילוי אוטומטי" }, "defaultAutoFillOnPageLoad": { - "message": "הגדרת ברירת מחדל למילוי אוטומטי של פרטי התחברות" + "message": "הגדרת ברירת המחדל של מילוי אוטומטי לפריטי כניסה" }, "defaultAutoFillOnPageLoadDesc": { - "message": "לאחר הפעלת מילוי אוטומטי של פרטים בעת טעינת דפים, אפשר להפעיל או לכבות את האפשרות לפרטי התחברות ספציפיים. זו הגדרת ברירת המחדל לפרטי התחברות שלא הוגדרו בנפרד." + "message": "אתה יכול לכבות מילוי אוטומטי בעת טעינת עמוד עבור פריטי כניסה בודדים מתצוגת העריכה של הפריט." }, "itemAutoFillOnPageLoad": { - "message": "מילוי אוטומטי בעת טעינת דפים (אם מופעל בהגדרות)" + "message": "מילוי אוטומטי בעת טעינת עמוד (אם מוגדר באפשרויות)" }, "autoFillOnPageLoadUseDefault": { - "message": "שימוש בהגדרות ברירת המחדל" + "message": "השתמש בהגדרת ברירת המחדל" }, "autoFillOnPageLoadYes": { - "message": "מילוי אוטומטי אחרי טעינת דפים" + "message": "מילוי אוטומטי בעת טעינת עמוד" }, "autoFillOnPageLoadNo": { - "message": "Do not autofill on page load" + "message": "אל תמלא אוטומטית בעת טעינת עמוד" }, "commandOpenPopup": { "message": "פתיחת כספת בחלונית צפה" @@ -1562,13 +1559,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": "צור והעתק סיסמה רנדומלית חדשה." @@ -1601,7 +1598,7 @@ "message": "אמת או שקר" }, "cfTypeCheckbox": { - "message": "Checkbox" + "message": "תיבת סימון" }, "cfTypeLinked": { "message": "מקושר", @@ -1618,19 +1615,19 @@ "message": "דפדפן זה לא יכול לעבד בקשות U2F בחלון צף זה. האם ברצונך לפתוח את החלון הצף כחלון חדש רגיל כדי שתוכל להכנס באמצעות U2F?" }, "enableFavicon": { - "message": "Show website icons" + "message": "הצג סמלים של אתרי אינטרנט" }, "faviconDesc": { - "message": "Show a recognizable image next to each login." + "message": "הצג תמונה ניתנת לזיהוי ליד כל כניסה." }, "faviconDescAlt": { - "message": "Show a recognizable image next to each login. Applies to all logged in accounts." + "message": "הצג תמונה ניתנת לזיהוי ליד כל כניסה. חל על כל החשבונות המחוברים." }, "enableBadgeCounter": { - "message": "Show badge counter" + "message": "הצג מונה סמל" }, "badgeCounterDesc": { - "message": "Indicate how many logins you have for the current web page." + "message": "מציין כמה כניסות יש לך עבור דף הרשת הנוכחי." }, "cardholderName": { "message": "שם בעל הכרטיס" @@ -1642,10 +1639,10 @@ "message": "מותג" }, "expirationMonth": { - "message": "תוקף אשראי - חודש" + "message": "חודש תפוגה" }, "expirationYear": { - "message": "תוקף אשראי - שנה" + "message": "שנת תפוגה" }, "expiration": { "message": "תוקף" @@ -1708,7 +1705,7 @@ "message": "דוקטור" }, "mx": { - "message": "Mx" + "message": "מיקס" }, "firstName": { "message": "שם פרטי" @@ -1729,13 +1726,13 @@ "message": "חברה" }, "ssn": { - "message": "מספר ביטוח לאומי" + "message": "מספר תעודת זהות" }, "passportNumber": { "message": "מספר דרכון" }, "licenseNumber": { - "message": "מספר רשיון" + "message": "מספר רישיון" }, "email": { "message": "אימייל" @@ -1786,10 +1783,10 @@ "message": "זהות" }, "typeSshKey": { - "message": "SSH key" + "message": "מפתח SSH" }, "newItemHeader": { - "message": "New $TYPE$", + "message": "$TYPE$ חדש", "placeholders": { "type": { "content": "$1", @@ -1798,7 +1795,7 @@ } }, "editItemHeader": { - "message": "Edit $TYPE$", + "message": "ערוך $TYPE$", "placeholders": { "type": { "content": "$1", @@ -1807,7 +1804,7 @@ } }, "viewItemHeader": { - "message": "View $TYPE$", + "message": "הצג $TYPE$", "placeholders": { "type": { "content": "$1", @@ -1819,13 +1816,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": "הקודם" @@ -1834,7 +1831,7 @@ "message": "אוספים" }, "nCollections": { - "message": "$COUNT$ collections", + "message": "$COUNT$ אוספים", "placeholders": { "count": { "content": "$1", @@ -1861,10 +1858,10 @@ "message": "פרטי התחברות" }, "secureNotes": { - "message": "פתקים מאובטחים" + "message": "הערות מאובטחות" }, "sshKeys": { - "message": "SSH Keys" + "message": "מפתחות SSH" }, "clear": { "message": "נקה", @@ -1890,11 +1887,11 @@ "description": "Domain name. Ex. website.com" }, "baseDomainOptionRecommended": { - "message": "Base domain (recommended)", + "message": "בסיס דומיין (מומלץ)", "description": "Domain name. Ex. website.com" }, "domainName": { - "message": "שם תחום", + "message": "שם דומיין", "description": "Domain name. Ex. website.com" }, "host": { @@ -1944,13 +1941,13 @@ "message": "אין סיסמאות להצגה ברשימה." }, "clearHistory": { - "message": "Clear history" + "message": "נקה היסטוריה" }, "nothingToShow": { - "message": "Nothing to show" + "message": "אין מה להראות" }, "nothingGeneratedRecently": { - "message": "You haven't generated anything recently" + "message": "לא חוללת כלום לאחרונה" }, "remove": { "message": "הסר" @@ -1963,7 +1960,7 @@ "description": "ex. Date this item was updated" }, "dateCreated": { - "message": "Created", + "message": "נוצר", "description": "ex. Date this item was created" }, "datePasswordUpdated": { @@ -2011,16 +2008,16 @@ "message": "בטל נעילה עם קוד PIN" }, "setYourPinTitle": { - "message": "Set PIN" + "message": "הגדר PIN" }, "setYourPinButton": { - "message": "Set PIN" + "message": "הגדר PIN" }, "setYourPinCode": { "message": "קבע קוד PIN לביטול נעילת Bitwarden. הגדרות הPIN יאופסו אם תבצע יציאה מהתוכנה." }, "setYourPinCode1": { - "message": "Your PIN will be used to unlock Bitwarden instead of your master password. Your PIN will reset if you ever fully log out of Bitwarden." + "message": "ה־PIN שלך ישמש לביטול נעילת Bitwarden במקום הסיסמה הראשית שלך. ה־PIN שלך יאופס אם אי פעם תצא באופן מלא מ־Bitwarden." }, "pinRequired": { "message": "נדרש קוד PIN." @@ -2029,25 +2026,25 @@ "message": "קוד PIN לא תקין." }, "tooManyInvalidPinEntryAttemptsLoggingOut": { - "message": "Too many invalid PIN entry attempts. Logging out." + "message": "יותר מדי ניסיונות פסולים להזנת PIN. מתנתק." }, "unlockWithBiometrics": { "message": "פתח נעילה עם זיהוי ביומטרי" }, "unlockWithMasterPassword": { - "message": "Unlock with master password" + "message": "בטל נעילה עם סיסמה ראשית" }, "awaitDesktop": { "message": "ממתין לאישור משולחן העבודה" }, "awaitDesktopDesc": { - "message": "אנא אשר בעזרת אמצעים ביומטרים באפליקציית Bitwarden של שולחן העבודה בכדי לאפשר אמצעים ביומטריים בדפדפן." + "message": "אנא אשר באמצעות זיהוי ביומטרי ביישום Bitwarden של שולחן העבודה בכדי להגדיר זיהוי ביומטרי עבור דפדפן." }, "lockWithMasterPassOnRestart": { "message": "נעל בעזרת הסיסמה הראשית בהפעלת הדפדפן מחדש" }, "lockWithMasterPassOnRestart1": { - "message": "Require master password on browser restart" + "message": "דרוש סיסמה ראשית בעת הפעלה מחדש של הדפדפן" }, "selectOneCollection": { "message": "עליך לבחור לפחות אוסף אחד." @@ -2059,33 +2056,36 @@ "message": "שכפול" }, "passwordGenerator": { - "message": "Password generator" + "message": "מחולל סיסמאות" }, "usernameGenerator": { - "message": "Username generator" + "message": "מחולל שם משתמש" + }, + "useThisEmail": { + "message": "השתמש בדוא\"ל זה" }, "useThisPassword": { - "message": "Use this password" + "message": "השתמש בסיסמה זו" }, "useThisUsername": { - "message": "Use this username" + "message": "השתמש בשם משתמש זה" }, "securePasswordGenerated": { - "message": "Secure password generated! Don't forget to also update your password on the website." + "message": "סיסמה מאובטחת נוצרה! אל תשכח גם לעדכן את הסיסמה שלך באתר האינטרנט." }, "useGeneratorHelpTextPartOne": { - "message": "Use the generator", + "message": "השתמש במחולל", "description": "This will be used as part of a larger sentence, broken up to include the generator icon. The full sentence will read 'Use the generator [GENERATOR_ICON] to create a strong unique password'" }, "useGeneratorHelpTextPartTwo": { - "message": "to create a strong unique password", + "message": "כדי ליצור סיסמה חזקה וייחודית", "description": "This will be used as part of a larger sentence, broken up to include the generator icon. The full sentence will read 'Use the generator [GENERATOR_ICON] to create a strong unique password'" }, "vaultTimeoutAction": { - "message": "פעולה לביצוע בכספת בתום זמן החיבור" + "message": "פעולת פסק זמן כספת" }, "vaultTimeoutAction1": { - "message": "Timeout action" + "message": "פעולת פסק זמן" }, "lock": { "message": "נעילה", @@ -2099,52 +2099,52 @@ "message": "חפש בסל המחזור" }, "permanentlyDeleteItem": { - "message": "מחק לצמיתות פריט שנבחר" + "message": "מחק פריט לצמיתות" }, "permanentlyDeleteItemConfirmation": { "message": "האם אתה בטוח שברצונך למחוק את הפריט הזה?" }, "permanentlyDeletedItem": { - "message": "פריט שנמחק לצמיתות" + "message": "הפריט נמחק לצמיתות" }, "restoreItem": { "message": "שחזר פריט" }, "restoredItem": { - "message": "פריט ששוחזר" + "message": "הפריט שוחזר" }, "alreadyHaveAccount": { - "message": "Already have an account?" + "message": "כבר יש לך חשבון?" }, "vaultTimeoutLogOutConfirmation": { "message": "יציאה מהחשבון תסיר את כל הגישה לכספת ויידרש אימות מקוון לאחר משך הזמן שהוקצב. האם אתה בטוח שברצונך להשתמש בהגדרה זו?" }, "vaultTimeoutLogOutConfirmationTitle": { - "message": "אישור פעולת אימות לאחר חוסר פעילות" + "message": "אישור פעולת פסק זמן" }, "autoFillAndSave": { - "message": "בצע השלמה אוטומטית ושמור" + "message": "מלא אוטומטית ושמור" }, "fillAndSave": { - "message": "Fill and save" + "message": "מלא ושמור" }, "autoFillSuccessAndSavedUri": { - "message": "בוצעה השלמה אוטומטית והכתובת נשמרה" + "message": "פריט התמלא אוטומטית וה־URI נשמר" }, "autoFillSuccess": { - "message": "בוצעה השלמה אוטומטית" + "message": "פריט התמלא אוטומטית " }, "insecurePageWarning": { - "message": "Warning: This is an unsecured HTTP page, and any information you submit can potentially be seen and changed by others. This Login was originally saved on a secure (HTTPS) page." + "message": "אזהרה: זהו דף HTTP לא מאובטח, וכל מידע שאתה שולח יכול באופן פוטנציאלי להיראות ולהשתנות על ידי אחרים. הכניסה הזאת נשמרה במקור בדף מאובטח (HTTPS)." }, "insecurePageWarningFillPrompt": { - "message": "Do you still wish to fill this login?" + "message": "האם עדיין ברצונך להשלים כניסה זו?" }, "autofillIframeWarning": { - "message": "The form is hosted by a different domain than the URI of your saved login. Choose OK to autofill anyway, or Cancel to stop." + "message": "הטופס מאורח על ידי דומיין שונה מה־URI של הכניסה השמורה שלך. בחר \"בסדר\" כדי להשלים אוטומטית בכל זאת, או \"ביטול\" כדי לעצור." }, "autofillIframeWarningTip": { - "message": "To prevent this warning in the future, save this URI, $HOSTNAME$, to your Bitwarden login item for this site.", + "message": "כדי למנוע אזהרה זו בעתיד, שמור את URI זה, $HOSTNAME$, בפריט כניסת Bitwarden שלך עבור אתר זה.", "placeholders": { "hostname": { "content": "$1", @@ -2156,13 +2156,13 @@ "message": "הגדר סיסמה ראשית" }, "currentMasterPass": { - "message": "Current master password" + "message": "סיסמה ראשית נוכחית" }, "newMasterPass": { - "message": "New master password" + "message": "סיסמה ראשית חדשה" }, "confirmNewMasterPass": { - "message": "Confirm new master password" + "message": "אמת סיסמה ראשית חדשה" }, "masterPasswordPolicyInEffect": { "message": "אחד או יותר מאילוצי המדיניות של הארגון דורשים שהסיסמה הראשית שלך תעמוד בדרישות הבאות:" @@ -2207,25 +2207,25 @@ "message": "הסיסמה הראשית החדשה השלך לא עומדת בדרישות המדיניות." }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "קבל עצות, הכרזות, והזדמנויות מחקר מאת Bitwarden בדואר הנכנס שלך." }, "unsubscribe": { - "message": "Unsubscribe" + "message": "בטל הרשמה" }, "atAnyTime": { - "message": "at any time." + "message": "בכל זמן." }, "byContinuingYouAgreeToThe": { - "message": "By continuing, you agree to the" + "message": "על ידי המשך אתה מסכים ל" }, "and": { - "message": "and" + "message": "ו" }, "acceptPolicies": { "message": "סימון תיבה זו מהווה את הסכמתך לתנאים הבאים:" }, "acceptPoliciesRequired": { - "message": "Terms of Service and Privacy Policy have not been acknowledged." + "message": "תנאי השימוש ומדיניות הפרטיות לא הוכרו." }, "termsOfService": { "message": "תנאי השירות" @@ -2240,10 +2240,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": "אימות סנכרון מול שולחן העבודה" @@ -2252,19 +2252,19 @@ "message": "אנא ודא כי אפליקציית שולחן העבודה שלך מציגה את טביעת האצבע הזו: " }, "desktopIntegrationDisabledTitle": { - "message": "אינטגרציית הדפדפן לא מופעלת" + "message": "שילוב הדפדפן אינו מוגדר" }, "desktopIntegrationDisabledDesc": { - "message": "אינטגרציית הדפדפן לא מופעלת באפליקציית Bitwarden בשולחן העבודה. אנא אפשר זאת בהגדרות האפליקציה." + "message": "שילוב הדפדפן אינו מוגדר ביישום Bitwarden של שולחן העבודה. אנא הגדר אותו בהגדרות שבתוך יישום שולחן העבודה." }, "startDesktopTitle": { - "message": "הפעל את אפליקציית Bitwarden בשולחן העבודה" + "message": "הפעל את יישום Bitwarden של שולחן העבודה" }, "startDesktopDesc": { - "message": "יש להפעיל את אפליקציית Bitwarden בשולחן העבודה בכדי להשתמש בפונקציה זו." + "message": "היישום Bitwarden של שולחן העבודה צריך להיות מופעל לפני שניתן לבטל נעילה עם זיהוי ביומטרי." }, "errorEnableBiometricTitle": { - "message": "לא ניתן להפעיל זיהוי ביומטרי" + "message": "לא ניתן להגדיר זיהוי ביומטרי" }, "errorEnableBiometricDesc": { "message": "הפעולה בוטלה על ידי אפליקציית שולחן העבודה" @@ -2282,16 +2282,16 @@ "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": "אמצעי זיהוי ביומטרים לא מאופשרים" + "message": "זיהוי ביומטרי אינו מוגדר" }, "biometricsNotEnabledDesc": { - "message": "בכדי להשתמש באמצעים ביומטרים בדפדפן יש לאפשר תכונה זו באפליקציה בשולחן העבודה." + "message": "זיהוי ביומטרי בדפדפן דורש שזיהוי ביומטרי בשולחן העבודה יהיה מוגדר בהגדרות קודם." }, "biometricsNotSupportedTitle": { "message": "אמצעי זיהוי ביומטרים לא נתמכים" @@ -2300,22 +2300,22 @@ "message": "מכשיר זה לא תומך בזיהוי ביומטרי בדפדפן." }, "biometricsNotUnlockedTitle": { - "message": "User locked or logged out" + "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": "Biometrics failed" + "message": "זיהוי ביומטרי נכשל" }, "biometricsFailedDesc": { - "message": "Biometrics cannot be completed, consider using a master password or logging out. If this persists, please contact Bitwarden support." + "message": "לא ניתן להשלים זיהוי ביומטרי, שקול להשתמש במפתח ראשי או להתנתק. אם הדבר נמשך, אנא צור קשר עם תמיכת Bitwarden." }, "nativeMessaginPermissionErrorTitle": { "message": "הרשאה לא סופקה" @@ -2324,47 +2324,111 @@ "message": "ללא הרשאות לתקשר עם אפליקציית שולחן העבודה אין באפשרותנו לספק תמיכה באמצעים ביומטריים בדפדפן. אנא נסה שוב." }, "nativeMessaginPermissionSidebarTitle": { - "message": "Permission request error" + "message": "שגיאת בקשת הרשאה" }, "nativeMessaginPermissionSidebarDesc": { - "message": "This action cannot be done in the sidebar, please retry the action in the popup or popout." + "message": "לא ניתן לבצע את הפעולה בסרגל הצד, נא לנסות שוב את הפעולה בחלון המוקפץ או המנותק." }, "personalOwnershipSubmitError": { - "message": "מדיניות הארגון מונעת ממך לשמור פריטים בכספת האישית. שנה את אפשרות הבעלות לארגוניות ובחר מתוך האוספים הזמינים." + "message": "בשל שגיאה ארגונית, אתה מוגבל מלשמור פריטים לכספת האישית שלך. שנה את אפשרות הבעלות לארגון ובחר מאוספים זמינים." }, "personalOwnershipPolicyInEffect": { "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": "דומיינים חסומים" }, "excludedDomains": { - "message": "Excluded domains" + "message": "דומיינים מוחרגים" }, "excludedDomainsDesc": { - "message": "Bitwarden will not ask to save login details for these domains. You must refresh the page for changes to take effect." + "message": "Bitwarden לא יבקש לשמור פרטי כניסה עבור הדומיינים האלה. אתה מוכרח לרענן את העמוד כדי שהשינויים ייכנסו לתוקף." }, "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": "שינוי" + }, + "changeButtonTitle": { + "message": "שנה סיסמה - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "סיסמאות בסכנה" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ מבקש/ת שתשנה $COUNT$ סיסמאות בגלל שהן בסכנה.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "הארגונים שלך מבקשים שתשנה $COUNT$ סיסמאות בגלל שהן בסכנה.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "סקור ושנה סיסמה אחת בסכנה" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "סקור ושנה $COUNT$ סיסמאות בסכנה", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "שנה סיסמאות בסכנה מהר יותר" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "עדכן את ההגדרות שלך כך שתוכל למלא במהירות את הסיסמאות שלך וליצור חדשות" + }, + "turnOnAutofill": { + "message": "הפעל השלמה אוטומטית" + }, + "turnedOnAutofill": { + "message": "השלמה אוטומטית הופעלה" + }, + "dismiss": { + "message": "התעלם" }, "websiteItemLabel": { - "message": "Website $number$ (URI)", + "message": "אתר אינטרנט $number$ (URI)", "placeholders": { "number": { "content": "$1", @@ -2373,7 +2437,7 @@ } }, "excludedDomainsInvalidDomain": { - "message": "$DOMAIN$ is not a valid domain", + "message": "$DOMAIN$ אינו דומיין חוקי", "placeholders": { "domain": { "content": "$1", @@ -2382,20 +2446,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": { @@ -2405,93 +2469,93 @@ } }, "send": { - "message": "Send", + "message": "שליחה", "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": "Text" + "message": "טקסט" }, "sendTypeTextToShare": { - "message": "Text to share" + "message": "טקסט לשיתוף" }, "sendTypeFile": { - "message": "File" + "message": "קובץ" }, "allSends": { - "message": "All Sends", + "message": "כל הסנדים", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "hideTextByDefault": { - "message": "Hide text by default" + "message": "הסתר טקסט כברירת מחדל" }, "expired": { - "message": "Expired" + "message": "פג תוקף" }, "passwordProtected": { - "message": "Password protected" + "message": "מוגן סיסמה" }, "copyLink": { - "message": "Copy link" + "message": "העתק קישור" }, "copySendLink": { - "message": "Copy Send link", + "message": "העתק קישור סנד", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "removePassword": { - "message": "Remove Password" + "message": "הסר סיסמה" }, "delete": { - "message": "Delete" + "message": "מחק" }, "removedPassword": { - "message": "Password removed" + "message": "סיסמה הוסרה" }, "deletedSend": { - "message": "Send deleted", + "message": "סנד נמחק", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendLink": { - "message": "Send link", + "message": "שלח קישור", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "disabled": { - "message": "Disabled" + "message": "מושבת" }, "removePasswordConfirmation": { - "message": "Are you sure you want to remove the password?" + "message": "האם אתה בטוח שברצונך להסיר את הסיסמה?" }, "deleteSend": { - "message": "Delete Send", + "message": "מחק סנד", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "deleteSendConfirmation": { - "message": "Are you sure you want to delete this Send?", + "message": "האם אתה בטוח שברצונך למחוק סנד זה?", "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": { - "message": "Edit Send", + "message": "ערוך סנד", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "deletionDate": { "message": "תאריך מחיקה" }, "deletionDateDescV2": { - "message": "The Send will be permanently deleted on this date.", + "message": "סנד זה יימחק לצמיתות בתאריך זה.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "expirationDate": { "message": "תאריך תפוגה" }, "oneDay": { - "message": "יום אחד" + "message": "יום 1" }, "days": { "message": "$DAYS$ ימים", @@ -2506,38 +2570,38 @@ "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": { - "message": "New Send", + "message": "סנד חדש", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "newPassword": { - "message": "New password" + "message": "סיסמה חדשה" }, "sendDisabled": { - "message": "Send removed", + "message": "סנד הוסר", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendDisabledWarning": { - "message": "Due to an enterprise policy, you are only able to delete an existing Send.", + "message": "בשל מדיניות ארגונית, אתה רק יכול למחוק את הסנד הנוכחי.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "createdSend": { - "message": "Send created", + "message": "סנד נוצר", "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": { @@ -2547,11 +2611,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": { @@ -2561,98 +2625,98 @@ } }, "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": { - "message": "Send saved", + "message": "סנד נשמר", "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": { - "message": "In order to choose a file, open the extension in the sidebar (if possible) or pop out to a new window by clicking this banner." + "message": "כדי לבחור קובץ, פתח את ההרחבה בסרגל הצד (אם ניתן) או נתק לחלון חדש על ידי לחיצת באנר זה." }, "sendFirefoxFileWarning": { - "message": "In order to choose a file using Firefox, open the extension in the sidebar or pop out to a new window by clicking this banner." + "message": "כדי לבחור קובץ באמצעות Firefox, פתח את ההרחבה בסרגל הצד או נתק לחלון חדש על ידי לחיצת באנר זה." }, "sendSafariFileWarning": { - "message": "In order to choose a file using Safari, pop out to a new window by clicking this banner." + "message": "כדי לבחור קובץ באמצעות Safari, נתק לחלון חדש על ידי לחיצת באנר זה." }, "popOut": { - "message": "Pop out" + "message": "נתק" }, "sendFileCalloutHeader": { - "message": "Before you start" + "message": "לפני שאתה מתחיל" }, "expirationDateIsInvalid": { - "message": "The expiration date provided is not valid." + "message": "תאריך התפוגה שסופק אינו חוקי." }, "deletionDateIsInvalid": { - "message": "The deletion date provided is not valid." + "message": "תאריך המחיקה שסופק אינו חוקי." }, "expirationDateAndTimeRequired": { - "message": "An expiration date and time are required." + "message": "דרושים תאריך תפוגה וזמן." }, "deletionDateAndTimeRequired": { - "message": "A deletion date and time are required." + "message": "דרושים תאריך מחיקה וזמן." }, "dateParsingError": { - "message": "There was an error saving your deletion and expiration dates." + "message": "הייתה שגיאה בשמירת תאריכי המחיקה והתפוגה שלך." }, "hideYourEmail": { - "message": "Hide your email address from viewers." + "message": "הסתר את כתובת הדוא\"ל שלך מצופים." }, "passwordPrompt": { - "message": "Master password re-prompt" + "message": "בקשת סיסמה ראשית חוזרת" }, "passwordConfirmation": { - "message": "Master password confirmation" + "message": "אישור סיסמה ראשית" }, "passwordConfirmationDesc": { - "message": "This action is protected. To continue, please re-enter your master password to verify your identity." + "message": "פעולה זו מוגנת. כדי להמשיך, נא להזין שוב את הסיסמה הראשית שלך כדי לאמת את זהותך." }, "emailVerificationRequired": { - "message": "Email verification required" + "message": "דרוש אימות דוא\"ל" }, "emailVerifiedV2": { - "message": "Email verified" + "message": "דוא\"ל אומת" }, "emailVerificationRequiredDesc": { - "message": "You must verify your email to use this feature. You can verify your email in the web vault." + "message": "עליך לאמת את הדוא\"ל שלך כדי להשתמש בתכונה זו. ניתן לאמת את הדוא\"ל שלך בכספת הרשת." }, "updatedMasterPassword": { - "message": "Updated master password" + "message": "סיסמה ראשית עודכנה" }, "updateMasterPassword": { - "message": "Update master password" + "message": "עדכן סיסמה ראשית" }, "updateMasterPasswordWarning": { - "message": "Your master password was recently changed by an administrator in your organization. In order to access the vault, you must update it now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour." + "message": "הסיסמה הראשית שלך שונתה לאחרונה על ידי מנהל הארגון שלך. כדי לגשת לכספת, עליך לעדכן אותה כעת. בהמשך תנותק מההפעלה הנוכחית שלך ותידרש להיכנס חזרה. הפעלות פעילות במכשירים אחרים עלולות להישאר פעילות למשך עד שעה אחת." }, "updateWeakMasterPasswordWarning": { - "message": "Your master password does not meet one or more of your organization policies. In order to access the vault, you must update your master password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour." + "message": "הסיסמה הראשית שלך אינה עומדת באחת או יותר ממדיניות הארגון שלך. כדי לגשת לכספת, אתה מוכרח לעדכן את הסיסמה הראשית שלך עכשיו. בהמשך תנותק מההפעלה הנוכחית שלך ותידרש להיכנס חזרה. הפעלות פעילות במכשירים אחרים עלולות להישאר פעילות למשך עד שעה אחת." }, "tdeDisabledMasterPasswordRequired": { - "message": "Your organization has disabled trusted device encryption. Please set a master password to access your vault." + "message": "הארגון שלך השבית הצפנת מכשיר מהימן. נא להגדיר סיסמה ראשית כדי לגשת לכספת שלך." }, "resetPasswordPolicyAutoEnroll": { - "message": "Automatic enrollment" + "message": "רישום אוטומטי" }, "resetPasswordAutoEnrollInviteWarning": { - "message": "This organization has an enterprise policy that will automatically enroll you in password reset. Enrollment will allow organization administrators to change your master password." + "message": "לארגון זה יש מדיניות ארגונית שתרשום אותך אוטומטי לאיפוס סיסמה. הרישום יאפשר למנהלי הארגון לשנות את הסיסמה הראשית שלך." }, "selectFolder": { - "message": "Select folder..." + "message": "בחר תיקיה..." }, "noFoldersFound": { - "message": "No folders found", + "message": "לא נמצאו תיקיות", "description": "Used as a message within the notification bar when no folders are found" }, "orgPermissionsUpdatedMustSetPassword": { @@ -2664,7 +2728,7 @@ "description": "Used as a card title description on the set password page to explain why the user is there" }, "cardMetrics": { - "message": "out of $TOTAL$", + "message": "מתוך $TOTAL$", "placeholders": { "total": { "content": "$1", @@ -2673,20 +2737,20 @@ } }, "verificationRequired": { - "message": "Verification required", + "message": "דרוש אימות", "description": "Default title for the user verification dialog." }, "hours": { - "message": "Hours" + "message": "שעות" }, "minutes": { - "message": "Minutes" + "message": "דקות" }, "vaultTimeoutPolicyAffectingOptions": { - "message": "Enterprise policy requirements have been applied to your timeout options" + "message": "דרישות מדיניות ארגונית הוחלו על אפשרויות פסק הזמן שלך" }, "vaultTimeoutPolicyInEffect": { - "message": "Your organization policies have set your maximum allowed vault timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "message": "מדיניות הארגון שלך הגדירו את פסק זמן הכספת המרבי שלך ל-$HOURS$ שעות ו-$MINUTES$ דקות.", "placeholders": { "hours": { "content": "$1", @@ -2699,7 +2763,7 @@ } }, "vaultTimeoutPolicyInEffect1": { - "message": "$HOURS$ hour(s) and $MINUTES$ minute(s) maximum.", + "message": "$HOURS$ שעות ו-$MINUTES$ דקות לכל היותר.", "placeholders": { "hours": { "content": "$1", @@ -2712,7 +2776,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", @@ -2725,7 +2789,7 @@ } }, "vaultTimeoutPolicyWithActionInEffect": { - "message": "Your organization policies are affecting your vault timeout. Maximum allowed vault timeout is $HOURS$ hour(s) and $MINUTES$ minute(s). Your vault timeout action is set to $ACTION$.", + "message": "מדיניות הארגון שלך משפיעה על פסק זמן הכספת שלך. פסק הזמן המרבי המותר הוא $HOURS$ שעות ו-$MINUTES$ דקות. פעולת פסק זמן הכספת שלך מוגדרת ל$ACTION$.", "placeholders": { "hours": { "content": "$1", @@ -2742,7 +2806,7 @@ } }, "vaultTimeoutActionPolicyInEffect": { - "message": "Your organization policies have set your vault timeout action to $ACTION$.", + "message": "מדיניות הארגון שלך הגדירה את פעולת פסק זמן הכספת שלך ל$ACTION$.", "placeholders": { "action": { "content": "$1", @@ -2751,22 +2815,22 @@ } }, "vaultTimeoutTooLarge": { - "message": "הזמן הקצוב לכספת שלך חורג מהמגבלות שנקבעו על ידי הארגון שלך." + "message": "פסק הזמן של הכספת שלך חורג מהמגבלות שנקבעו על ידי הארגון שלך." }, "vaultExportDisabled": { - "message": "Vault export unavailable" + "message": "ייצוא כספת לא זמין" }, "personalVaultExportPolicyInEffect": { - "message": "One or more organization policies prevents you from exporting your individual vault." + "message": "מדיניות ארגון אחת או יותר מונעת ממך מלייצא את הכספת האישית שלך." }, "copyCustomFieldNameInvalidElement": { - "message": "Unable to identify a valid form element. Try inspecting the HTML instead." + "message": "לא ניתן לזהות רכיב טופס חוקי. נסה לבדוק את ה־HTML במקום זאת." }, "copyCustomFieldNameNotUnique": { - "message": "No unique identifier found." + "message": "לא נמצא מזהה ייחודי." }, "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ משתמשים ב־SSO עם שרת מפתחות באירוח עצמי. סיסמה ראשית לא נחוצה יותר לטובת כניסה לחברי הארגון.", + "message": "$ORGANIZATION$ משתמשת ב־SSO עם שרת מפתחות באירוח עצמי. סיסמה ראשית לא דרושה יותר כדי להיכנס עבור חברים של ארגון זה.", "placeholders": { "organization": { "content": "$1", @@ -2775,31 +2839,31 @@ } }, "leaveOrganization": { - "message": "לעזוב את הארגון" + "message": "עזוב ארגון" }, "removeMasterPassword": { - "message": "הסרת סיסמה ראשית" + "message": "הסר סיסמה ראשית" }, "removedMasterPassword": { - "message": "הסיסמה הראשית הוסרה." + "message": "הסיסמה הראשית הוסרה" }, "leaveOrganizationConfirmation": { - "message": "לעזוב את הארגון?" + "message": "אתה בטוח שברצונך לעזוב את הארגון הזה?" }, "leftOrganization": { "message": "עזבת את הארגון." }, "toggleCharacterCount": { - "message": "החלפת מצב ספירת תווים" + "message": "הצג או הסתר מונה תווים" }, "sessionTimeout": { - "message": "Your session has timed out. Please go back and try logging in again." + "message": "תם הזמן הקצוב להפעלה שלך. בבקשה לחזור ולנסות להיכנס שוב." }, "exportingPersonalVaultTitle": { - "message": "הכספת האישית מיוצאת" + "message": "מייצא כספת אישית" }, "exportingIndividualVaultDescription": { - "message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.", + "message": "רק פריטי הכספת האישית המשויכת עם $EMAIL$ ייוצאו. כספת ארגון לא תיכלל. רק פרטי פריט כספת ייוצאו ולא יכללו קבצים מצורפים משויכים.", "placeholders": { "email": { "content": "$1", @@ -2808,10 +2872,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", @@ -2823,27 +2887,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": "Generate username" + "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": { @@ -2857,7 +2921,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": { @@ -2867,7 +2931,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": { @@ -2877,46 +2941,46 @@ } }, "plusAddressedEmail": { - "message": "Plus addressed email", + "message": "דוא\"ל ממוען עם פלוס", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" }, "plusAddressedEmailDesc": { - "message": "Use your email provider's sub-addressing capabilities." + "message": "השתמש ביכולות מיעון משנה של ספק הדוא\"ל שלך." }, "catchallEmail": { - "message": "Catch-all email" + "message": "דוא\"ל תופס-כל" }, "catchallEmailDesc": { - "message": "Use your domain's configured catch-all inbox." + "message": "השתמש בתיבת תפוס-כל המוגדרת בדומיין שלך." }, "random": { - "message": "Random" + "message": "אקראי" }, "randomWord": { - "message": "Random word" + "message": "מילה אקראית" }, "websiteName": { - "message": "Website name" + "message": "שם אתר" }, "service": { - "message": "Service" + "message": "שירות" }, "forwardedEmail": { - "message": "כתובת דוא״ל להעברה" + "message": "כינוי דוא\"ל מועבר" }, "forwardedEmailDesc": { - "message": "יצירת כינוי דוא״ל עם שירות העברה חיצוני." + "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": { @@ -2930,11 +2994,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": { @@ -2944,7 +3008,7 @@ } }, "forwaderInvalidToken": { - "message": "Invalid $SERVICENAME$ API token", + "message": "אסימון $SERVICENAME$ API לא חוקי", "description": "Displayed when the user's API token is empty or rejected by the forwarding service.", "placeholders": { "servicename": { @@ -2954,7 +3018,7 @@ } }, "forwaderInvalidTokenWithMessage": { - "message": "Invalid $SERVICENAME$ API token: $ERRORMESSAGE$", + "message": "אסימון $SERVICENAME$ API לא חוקי: $ERRORMESSAGE$", "description": "Displayed when the user's API token is rejected by the forwarding service with an error message.", "placeholders": { "servicename": { @@ -2968,7 +3032,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": { @@ -2978,7 +3042,7 @@ } }, "forwarderNoDomain": { - "message": "Invalid $SERVICENAME$ domain.", + "message": "דומיין $SERVICENAME$ לא חוקי.", "description": "Displayed when the domain is empty or domain authorization failed at the forwarding service.", "placeholders": { "servicename": { @@ -2988,7 +3052,7 @@ } }, "forwarderNoUrl": { - "message": "Invalid $SERVICENAME$ url.", + "message": "ה־url של $SERVICENAME$ לא חוקי.", "description": "Displayed when the url of the forwarding service wasn't supplied.", "placeholders": { "servicename": { @@ -2998,7 +3062,7 @@ } }, "forwarderUnknownError": { - "message": "Unknown $SERVICENAME$ error occurred.", + "message": "התרחשה שגיאת $SERVICENAME$ לא ידועה.", "description": "Displayed when the forwarding service failed due to an unknown error.", "placeholders": { "servicename": { @@ -3008,7 +3072,7 @@ } }, "forwarderUnknownForwarder": { - "message": "Unknown forwarder: '$SERVICENAME$'.", + "message": "משלח לא ידוע: '$SERVICENAME$'.", "description": "Displayed when the forwarding service is not supported.", "placeholders": { "servicename": { @@ -3028,19 +3092,19 @@ "message": "מפתח API" }, "ssoKeyConnectorError": { - "message": "Key connector error: make sure key connector is available and working correctly." + "message": "שגיאת מחבר מפתח: ודא שמחבר המפתח זמין ועובד נכון." }, "premiumSubcriptionRequired": { - "message": "Premium subscription required" + "message": "נדרש מנוי פרימיום" }, "organizationIsDisabled": { - "message": "Organization suspended." + "message": "ארגון מושהה." }, "disabledOrganizationFilterError": { - "message": "Items in suspended Organizations cannot be accessed. Contact your Organization owner for assistance." + "message": "לא ניתן לגשת לפריטים בארגון מושהה. פנה אל בעל הארגון שלך עבור סיוע." }, "loggingInTo": { - "message": "Logging in to $DOMAIN$", + "message": "נכנס אל $DOMAIN$", "placeholders": { "domain": { "content": "$1", @@ -3049,25 +3113,25 @@ } }, "settingsEdited": { - "message": "Settings have been edited" + "message": "הגדרות נערכו" }, "environmentEditedClick": { - "message": "Click here" + "message": "לחץ כאן" }, "environmentEditedReset": { - "message": "to reset to pre-configured settings" + "message": "כדי לאפס את ההגדרות שהוגדרו מראש" }, "serverVersion": { - "message": "Server version" + "message": "גרסת שרת" }, "selfHostedServer": { - "message": "self-hosted" + "message": "אירוח עצמי" }, "thirdParty": { - "message": "Third-party" + "message": "צד שלישי" }, "thirdPartyServerMessage": { - "message": "Connected to third-party server implementation, $SERVERNAME$. Please verify bugs using the official server, or report them to the third-party server.", + "message": "מחובר ליישום שרת צד שלישי, $SERVERNAME$. בבקשה אמת באגים בעזרת השרת הרשמי, או דווח אותם לשרת הצד שלישי.", "placeholders": { "servername": { "content": "$1", @@ -3076,7 +3140,7 @@ } }, "lastSeenOn": { - "message": "last seen on: $DATE$", + "message": "נראה לאחרונה ב: $DATE$", "placeholders": { "date": { "content": "$1", @@ -3085,82 +3149,91 @@ } }, "loginWithMasterPassword": { - "message": "Log in with master password" + "message": "כניסה עם סיסמה ראשית" }, "loggingInAs": { - "message": "Logging in as" + "message": "כניסה בתור" }, "notYou": { - "message": "Not you?" + "message": "לא את/ה?" }, "newAroundHere": { - "message": "New around here?" + "message": "חדש כאן?" }, "rememberEmail": { - "message": "Remember email" + "message": "זכור דוא\"ל" }, "loginWithDevice": { - "message": "Log in with device" + "message": "כניסה עם מכשיר" }, "loginWithDeviceEnabledInfo": { - "message": "Log in with device must be set up in the settings of the Bitwarden app. Need another option?" + "message": "כניסה עם מכשיר צריכה להיות מוגדרת בהגדרות של היישום Bitwarden. צריך אפשרות אחרת?" }, "fingerprintPhraseHeader": { - "message": "Fingerprint phrase" + "message": "ביטוי טביעת אצבע" }, "fingerprintMatchInfo": { - "message": "Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device." + "message": "בבקשה ודא שהכספת שלך לא נעולה ושביטוי טביעת האצבע תואם במכשיר האחר." }, "resendNotification": { - "message": "Resend notification" + "message": "שליחת התראה מחדש" }, "viewAllLogInOptions": { - "message": "View all log in options" + "message": "הצג את כל אפשרויות הכניסה" }, "viewAllLoginOptionsV1": { - "message": "View all log in options" + "message": "הצג את כל אפשרויות הכניסה" }, "notificationSentDevice": { - "message": "A notification has been sent to your device." + "message": "התראה נשלחה למכשיר שלך." + }, + "notificationSentDevicePart1": { + "message": "בטל נעילת Bitwarden במכשיר שלך או ב" + }, + "notificationSentDeviceAnchor": { + "message": "יישום הרשת" + }, + "notificationSentDevicePart2": { + "message": "ודא שביטוי טביעת אצבע תואם את זה שלמטה לפני אישור." }, "aNotificationWasSentToYourDevice": { - "message": "A notification was sent to your device" - }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" + "message": "התראה נשלחה למכשיר שלך" }, "youWillBeNotifiedOnceTheRequestIsApproved": { - "message": "You will be notified once the request is approved" + "message": "תקבל התראה כאשר הבקשה תאושר" }, "needAnotherOptionV1": { - "message": "Need another option?" + "message": "צריך אפשרות אחרת?" }, "loginInitiated": { - "message": "Login initiated" + "message": "הכניסה החלה" + }, + "logInRequestSent": { + "message": "בקשה נשלחה" }, "exposedMasterPassword": { - "message": "Exposed Master Password" + "message": "סיסמה ראשית חשופה" }, "exposedMasterPasswordDesc": { - "message": "Password found in a data breach. Use a unique password to protect your account. Are you sure you want to use an exposed password?" + "message": "הסיסמה נמצאה בפרצת מידע. השתמש בסיסמה ייחודית כדי לשמור על חשבונך. האם אתה בטוח שברצונך להשתמש בסיסמה חשופה?" }, "weakAndExposedMasterPassword": { - "message": "Weak and Exposed Master Password" + "message": "סיסמה ראשית חלשה וחשופה" }, "weakAndBreachedMasterPasswordDesc": { - "message": "Weak password identified and found in a data breach. Use a strong and unique password to protect your account. Are you sure you want to use this password?" + "message": "סיסמה חלשה זוהתה ונמצאה בפרצת מידע. השתמש בסיסמה חזקה וייחודית כדי להגן על חשבונך. האם אתה בטוח שאתה רוצה להשתמש בסיסמה הזאת?" }, "checkForBreaches": { - "message": "Check known data breaches for this password" + "message": "בדוק פרצות מידע ידועות עבור סיסמה זו" }, "important": { - "message": "Important:" + "message": "חשוב:" }, "masterPasswordHint": { - "message": "Your master password cannot be recovered if you forget it!" + "message": "לא ניתן לשחזר את הסיסמה הראשית שלך אם אתה שוכח אותה!" }, "characterMinimum": { - "message": "$LENGTH$ character minimum", + "message": "$LENGTH$ תווים לכל הפחות", "placeholders": { "length": { "content": "$1", @@ -3169,13 +3242,13 @@ } }, "autofillPageLoadPolicyActivated": { - "message": "Your organization policies have turned on autofill on page load." + "message": "מדיניות הארגון של הפעילה מילוי אוטומטי בעת טעינת עמוד." }, "howToAutofill": { - "message": "How to autofill" + "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", @@ -3184,31 +3257,31 @@ } }, "autofillSelectInfoWithoutCommand": { - "message": "Select an item from this screen, or explore other options in settings." + "message": "בחר פריט ממסך זה, או חקור אפשרויות אחרות בהגדרות." }, "gotIt": { - "message": "Got it" + "message": "הבנתי" }, "autofillSettings": { - "message": "Autofill settings" + "message": "הגדרות מילוי אוטומטי" }, "autofillKeyboardShortcutSectionTitle": { - "message": "Autofill shortcut" + "message": "קיצור מילוי אוטומטי" }, "autofillKeyboardShortcutUpdateLabel": { - "message": "Change shortcut" + "message": "שנה קיצור דרך" }, "autofillKeyboardManagerShortcutsLabel": { - "message": "Manage shortcuts" + "message": "נהל קיצורי דרך" }, "autofillShortcut": { - "message": "Autofill keyboard shortcut" + "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", @@ -3217,7 +3290,7 @@ } }, "autofillShortcutTextSafari": { - "message": "Default autofill shortcut: $COMMAND$.", + "message": "קיצור דרך למילוי אוטומטי ברירת מחדל: $COMMAND$.", "placeholders": { "command": { "content": "$1", @@ -3226,65 +3299,65 @@ } }, "opensInANewWindow": { - "message": "Opens in a new window" + "message": "נפתח בחלון חדש" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "זכור מכשיר זה כדי להפוך כניסות עתידיות לחלקות" }, "deviceApprovalRequired": { - "message": "Device approval required. Select an approval option below:" + "message": "נדרש אישור מכשיר. בחר אפשרות אישור למטה:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "נדרש אישור מכשיר" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "בחר אפשרות אישור למטה" }, "rememberThisDevice": { - "message": "Remember this device" + "message": "זכור מכשיר זה" }, "uncheckIfPublicDevice": { - "message": "Uncheck if using a public device" + "message": "בטל את הסימון אם אתה משתמש במכשיר ציבורי" }, "approveFromYourOtherDevice": { - "message": "Approve from your other device" + "message": "אשר מהמכשיר האחר שלך" }, "requestAdminApproval": { - "message": "Request admin approval" + "message": "בקש אישור מנהל" }, "approveWithMasterPassword": { - "message": "Approve with master password" + "message": "אשר עם סיסמה ראשית" }, "ssoIdentifierRequired": { - "message": "Organization SSO identifier is required." + "message": "נדרש מזהה SSO של הארגון." }, "creatingAccountOn": { - "message": "Creating account on" + "message": "יוצר חשבון ב־" }, "checkYourEmail": { - "message": "Check your email" + "message": "בדוק את הדוא\"ל שלך" }, "followTheLinkInTheEmailSentTo": { - "message": "Follow the link in the email sent to" + "message": "עקוב אחר הקישור בדוא\"ל הנשלח אל" }, "andContinueCreatingYourAccount": { - "message": "and continue creating your account." + "message": "והמשך ליצור את החשבון שלך." }, "noEmail": { - "message": "No email?" + "message": "אין דוא\"ל?" }, "goBack": { - "message": "Go back" + "message": "חזור אחורה" }, "toEditYourEmailAddress": { - "message": "to edit your email address." + "message": "כדי לערוך את כתובת הדוא\"ל שלך." }, "eu": { - "message": "EU", + "message": "האיחוד האירופי", "description": "European Union" }, "accessDenied": { - "message": "Access denied. You do not have permission to view this page." + "message": "גישה נדחתה. אין לך הרשאות כדי לצפות בדף זה." }, "general": { "message": "כללי" @@ -3293,51 +3366,51 @@ "message": "תצוגה" }, "accountSuccessfullyCreated": { - "message": "Account successfully created!" + "message": "החשבון נוצר בהצלחה!" }, "adminApprovalRequested": { - "message": "Admin approval requested" + "message": "התבקש אישור מנהל" }, "adminApprovalRequestSentToAdmins": { - "message": "Your request has been sent to your admin." + "message": "הבקשה שלך נשלחה למנהל שלך." }, "youWillBeNotifiedOnceApproved": { - "message": "You will be notified once approved." + "message": "תקבל התראה כשתאושר." }, "troubleLoggingIn": { - "message": "Trouble logging in?" + "message": "בעיות בהתחברות?" }, "loginApproved": { - "message": "Login approved" + "message": "כניסה אושרה" }, "userEmailMissing": { - "message": "User email missing" + "message": "חסר דוא\"ל משתמש" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "דוא\"ל משתמש פעיל לא נמצא. מנתק אותך." }, "deviceTrusted": { - "message": "Device trusted" + "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." }, "inputRequired": { - "message": "Input is required." + "message": "נדרש קלט." }, "required": { - "message": "required" + "message": "נדרש" }, "search": { - "message": "Search" + "message": "חיפוש" }, "inputMinLength": { - "message": "Input must be at least $COUNT$ characters long.", + "message": "קלט חייב להיות באורך $COUNT$ תווים לכל הפחות.", "placeholders": { "count": { "content": "$1", @@ -3346,7 +3419,7 @@ } }, "inputMaxLength": { - "message": "Input must not exceed $COUNT$ characters in length.", + "message": "קלט חייב להיות באורך $COUNT$ תווים לכל היותר.", "placeholders": { "count": { "content": "$1", @@ -3355,7 +3428,7 @@ } }, "inputForbiddenCharacters": { - "message": "The following characters are not allowed: $CHARACTERS$", + "message": "התווים הבאים אינם מותרים: $CHARACTERS$", "placeholders": { "characters": { "content": "$1", @@ -3364,7 +3437,7 @@ } }, "inputMinValue": { - "message": "Input value must be at least $MIN$.", + "message": "ערך הקלט חייב להיות לפחות $MIN$.", "placeholders": { "min": { "content": "$1", @@ -3373,7 +3446,7 @@ } }, "inputMaxValue": { - "message": "Input value must not exceed $MAX$.", + "message": "ערך הקלט לא יעלה על $MAX$.", "placeholders": { "max": { "content": "$1", @@ -3382,17 +3455,17 @@ } }, "multipleInputEmails": { - "message": "1 or more emails are invalid" + "message": "1 או יותר דוא\"לים אינם חוקיים" }, "inputTrimValidator": { - "message": "Input must not contain only whitespace.", + "message": "אסור שקלט יכיל רק רווח לבן.", "description": "Notification to inform the user that a form's input can't contain only whitespace." }, "inputEmail": { - "message": "Input is not an email address." + "message": "קלט הוא לא כתובת דוא\"ל." }, "fieldsNeedAttention": { - "message": "$COUNT$ field(s) above need your attention.", + "message": "$COUNT$ שדות למעלה צריכות את תשומת לבך.", "placeholders": { "count": { "content": "$1", @@ -3401,10 +3474,10 @@ } }, "singleFieldNeedsAttention": { - "message": "1 field needs your attention." + "message": "שדה 1 צריך את תשומת לבך." }, "multipleFieldsNeedAttention": { - "message": "$COUNT$ fields need your attention.", + "message": "$COUNT$ שדות צריכות את תשומת לבך.", "placeholders": { "count": { "content": "$1", @@ -3413,22 +3486,22 @@ } }, "selectPlaceholder": { - "message": "-- Select --" + "message": "-- בחר --" }, "multiSelectPlaceholder": { - "message": "-- Type to filter --" + "message": "-- הקלד כדי לסנן --" }, "multiSelectLoading": { - "message": "Retrieving options..." + "message": "מאחזר אפשרויות..." }, "multiSelectNotFound": { - "message": "No items found" + "message": "לא נמצאו פריטים" }, "multiSelectClearAll": { - "message": "Clear all" + "message": "נקה הכל" }, "plusNMore": { - "message": "+ $QUANTITY$ more", + "message": "+ עוד $QUANTITY$", "placeholders": { "quantity": { "content": "$1", @@ -3437,122 +3510,122 @@ } }, "submenu": { - "message": "Submenu" + "message": "תפריט משנה" }, "toggleCollapse": { - "message": "Toggle collapse", + "message": "החלף מצב כיווץ", "description": "Toggling an expand/collapse state." }, "aliasDomain": { - "message": "Alias domain" + "message": "דומיין כינוי" }, "passwordRepromptDisabledAutofillOnPageLoad": { - "message": "Items with master password re-prompt cannot be autofilled on page load. Autofill on page load turned off.", + "message": "פריטים עם בקשת סיסמה ראשית חוזרת לא ניתנים למילוי אוטומטי בעת טעינת עמוד. מילוי אוטומטי בעת טעינת נכבה.", "description": "Toast message for describing that master password re-prompt cannot be autofilled on page load." }, "autofillOnPageLoadSetToDefault": { - "message": "Autofill on page load set to use default setting.", + "message": "מילוי אוטומטי בעת טעינת הוגדר להשתמש בהגדרת ברירת מחדל.", "description": "Toast message for informing the user that autofill on page load has been set to the default setting." }, "turnOffMasterPasswordPromptToEditField": { - "message": "Turn off master password re-prompt to edit this field", + "message": "כבה בקשת סיסמה ראשית חוזרת כדי לערוך שדה זה", "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": "החלף מצב תפריט מילוי אוטומטי של Bitwaden", "description": "Screen reader and tool tip label for the overlay button" }, "bitwardenVault": { - "message": "Bitwarden autofill menu", + "message": "תפריט מילוי אוטומטי של Bitwaden", "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": { - "message": "No items to show", + "message": "אין פריטים להצגה", "description": "Text to show in overlay if there are no matching items" }, "newItem": { - "message": "New item", + "message": "פריט חדש", "description": "Button text to display in overlay when there are no matching items" }, "addNewVaultItem": { - "message": "Add new vault item", + "message": "הוסף פריט כספת חדש", "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": { - "message": "Turn on" + "message": "הפעל" }, "ignore": { - "message": "Ignore" + "message": "התעלם" }, "importData": { "message": "ייבוא נתונים", @@ -3562,10 +3635,10 @@ "message": "שגיאת ייבוא" }, "importErrorDesc": { - "message": "There was a problem with the data you tried to import. Please resolve the errors listed below in your source file and try again." + "message": "הייתה בעיה עם הנתונים שאתה מנסה לייבא. נא לפתור את השגיאות הרשומות למטה בקובץ המקור שלך ולנסות שוב." }, "resolveTheErrorsBelowAndTryAgain": { - "message": "Resolve the errors below and try again." + "message": "פתור את השגיאות למטה ונסה שוב." }, "description": { "message": "תיאור" @@ -3574,7 +3647,7 @@ "message": "הנתונים יובאו בהצלחה" }, "importSuccessNumberOfItems": { - "message": "A total of $AMOUNT$ items were imported.", + "message": "סך הכל יובאו $AMOUNT$ פריטים.", "placeholders": { "amount": { "content": "$1", @@ -3583,46 +3656,46 @@ } }, "tryAgain": { - "message": "Try again" + "message": "נסה שוב" }, "verificationRequiredForActionSetPinToContinue": { - "message": "Verification required for this action. Set a PIN to continue." + "message": "נדרש אימות לפעולה זו. הגדר PIN כדי להמשיך." }, "setPin": { - "message": "Set PIN" + "message": "הגדר PIN" }, "verifyWithBiometrics": { - "message": "Verify with biometrics" + "message": "אמת עם זיהוי ביומטרי" }, "awaitingConfirmation": { - "message": "Awaiting confirmation" + "message": "ממתין לאישור" }, "couldNotCompleteBiometrics": { - "message": "Could not complete biometrics." + "message": "לא היה ניתן להשלים את הזיהוי הביומטרי." }, "needADifferentMethod": { - "message": "Need a different method?" + "message": "זקוק לשיטה אחרת?" }, "useMasterPassword": { - "message": "Use master password" + "message": "השתמש בסיסמה ראשית" }, "usePin": { - "message": "Use PIN" + "message": "השתמש ב־PIN" }, "useBiometrics": { - "message": "Use biometrics" + "message": "השתמש בזיהוי ביומטרי" }, "enterVerificationCodeSentToEmail": { - "message": "Enter the verification code that was sent to your email." + "message": "הזן את קוד האימות שנשלח לדוא\"ל שלך." }, "resendCode": { - "message": "Resend code" + "message": "שלח קוד מחדש" }, "total": { - "message": "סך הכול" + "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", @@ -3631,49 +3704,49 @@ } }, "duoHealthCheckResultsInNullAuthUrlError": { - "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." + "message": "שגיאה בהתחברות עם שירות ה־Duo. השתמש בשיטת כניסה דו־שלבית אחרת או פנה אל Duo לסיוע." }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." + "message": "פתח את Duo ועקוב אחר השלבים לסיום הכניסה." }, "duoRequiredForAccount": { - "message": "Duo two-step login is required for your account." + "message": "דרושה כניסה דו־שלבים של Duo עבור החשבון שלך." }, "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." + "message": "נתק את ההרחבה כדי להשלים כניסה." }, "popoutExtension": { - "message": "Popout extension" + "message": "נתק הרחבה" }, "launchDuo": { - "message": "Launch Duo" + "message": "פתח את Duo" }, "importFormatError": { - "message": "Data is not formatted correctly. Please check your import file and try again." + "message": "נתונים לא מעוצבים כראוי. נא לבדוק את קובץ הייבוא שלך ולנסות שוב." }, "importNothingError": { - "message": "Nothing was imported." + "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": "Select a folder" + "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": { @@ -3683,25 +3756,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": { @@ -3711,200 +3784,200 @@ } }, "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": "Passkey will not be copied" + "message": "מפתח גישה לא יועתק" }, "passkeyNotCopiedAlert": { - "message": "The passkey will not be copied to the cloned item. Do you want to continue cloning this item?" + "message": "מפתח הגישה לא יועתק לפריט המשוכפל. האם ברצונך להמשיך לשכפל פריט זה?" }, "passkeyFeatureIsNotImplementedForAccountsWithoutMasterPassword": { - "message": "Verification required by the initiating site. This feature is not yet implemented for accounts without master password." + "message": "נדרש אימות על ידי האתר היוזם. תכונה זו עדיין לא מיושמת עבור חשבונות ללא סיסמה ראשית." }, "logInWithPasskeyQuestion": { - "message": "Log in with passkey?" + "message": "אימות עם מפתח גישה?" }, "passkeyAlreadyExists": { - "message": "A passkey already exists for this application." + "message": "מפתח גישה כבר קיים ביישום זה." }, "noPasskeysFoundForThisApplication": { - "message": "No passkeys found for this application." + "message": "לא נמצאו מפתחות גישה עבור יישום זה." }, "noMatchingPasskeyLogin": { - "message": "You do not have a matching login for this site." + "message": "אין לך כניסות תואמות עבור אתר זה." }, "noMatchingLoginsForSite": { - "message": "No matching logins for this site" + "message": "אין כניסות תואמות עבור אתר זה" }, "searchSavePasskeyNewLogin": { - "message": "Search or save passkey as new login" + "message": "חפש או שמור מפתח גישה ככניסה חדשה" }, "confirm": { - "message": "Confirm" + "message": "אשר" }, "savePasskey": { - "message": "Save passkey" + "message": "שמור מפתח גישה" }, "savePasskeyNewLogin": { - "message": "Save passkey as new login" + "message": "שמור מפתח גישה ככניסה חדשה" }, "chooseCipherForPasskeySave": { - "message": "Choose a login to save this passkey to" + "message": "בחר כניסה אליה יישמר מפתח כניסה זה" }, "chooseCipherForPasskeyAuth": { - "message": "Choose a passkey to log in with" + "message": "בחר מפתח גישה כדי להיכנס באמצעותה" }, "passkeyItem": { - "message": "Passkey Item" + "message": "פריט מפתח גישה" }, "overwritePasskey": { - "message": "Overwrite passkey?" + "message": "לדרוס מפתח גישה?" }, "overwritePasskeyAlert": { - "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + "message": "פריט זה כבר מכיל מפתח גישה. האם אתה בטוח שברצונך לדרוס את המפתח גישה הנוכחי?" }, "featureNotSupported": { - "message": "Feature not yet supported" + "message": "תכונה עדיין לא נתמכת" }, "yourPasskeyIsLocked": { - "message": "Authentication required to use passkey. Verify your identity to continue." + "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": "PIN שגוי" }, "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": "חשבון פעיל" }, "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", @@ -3913,106 +3986,106 @@ } }, "commonImportFormats": { - "message": "תסדירים נפוצים", + "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": "הפוך את Bitwaren למנהל הסיסמאות ברירת המחדל שלך", "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": "הצעות למילוי אוטומטי" }, "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": { @@ -4022,7 +4095,7 @@ } }, "copyNoteTitle": { - "message": "Copy Note - $ITEMNAME$", + "message": "העתק פתק - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", "placeholders": { "itemname": { @@ -4032,7 +4105,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": { @@ -4042,7 +4115,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": { @@ -4052,7 +4125,7 @@ } }, "viewItemTitle": { - "message": "View item - $ITEMNAME$", + "message": "הצג פריט - $ITEMNAME$", "description": "Title for a link that opens a view for an item.", "placeholders": { "itemname": { @@ -4062,7 +4135,7 @@ } }, "autofillTitle": { - "message": "Autofill - $ITEMNAME$", + "message": "מילוי אוטומטי - $ITEMNAME$", "description": "Title for a button that autofills a login item.", "placeholders": { "itemname": { @@ -4072,40 +4145,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": { @@ -4115,7 +4188,7 @@ } }, "backTo": { - "message": "Back to $NAME$", + "message": "חזרה אל $NAME$", "description": "Navigate back to a previous folder or collection", "placeholders": { "name": { @@ -4125,10 +4198,10 @@ } }, "new": { - "message": "New" + "message": "חדש" }, "removeItem": { - "message": "Remove $NAME$", + "message": "הסר $NAME$", "description": "Remove a selected option, such as a folder or collection", "placeholders": { "name": { @@ -4138,65 +4211,56 @@ } }, "itemsWithNoFolder": { - "message": "Items with no folder" + "message": "פריטים ללא תיקיה" }, "itemDetails": { - "message": "Item details" + "message": "פרטי הפריט" }, "itemName": { - "message": "Item name" - }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } + "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": "גודל הקובץ המרבי הוא 500MB" }, "deleteAttachmentName": { - "message": "Delete attachment $NAME$", + "message": "מחק קובץ מצורף $NAME$", "placeholders": { "name": { "content": "$1", @@ -4205,7 +4269,7 @@ } }, "downloadAttachmentName": { - "message": "Download $NAME$", + "message": "הורד $NAME$", "placeholders": { "name": { "content": "$1", @@ -4214,25 +4278,25 @@ } }, "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", @@ -4241,16 +4305,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", @@ -4259,23 +4323,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": "אתר אינטרנט (URI)" }, "websiteUriCount": { - "message": "Website (URI) $COUNT$", + "message": "אתר אינטרנט (URI) $COUNT$", "description": "Label for an input field that contains a website URI. The input field is part of a list of fields, and the count indicates the position of the field in the list.", "placeholders": { "count": { @@ -4285,16 +4349,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": { @@ -4304,7 +4368,7 @@ } }, "showMatchDetection": { - "message": "Show match detection $WEBSITE$", + "message": "הצג זיהוי התאמה $WEBSITE$", "placeholders": { "website": { "content": "$1", @@ -4313,7 +4377,7 @@ } }, "hideMatchDetection": { - "message": "Hide match detection $WEBSITE$", + "message": "הסתר זיהוי התאמה $WEBSITE$", "placeholders": { "website": { "content": "$1", @@ -4322,19 +4386,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", @@ -4343,43 +4407,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", @@ -4391,37 +4455,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 או מציין מיקום." }, "editField": { - "message": "Edit field" + "message": "ערוך שדה" }, "editFieldLabel": { - "message": "Edit $LABEL$", + "message": "ערוך $LABEL$", "placeholders": { "label": { "content": "$1", @@ -4430,7 +4494,7 @@ } }, "deleteCustomField": { - "message": "Delete $LABEL$", + "message": "מחק $LABEL$", "placeholders": { "label": { "content": "$1", @@ -4439,7 +4503,7 @@ } }, "fieldAdded": { - "message": "$LABEL$ added", + "message": "$LABEL$ נוסף", "placeholders": { "label": { "content": "$1", @@ -4448,7 +4512,7 @@ } }, "reorderToggleButton": { - "message": "Reorder $LABEL$. Use arrow key to move item up or down.", + "message": "סדר מחדש את $LABEL$. השתמש במקש חץ כדי להעביר את הפריט למעלה או למטה.", "placeholders": { "label": { "content": "$1", @@ -4457,7 +4521,7 @@ } }, "reorderFieldUp": { - "message": "$LABEL$ moved up, position $INDEX$ of $LENGTH$", + "message": "$LABEL$ עבר למעלה, מיקום $INDEX$ מתוך $LENGTH$", "placeholders": { "label": { "content": "$1", @@ -4474,13 +4538,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": "פריט 1 יועבר לצמיתות לארגון הנבחר. לא תהיה יותר הבעלים של הפריט הזה." }, "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", @@ -4489,7 +4553,7 @@ } }, "personalItemWithOrgTransferWarningSingular": { - "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "message": "פריט 1 יועבר לצמיתות אל $ORG$. לא תהיה יותר הבעלים של הפריט הזה.", "placeholders": { "org": { "content": "$1", @@ -4498,7 +4562,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", @@ -4511,13 +4575,13 @@ } }, "successfullyAssignedCollections": { - "message": "Successfully assigned collections" + "message": "אוספים הוקצו בהצלחה" }, "nothingSelected": { - "message": "You have not selected anything." + "message": "לא בחרת כלום." }, "movedItemsToOrg": { - "message": "Selected items moved to $ORGNAME$", + "message": "פריטים נבחרים הועברו ל־$ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -4526,7 +4590,7 @@ } }, "itemsMovedToOrg": { - "message": "Items moved to $ORGNAME$", + "message": "פריטים הועברו ל־$ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -4535,7 +4599,7 @@ } }, "itemMovedToOrg": { - "message": "Item moved to $ORGNAME$", + "message": "פריט הועבר ל־$ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -4544,7 +4608,7 @@ } }, "reorderFieldDown": { - "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", + "message": "$LABEL$ עבר למטה, מיקום $INDEX$ מתוך $LENGTH$", "placeholders": { "label": { "content": "$1", @@ -4561,115 +4625,115 @@ } }, "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" }, "sshKeyAlgorithmRSA2048": { - "message": "RSA 2048-Bit" + "message": "RSA‏ 2048 סיביות" }, "sshKeyAlgorithmRSA3072": { - "message": "RSA 3072-Bit" + "message": "RSA‏ 3072 סיביות" }, "sshKeyAlgorithmRSA4096": { - "message": "RSA 4096-Bit" + "message": "RSA‏ 4096 סיביות" }, "retry": { - "message": "Retry" + "message": "נסה שוב" }, "vaultCustomTimeoutMinimum": { - "message": "Minimum custom timeout is 1 minute." + "message": "פסק זמן מינימלי הוא דקה 1." }, "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": "פריטים שאתה מוחק יופיעו כאן ויימחקו לצמיתות לאחר 30 יום" }, "trashWarning": { - "message": "Items that have been in trash more than 30 days will automatically be deleted" + "message": "פריטים שהיו באשפה יותר מ־30 יום יימחקו באופן אוטומטי" }, "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": "ביטול נעילה ביומטרי אינו זמין בגלל שקודם צריך לבטל את הנעילה עם PIN או סיסמה." }, "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", @@ -4678,187 +4742,187 @@ } }, "biometricsStatusHelptextUnavailableReasonUnknown": { - "message": "Biometric unlock is currently unavailable for an unknown reason." + "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" }, "saveLoginToBitwarden": { - "message": "Save login to Bitwarden?", + "message": "לשמור כניסה ב־Bitwarden?", "description": "Confirmation message for saving a login to Bitwarden" }, "spaceCharacterDescriptor": { - "message": "Space", + "message": "רווח", "description": "Represents the space key in screen reader content as a readable word" }, "tildeCharacterDescriptor": { - "message": "Tilde", + "message": "טילדה", "description": "Represents the ~ key in screen reader content as a readable word" }, "backtickCharacterDescriptor": { - "message": "Backtick", + "message": "בקטיק", "description": "Represents the ` key in screen reader content as a readable word" }, "exclamationCharacterDescriptor": { - "message": "Exclamation mark", + "message": "סימן קריאה", "description": "Represents the ! key in screen reader content as a readable word" }, "atSignCharacterDescriptor": { - "message": "At sign", + "message": "כרוכית", "description": "Represents the @ key in screen reader content as a readable word" }, "hashSignCharacterDescriptor": { - "message": "Hash sign", + "message": "סולמית", "description": "Represents the # key in screen reader content as a readable word" }, "dollarSignCharacterDescriptor": { - "message": "Dollar sign", + "message": "סימן הדולר", "description": "Represents the $ key in screen reader content as a readable word" }, "percentSignCharacterDescriptor": { - "message": "Percent sign", + "message": "סימן אחוז", "description": "Represents the % key in screen reader content as a readable word" }, "caretCharacterDescriptor": { - "message": "Caret", + "message": "קרט", "description": "Represents the ^ key in screen reader content as a readable word" }, "ampersandCharacterDescriptor": { - "message": "Ampersand", + "message": "אמפרסנד", "description": "Represents the & key in screen reader content as a readable word" }, "asteriskCharacterDescriptor": { - "message": "Asterisk", + "message": "כוכבית", "description": "Represents the * key in screen reader content as a readable word" }, "parenLeftCharacterDescriptor": { - "message": "Left parenthesis", + "message": "סוגר שמאלי", "description": "Represents the ( key in screen reader content as a readable word" }, "parenRightCharacterDescriptor": { - "message": "Right parenthesis", + "message": "סוגר ימני", "description": "Represents the ) key in screen reader content as a readable word" }, "hyphenCharacterDescriptor": { - "message": "Underscore", + "message": "קו תחתון", "description": "Represents the _ key in screen reader content as a readable word" }, "underscoreCharacterDescriptor": { - "message": "Hyphen", + "message": "מקף", "description": "Represents the - key in screen reader content as a readable word" }, "plusCharacterDescriptor": { - "message": "Plus", + "message": "פלוס", "description": "Represents the + key in screen reader content as a readable word" }, "equalsCharacterDescriptor": { - "message": "Equals", + "message": "שוויון", "description": "Represents the = key in screen reader content as a readable word" }, "braceLeftCharacterDescriptor": { - "message": "Left brace", + "message": "סוגר מסולסל שמאלי", "description": "Represents the { key in screen reader content as a readable word" }, "braceRightCharacterDescriptor": { - "message": "Right brace", + "message": "סוגר מסולסל ימני", "description": "Represents the } key in screen reader content as a readable word" }, "bracketLeftCharacterDescriptor": { - "message": "Left bracket", + "message": "סוגר מרובע שמאלי", "description": "Represents the [ key in screen reader content as a readable word" }, "bracketRightCharacterDescriptor": { - "message": "Right bracket", + "message": "סוגר מרובע ימני", "description": "Represents the ] key in screen reader content as a readable word" }, "pipeCharacterDescriptor": { - "message": "Pipe", + "message": "צינור", "description": "Represents the | key in screen reader content as a readable word" }, "backSlashCharacterDescriptor": { - "message": "Back slash", + "message": "לוכסן שמאלי", "description": "Represents the back slash key in screen reader content as a readable word" }, "colonCharacterDescriptor": { - "message": "Colon", + "message": "נקודתיים", "description": "Represents the : key in screen reader content as a readable word" }, "semicolonCharacterDescriptor": { - "message": "Semicolon", + "message": "נקודה ופסיק", "description": "Represents the ; key in screen reader content as a readable word" }, "doubleQuoteCharacterDescriptor": { - "message": "Double quote", + "message": "מירכאה כפולה", "description": "Represents the double quote key in screen reader content as a readable word" }, "singleQuoteCharacterDescriptor": { - "message": "Single quote", + "message": "מירכאה בודדת", "description": "Represents the ' key in screen reader content as a readable word" }, "lessThanCharacterDescriptor": { - "message": "Less than", + "message": "קטן מ-", "description": "Represents the < key in screen reader content as a readable word" }, "greaterThanCharacterDescriptor": { - "message": "Greater than", + "message": "גדול מ-", "description": "Represents the > key in screen reader content as a readable word" }, "commaCharacterDescriptor": { - "message": "Comma", + "message": "פסיק", "description": "Represents the , key in screen reader content as a readable word" }, "periodCharacterDescriptor": { - "message": "Period", + "message": "נקודה", "description": "Represents the . key in screen reader content as a readable word" }, "questionCharacterDescriptor": { - "message": "Question mark", + "message": "סימן שאלה", "description": "Represents the ? key in screen reader content as a readable word" }, "forwardSlashCharacterDescriptor": { - "message": "Forward slash", + "message": "לוכסן", "description": "Represents the / key in screen reader content as a readable word" }, "lowercaseAriaLabel": { - "message": "Lowercase" + "message": "אות קטנה" }, "uppercaseAriaLabel": { - "message": "Uppercase" + "message": "אות גדולה" }, "generatedPassword": { - "message": "Generated password" + "message": "נוצרה סיסמה" }, "compactMode": { - "message": "Compact mode" + "message": "מצב קומפקטי" }, "beta": { - "message": "Beta" + "message": "בטא" }, "importantNotice": { - "message": "Important notice" + "message": "הודעה חשובה" }, "setupTwoStepLogin": { - "message": "Set up two-step login" + "message": "הגדר כניסה דו-שלבית" }, "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + "message": "Bitwarden ישלח קוד לדוא\"ל החשבון שלך כדי לאמת כניסות ממכשירים חדשים החל מפברואר 2025." }, "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + "message": "אתה יכול להגדיר כניסה דו-שלבית כדרך חלופית להגן על החשבון שלך או לשנות את הדוא\"ל שלך לאחד שתוכל לגשת אליו." }, "remindMeLater": { - "message": "Remind me later" + "message": "הזכר לי מאוחר יותר" }, "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", + "message": "יש לך גישה מהימנה לדוא\"ל שלך, $EMAIL$?", "placeholders": { "email": { "content": "$1", @@ -4867,30 +4931,39 @@ } }, "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" + "message": "לא, אין לי" }, "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" + "message": "כן, אני יכול לגשת לדוא\"ל באופן מהימן" }, "turnOnTwoStepLogin": { - "message": "Turn on two-step login" + "message": "הפעל כניסה דו-שלבית" }, "changeAcctEmail": { - "message": "Change account email" + "message": "שנה את דוא\"ל החשבון" }, "extensionWidth": { - "message": "Extension width" + "message": "רוחב הרחבה" }, "wide": { - "message": "Wide" + "message": "רחב" }, "extraWide": { - "message": "Extra wide" + "message": "רחב במיוחד" + }, + "cannotRemoveViewOnlyCollections": { + "message": "אינך יכול להסיר אוספים עם הרשאות צפייה בלבד: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } }, "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": "כדי להשתמש בביטול נעילה ביומטרי, נא לעדכן את יישום שולחן העבודה שלך, להשבית ביטול נעילה בעזרת טביעת אצבע בהגדרות שולחן העבודה." } } diff --git a/apps/browser/src/_locales/hi/messages.json b/apps/browser/src/_locales/hi/messages.json index 362720e4ee2..8d6340c9727 100644 --- a/apps/browser/src/_locales/hi/messages.json +++ b/apps/browser/src/_locales/hi/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Purchase Premium" }, - "premiumPurchaseAlert": { - "message": "आप bitwarden.com वेब वॉल्ट पर प्रीमियम सदस्यता खरीद सकते हैं।क्या आप अब वेबसाइट पर जाना चाहते हैं?" - }, "premiumPurchaseAlertV2": { "message": "You can purchase Premium from your account settings on the Bitwarden web app." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Username generator" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Use this password" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Website $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "You will be notified once the request is approved" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Login initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Exposed Master Password" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organization is deactivated" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra wide" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/hr/messages.json b/apps/browser/src/_locales/hr/messages.json index ae438b5add0..56778b96bcc 100644 --- a/apps/browser/src/_locales/hr/messages.json +++ b/apps/browser/src/_locales/hr/messages.json @@ -334,7 +334,7 @@ "message": "Bitwarden autentifikator" }, "continueToAuthenticatorPageDesc": { - "message": "Bitwarden autentifikator omogućuje pohranu ključeva za autentifikaciju i generiranje TOTP kodova za dvostruku autentifikaciju. Saznaj više na web stranici bitwarden.com" + "message": "Bitwarden autentifikator omogućuje pohranu autentifikatorskih ključeva i generiranje TOTP kodova za dvostruku autentifikaciju. Saznaj više na web stranici bitwarden.com" }, "bitwardenSecretsManager": { "message": "Bitwarden Secrets Manager" @@ -446,16 +446,16 @@ "message": "Generiraj frazu lozinke" }, "passwordGenerated": { - "message": "Password generated" + "message": "Lozinka generirana" }, "passphraseGenerated": { - "message": "Passphrase generated" + "message": "Frazna lozinka generirana" }, "usernameGenerated": { - "message": "Username generated" + "message": "Korisničko ime generirano" }, "emailGenerated": { - "message": "Email generated" + "message": "e-pošta generirana" }, "regeneratePassword": { "message": "Ponovno generiraj lozinku" @@ -660,10 +660,10 @@ "message": "Potvrdi identitet" }, "weDontRecognizeThisDevice": { - "message": "We don't recognize this device. Enter the code sent to your email to verify your identity." + "message": "Ne prepoznajemo ovaj uređaj. Za potvrdu identiteta unesi kôd poslan e-poštom." }, "continueLoggingIn": { - "message": "Continue logging in" + "message": "Nastavi prijavu" }, "yourVaultIsLocked": { "message": "Tvoj trezor je zaključan. Potvrdi glavnu lozinku za nastavak." @@ -903,7 +903,7 @@ "message": "Mapa dodana" }, "twoStepLoginConfirmation": { - "message": "Prijava dvostrukom autentifikacijom čini tvoj račun još sigurnijim tako što će zahtijevati da potvrdiš prijavu putem drugog uređaja pomoću sigurnosnog koda, autentifikatorske aplikacije, SMS-om, pozivom ili e-poštom. Prijavu dvostrukom autentifikacijom možeš omogućiti na web trezoru. Želiš li sada posjetiti bitwarden.com?" + "message": "Prijava dvostrukom autentifikacijom čini tvoj račun još sigurnijim tako što će zahtijevati potvrdu prijave drugim uređajem kao što je sigurnosni ključ, autentifikatorska aplikacija, SMS, poziv ili e-pošta. Prijavu dvostrukom autentifikacijom možeš omogućiti na web trezoru. Želiš li sada posjetiti bitwarden.com?" }, "twoStepLoginConfirmationContent": { "message": "Učini svoj račun sigurnijim uključivanjem prijave dvofaktorskom autentifikacijom u Bitwarden web aplikaciji." @@ -1005,7 +1005,7 @@ "message": "Pitaj za dodavanje stavke ako nije pronađena u tvojem trezoru. Primjenjuje se na sve prijavljene račune." }, "showCardsInVaultViewV2": { - "message": "Always show cards as Autofill suggestions on Vault view" + "message": "Uvijek prikaži kartice kao prijedloge za auto-ispunu u prikazu trezora" }, "showCardsCurrentTab": { "message": "Prikaži platne kartice" @@ -1014,7 +1014,7 @@ "message": "Prikazuj platne kartice za jednostavnu auto-ispunu." }, "showIdentitiesInVaultViewV2": { - "message": "Always show identities as Autofill suggestions on Vault view" + "message": "Uvijek prikaži identitete kao prijedloge za auto-ispunu u prikazu trezora" }, "showIdentitiesCurrentTab": { "message": "Prikaži identitete" @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Kupi premium članstvo" }, - "premiumPurchaseAlert": { - "message": "Možeš kupiti premium članstvo na web trezoru. Želiš li sada posjetiti bitwarden.com?" - }, "premiumPurchaseAlertV2": { "message": "Premium možeš kupiti u postavkama računa na Bitwarden web aplikaciji." }, @@ -1320,7 +1317,7 @@ "message": "Automatski kopiraj TOTP" }, "disableAutoTotpCopyDesc": { - "message": "Ako za prijavu postoji autentifikatorski ključ, kopiraj TOTP kôd za provjeru u međuspremnik nakon auto-ispune prijave." + "message": "Ako za prijavu postoji ključ autentifikatora, kopiraj TOTP kôd za provjeru u međuspremnik nakon auto-ispune prijave." }, "enableAutoBiometricsPrompt": { "message": "Traži biometrijsku autentifikaciju pri pokretanju" @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Generator korisničkih imena" }, + "useThisEmail": { + "message": "Koristi ovu e-poštu" + }, "useThisPassword": { "message": "Koristi ovu lozinku" }, @@ -2343,7 +2343,7 @@ "description": "A category title describing the concept of web domains" }, "blockedDomains": { - "message": "Blocked domains" + "message": "Blokirane domene" }, "excludedDomains": { "message": "Izuzete domene" @@ -2355,13 +2355,77 @@ "message": "Bitwarden neće nuditi spremanje podataka za prijavu za ove domene za sve prijavljene račune. Moraš osvježiti stranicu kako bi promjene stupile na snagu." }, "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": "Auto-ispuna i druge vezane značajke neće biti ponuđene za ova web mjesta. Potrebno je osvježiti stranicu zaprimjenu postavki." }, "autofillBlockedNoticeV2": { - "message": "Autofill is blocked for this website." + "message": "Auto-ispuna je blokirana za ovu web stranicu." }, "autofillBlockedNoticeGuidance": { - "message": "Change this in settings" + "message": "Promijeni ovo u postavkama" + }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" }, "websiteItemLabel": { "message": "Web stranica $number$ (URI)", @@ -2382,7 +2446,7 @@ } }, "blockedDomainsSavedSuccess": { - "message": "Blocked domain changes saved" + "message": "Spremljene promjene blokiranih domena" }, "excludedDomainsSavedSuccess": { "message": "Spremljene promjene izuzete domene" @@ -2823,17 +2887,17 @@ "message": "Pogreška" }, "decryptionError": { - "message": "Decryption error" + "message": "Pogreška pri dešifriranju" }, "couldNotDecryptVaultItemsBelow": { - "message": "Bitwarden could not decrypt the vault item(s) listed below." + "message": "Bitwarden nije mogao dešifrirati sljedeće stavke trezora." }, "contactCSToAvoidDataLossPart1": { - "message": "Contact customer success", + "message": "Kontaktiraj službu za korisnike", "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": "kako bi izbjegli gubitak podataka.", "description": "This is part of a larger sentence. The full sentence will read 'Contact customer success to avoid additional data loss.'" }, "generateUsername": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "Obavijest je poslana na tvoj uređaj." }, + "notificationSentDevicePart1": { + "message": "Otključaj Bitwarden na svojem uređaju ili na" + }, + "notificationSentDeviceAnchor": { + "message": "web trezoru" + }, + "notificationSentDevicePart2": { + "message": "Provjeri slaže li se jedinstvena fraza s ovdje prikazanom prije odobravanja." + }, "aNotificationWasSentToYourDevice": { "message": "Obavijest je poslana na tvoj uređaj" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Provjeri je li trezor otključan i slaže li se jedinstvena fraza s drugim uređajem" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "Dobiti ćeš obavijest kada je tvoj zahtjev odobren" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Prijava pokrenuta" }, + "logInRequestSent": { + "message": "Zahtjev poslan" + }, "exposedMasterPassword": { "message": "Ukradena glavna lozinka" }, @@ -3994,10 +4067,10 @@ "message": "Pristupni ključ uklonjen" }, "autofillSuggestions": { - "message": "Autofill suggestions" + "message": "Prijedlozi auto-ispune" }, "itemSuggestions": { - "message": "Suggested items" + "message": "Predložene stavke" }, "autofillSuggestionsTip": { "message": "Spremi u auto-ispunu stavku prijave za ovu stranicu" @@ -4146,15 +4219,6 @@ "itemName": { "message": "Naziv stavke" }, - "cannotRemoveViewOnlyCollections": { - "message": "S dopuštenjima samo za prikaz ne možeš ukloniti zbirke: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organizacija je deaktivirana" }, @@ -4266,7 +4330,7 @@ "message": "Vjerodajnice za prijavu" }, "authenticatorKey": { - "message": "Kôd za provjeru" + "message": "Ključ autentifikatora" }, "autofillOptions": { "message": "Postavke auto-ispune" @@ -4654,22 +4718,22 @@ "message": "Nemaš prava za uređivanje ove stavke" }, "biometricsStatusHelptextUnlockNeeded": { - "message": "Biometric unlock is unavailable because PIN or password unlock is required first." + "message": "Biometrijsko otključavanje nije dostupno jer je prvo potrebno otključati PIN-om ili lozinkom." }, "biometricsStatusHelptextHardwareUnavailable": { - "message": "Biometric unlock is currently unavailable." + "message": "Biometrijsko otključavanje trenutno nije dostupno." }, "biometricsStatusHelptextAutoSetupNeeded": { - "message": "Biometric unlock is unavailable due to misconfigured system files." + "message": "Biometrijsko otključavanje nije dostupno zbog pogrešno konfiguriranih sistemskih datoteka." }, "biometricsStatusHelptextManualSetupNeeded": { - "message": "Biometric unlock is unavailable due to misconfigured system files." + "message": "Biometrijsko otključavanje nije dostupno zbog pogrešno konfiguriranih sistemskih datoteka." }, "biometricsStatusHelptextDesktopDisconnected": { - "message": "Biometric unlock is unavailable because the Bitwarden desktop app is closed." + "message": "Biometrijsko otključavanje nije dostupno jer je Bitwarden dekstop aplikacija zatvorena." }, "biometricsStatusHelptextNotEnabledInDesktop": { - "message": "Biometric unlock is unavailable because it is not enabled for $EMAIL$ in the Bitwarden desktop app.", + "message": "Biometrijsko otključavanje nije dostupno jer nije omogućeno za $EMAIL$ u Bitwarden desktop aplikaciji.", "placeholders": { "email": { "content": "$1", @@ -4678,7 +4742,7 @@ } }, "biometricsStatusHelptextUnavailableReasonUnknown": { - "message": "Biometric unlock is currently unavailable for an unknown reason." + "message": "Biometrijsko otključavanje trenutno nije dostupno iz nepoznatog razloga." }, "authenticating": { "message": "Autentifikacija" @@ -4887,10 +4951,19 @@ "extraWide": { "message": "Ekstra široko" }, + "cannotRemoveViewOnlyCollections": { + "message": "S dopuštenjima samo za prikaz ne možeš ukloniti zbirke: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { - "message": "Please update your desktop application" + "message": "Molimo, ažuriraj svoju desktop aplikaciju" }, "updateDesktopAppOrDisableFingerprintDialogMessage": { - "message": "To use biometric unlock, please update your desktop application, or disable fingerprint unlock in the desktop settings." + "message": "Za korištenje biometrijskog otključavanja ažuriraj desktop aplikaciju ili nemogući otključavanje otiskom prsta u desktop aplikaciji." } } diff --git a/apps/browser/src/_locales/hu/messages.json b/apps/browser/src/_locales/hu/messages.json index 0f697f8e156..4a56787d919 100644 --- a/apps/browser/src/_locales/hu/messages.json +++ b/apps/browser/src/_locales/hu/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Prémium funkció megvásárlása" }, - "premiumPurchaseAlert": { - "message": "A prémium tagság megvásárolható a bitwarden.com webes széfben. Szeretnénk felkeresni a webhelyet most?" - }, "premiumPurchaseAlertV2": { "message": "Prémium szolgáltatást vásárolhatunk a Bitwarden webalkalmazás fiókbeállításai között." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Felhasználónév generátor" }, + "useThisEmail": { + "message": "Ezen email használata" + }, "useThisPassword": { "message": "Jelszó használata" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Megváltoztatás a beállításokban" }, + "change": { + "message": "Módosítás" + }, + "changeButtonTitle": { + "message": "Jelszó módosítás - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "Veszélyes jelszavak" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ $COUNT$ jelszó meegváltoztatását kéri, mert veszélyben vannak.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "A szervezetek $COUNT$ jelszó meegváltoztatását kérik, mert veszélyben vannak.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Tekintsük át és módosítsuk az egyik veszélyeztetett jelszót." + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Tekintsük át és módosítsunk $COUNT$ kockázatnak kitett jelszót.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Változtassuk meg gyorsabban a veszélyeztetett jelszavakat." + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Frissítsük a beállításokat, hogy gyorsan automatikusan kitölthessük a jelszavakat és újakat generálhassunk." + }, + "turnOnAutofill": { + "message": "Automatikus kitöltés bekapcsolása" + }, + "turnedOnAutofill": { + "message": "Az automatikus kitöltés bekapcsolásra került." + }, + "dismiss": { + "message": "Elvetés" + }, "websiteItemLabel": { "message": "Webhely $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "Egy értesítés lett elküldve az eszközre." }, + "notificationSentDevicePart1": { + "message": "A Bitwarden zárolás feloldása az eszközön vagy: " + }, + "notificationSentDeviceAnchor": { + "message": "webalkalmazás" + }, + "notificationSentDevicePart2": { + "message": "Jóváhagyás előtt győződjünk meg arról, hogy az ujjlenyomat kifejezés megegyezik az alábbi kifejezéssel." + }, "aNotificationWasSentToYourDevice": { "message": "Egy értesítés lett elküldve az eszközre." }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Ellenőrizzük, hogy a széf feloldásra került és az ujjlenyomat kifejezés egyezik a másik eszközön levővel." - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "A kérelem jóváhagyása után értesítés érkezik." }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "A bejelentkezés elindításra került." }, + "logInRequestSent": { + "message": "A kérés elküldésre került." + }, "exposedMasterPassword": { "message": "Kiszivárgott mesterjelszó" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Elem neve" }, - "cannotRemoveViewOnlyCollections": { - "message": "Nem távolíthatók el a csak megtekintési engedéllyel bíró gyűjtemények: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organization is deactivated" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra széles" }, + "cannotRemoveViewOnlyCollections": { + "message": "Nem távolíthatók el a csak megtekintési engedéllyel bíró gyűjtemények: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Frissítsük az asztali alkalmazást." }, diff --git a/apps/browser/src/_locales/id/messages.json b/apps/browser/src/_locales/id/messages.json index aad20632333..8f3a8d5a49b 100644 --- a/apps/browser/src/_locales/id/messages.json +++ b/apps/browser/src/_locales/id/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Beli Keanggotaan Premium" }, - "premiumPurchaseAlert": { - "message": "Anda dapat membeli keanggotaan premium di brankas web bitwarden.com. Anda ingin mengunjungi situs web sekarang?" - }, "premiumPurchaseAlertV2": { "message": "Anda dapat membeli Premium dari pilihan akun Anda pada aplikasi web Bitwarden." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Pembuat nama pengguna" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Gunakan kata sandi ini" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Situs web $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "Sebuah pemberitahuan dikirim ke perangkat Anda." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "Sebuah pemberitahuan telah dikirim ke perangkat Anda" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Pastikan akun Anda terbuka dan frasa sidik jari cocok pada perangkat lainnya" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "Anda akan diberitahu setelah permintaan disetujui" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Memulai login" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Kata Sandi Utama yang Terpapar" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Nama benda" }, - "cannotRemoveViewOnlyCollections": { - "message": "Anda tidak dapat menghapus koleksi dengan izin hanya lihat: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organisasi dinonaktifkan" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Ekstra lebar" }, + "cannotRemoveViewOnlyCollections": { + "message": "Anda tidak dapat menghapus koleksi dengan izin hanya lihat: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/it/messages.json b/apps/browser/src/_locales/it/messages.json index 6258385e64a..62303f90021 100644 --- a/apps/browser/src/_locales/it/messages.json +++ b/apps/browser/src/_locales/it/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Passa a Premium" }, - "premiumPurchaseAlert": { - "message": "Puoi acquistare il un abbonamento Premium dalla cassaforte web su bitwarden.com. Vuoi visitare il sito?" - }, "premiumPurchaseAlertV2": { "message": "Puoi acquistare Premium dalle impostazioni del tuo account sull'app web Bitwarden." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Generatore di nomi utente" }, + "useThisEmail": { + "message": "Usa questa e-mail" + }, "useThisPassword": { "message": "Usa questa password" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Modifica questo nelle impostazioni" }, + "change": { + "message": "Cambia" + }, + "changeButtonTitle": { + "message": "Cambia parola d'accesso - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "Parola d'accesso a rischio" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ ti sta richiedendo di modificare $COUNT$ parole d'accesso perché sono a rischio.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Le tue organizzazioni ti chiedono di modificare le $COUNT$ parole d'accesso perché sono a rischio.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Rivedi e modifica una parola d'accesso a rischio" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Rivedi e modifica $COUNT$ parole d'accesso a rischio", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Cambia le parole d'accesso a rischio più velocemente" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Aggiorna le impostazioni in modo da poter rapidamente riempire automaticamente le parole d'accesso e generarne di nuove" + }, + "turnOnAutofill": { + "message": "Attiva riempimento automatico" + }, + "turnedOnAutofill": { + "message": "Riempimento automatico attivato" + }, + "dismiss": { + "message": "Ignora" + }, "websiteItemLabel": { "message": "Sito $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "Una notifica è stata inviata al tuo dispositivo." }, + "notificationSentDevicePart1": { + "message": "Sblocca Bitwarden sul tuo dispositivo o su" + }, + "notificationSentDeviceAnchor": { + "message": "app web" + }, + "notificationSentDevicePart2": { + "message": "Assicurarsi che la frase di impronta digitale corrisponda a quella sottostante prima dell'approvazione." + }, "aNotificationWasSentToYourDevice": { "message": "Una notifica è stata inviata al tuo dispositivo" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Assicurati che il tuo account sia sbloccato e che la frase dell'impronta digitale corrisponda nell'altro dispositivo" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "Sarai notificato una volta che la richiesta sarà approvata" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Accesso avviato" }, + "logInRequestSent": { + "message": "Richiesta inviata" + }, "exposedMasterPassword": { "message": "Password principale violata" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Nome elemento" }, - "cannotRemoveViewOnlyCollections": { - "message": "Non puoi rimuovere raccolte con i soli permessi di visualizzazione: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "L'organizzazione è disattivata" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Molto larga" }, + "cannotRemoveViewOnlyCollections": { + "message": "Non puoi rimuovere raccolte con i soli permessi di visualizzazione: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Aggiornare l'applicazione desktop" }, diff --git a/apps/browser/src/_locales/ja/messages.json b/apps/browser/src/_locales/ja/messages.json index e6e464a67de..706fe156879 100644 --- a/apps/browser/src/_locales/ja/messages.json +++ b/apps/browser/src/_locales/ja/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "プレミアム会員に加入" }, - "premiumPurchaseAlert": { - "message": "プレミアム会員権は bitwarden.com ウェブ保管庫で購入できます。ウェブサイトを開きますか?" - }, "premiumPurchaseAlertV2": { "message": "Bitwarden ウェブアプリでアカウント設定からプレミアムを購入できます。" }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "ユーザー名生成ツール" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "このパスワードを使用する" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "ウェブサイト $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "デバイスに通知を送信しました。" }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "お使いのデバイスに通知が送信されました" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "アカウントがロック解除されていることと、フィンガープリントフレーズが他の端末で一致していることを確認してください" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "リクエストが承認されると通知されます" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "ログイン開始" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "流出したマスターパスワード" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "アイテム名" }, - "cannotRemoveViewOnlyCollections": { - "message": "表示のみの権限が与えられているコレクションを削除することはできません: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "組織は無効化されています" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "エクストラワイド" }, + "cannotRemoveViewOnlyCollections": { + "message": "表示のみの権限が与えられているコレクションを削除することはできません: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/ka/messages.json b/apps/browser/src/_locales/ka/messages.json index 795d78ca6e0..e7f8f721640 100644 --- a/apps/browser/src/_locales/ka/messages.json +++ b/apps/browser/src/_locales/ka/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Purchase Premium" }, - "premiumPurchaseAlert": { - "message": "You can purchase Premium membership on the bitwarden.com web vault. Do you want to visit the website now?" - }, "premiumPurchaseAlertV2": { "message": "You can purchase Premium from your account settings on the Bitwarden web app." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Username generator" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Use this password" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Website $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "You will be notified once the request is approved" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Login initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Exposed Master Password" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "ჩანაწერის სახელი" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organization is deactivated" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra wide" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/km/messages.json b/apps/browser/src/_locales/km/messages.json index a228cf8ff55..33ba50ddab4 100644 --- a/apps/browser/src/_locales/km/messages.json +++ b/apps/browser/src/_locales/km/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Purchase Premium" }, - "premiumPurchaseAlert": { - "message": "You can purchase Premium membership on the bitwarden.com web vault. Do you want to visit the website now?" - }, "premiumPurchaseAlertV2": { "message": "You can purchase Premium from your account settings on the Bitwarden web app." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Username generator" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Use this password" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Website $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "You will be notified once the request is approved" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Login initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Exposed Master Password" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organization is deactivated" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra wide" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/kn/messages.json b/apps/browser/src/_locales/kn/messages.json index 594c9a83760..83ed983db46 100644 --- a/apps/browser/src/_locales/kn/messages.json +++ b/apps/browser/src/_locales/kn/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "ಪ್ರೀಮಿಯಂ ಖರೀದಿಸಿ" }, - "premiumPurchaseAlert": { - "message": "ನೀವು ಬಿಟ್ವಾರ್ಡೆನ್.ಕಾಮ್ ವೆಬ್ ವಾಲ್ಟ್ನಲ್ಲಿ ಪ್ರೀಮಿಯಂ ಸದಸ್ಯತ್ವವನ್ನು ಖರೀದಿಸಬಹುದು. ನೀವು ಈಗ ವೆಬ್‌ಸೈಟ್‌ಗೆ ಭೇಟಿ ನೀಡಲು ಬಯಸುವಿರಾ?" - }, "premiumPurchaseAlertV2": { "message": "You can purchase Premium from your account settings on the Bitwarden web app." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Username generator" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Use this password" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Website $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "You will be notified once the request is approved" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Login initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Exposed Master Password" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organization is deactivated" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra wide" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/ko/messages.json b/apps/browser/src/_locales/ko/messages.json index 0aeb64283b8..305580ad0d3 100644 --- a/apps/browser/src/_locales/ko/messages.json +++ b/apps/browser/src/_locales/ko/messages.json @@ -1005,7 +1005,7 @@ "message": "보관함에 항목이 없을 경우 추가하라는 메시지를 표시합니다. 모든 로그인된 계정에 적용됩니다." }, "showCardsInVaultViewV2": { - "message": "Always show cards as Autofill suggestions on Vault view" + "message": "보관함 보기에서 언제나 카드 자동 완성 제안을 표시" }, "showCardsCurrentTab": { "message": "탭 페이지에 카드 표시" @@ -1014,7 +1014,7 @@ "message": "간편한 자동완성을 위해 탭에 카드 항목들을 나열" }, "showIdentitiesInVaultViewV2": { - "message": "Always show identities as Autofill suggestions on Vault view" + "message": "보관함 보기에서 언제나 신원의 자동 완성 제안을 표시" }, "showIdentitiesCurrentTab": { "message": "탭 페이지에 신원들을 표시" @@ -1125,10 +1125,10 @@ "message": "이 비밀번호는 이 파일을 파일 내보내거나, 가져오는데 사용됩니다." }, "accountRestrictedOptionDescription": { - "message": "계정의 사용자 이름과 마스터 비밀번호에서 파생된 계정 암호화 키를 사용하여 내보내기를 암호화하고, 현재 Bitwarden계정으만 가져오기를 제한합니다." + "message": "내보내기를 당신의 계정의 사용자이름과 마스터비밀번호로부터 파생된 계정 암호화 키를 사용하여 암호화하고, 현재의 Bitwarden 계정으로만 가져오도록 제한합니다." }, "passwordProtectedOptionDescription": { - "message": "파일 비밀번호를 설정하여 내보내기를 암호화하고, 어느 Bitwarden 계정으로든 해독에 그 파일 비밀번호를 사용하여 가져오세요." + "message": "파일에 비밀번호를 설정하여 내보내기를 암호화하고, 어느 Bitwarden 계정으로든 그 비밀번호로 해독하여 가져오기 합니다." }, "exportTypeHeading": { "message": "내보내기 유형" @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "프리미엄 멤버십 구입" }, - "premiumPurchaseAlert": { - "message": "bitwarden.com 웹 보관함에서 프리미엄 멤버십을 구입할 수 있습니다. 지금 웹 사이트를 방문하시겠습니까?" - }, "premiumPurchaseAlertV2": { "message": "Bitwarden 웹 앱의 계정 설정에서 프리미엄에 대한 결제를 할 수 있습니다." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "사용자 이름 생성기" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "이 비밀번호 사용" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "웹사이트 $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "기기에 알림이 전송되었습니다." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "기기에 알림이 전송되었습니다." }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "반드시 계정이 잠금 해제되었고, 지문 구절이 다른 기기에서 일치하는지 확인해주세요." - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "요청이 승인되면 알림을 받게 됩니다" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "로그인 시작" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "노출된 마스터 비밀번호" }, @@ -3994,7 +4067,7 @@ "message": "패스키 제거됨" }, "autofillSuggestions": { - "message": "Autofill suggestions" + "message": "자동 완성 제안" }, "itemSuggestions": { "message": "Suggested items" @@ -4146,15 +4219,6 @@ "itemName": { "message": "항목 이름" }, - "cannotRemoveViewOnlyCollections": { - "message": "보기 권한만 있는 컬렉션은 제거할 수 없습니다: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "조직이 비활성화되었습니다" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "매우 넓게" }, + "cannotRemoveViewOnlyCollections": { + "message": "보기 권한만 있는 컬렉션은 제거할 수 없습니다: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/lt/messages.json b/apps/browser/src/_locales/lt/messages.json index 901fd6cea26..8e0e0124c85 100644 --- a/apps/browser/src/_locales/lt/messages.json +++ b/apps/browser/src/_locales/lt/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Įsigyti Premium" }, - "premiumPurchaseAlert": { - "message": "Galite įsigyti „Premium“ narystę „bitwarden.com“ žiniatinklio saugykloje. Ar norite apsilankyti svetainėje dabar?" - }, "premiumPurchaseAlertV2": { "message": "You can purchase Premium from your account settings on the Bitwarden web app." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Username generator" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Use this password" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Website $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "You will be notified once the request is approved" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Pradėtas prisijungimas" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Exposed Master Password" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Elemento pavadinimas" }, - "cannotRemoveViewOnlyCollections": { - "message": "Negalite pašalinti kolekcijų su Peržiūrėti tik leidimus: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organization is deactivated" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra wide" }, + "cannotRemoveViewOnlyCollections": { + "message": "Negalite pašalinti kolekcijų su Peržiūrėti tik leidimus: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/lv/messages.json b/apps/browser/src/_locales/lv/messages.json index 822ea75915c..0a9904e23c4 100644 --- a/apps/browser/src/_locales/lv/messages.json +++ b/apps/browser/src/_locales/lv/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Iegādāties Premium" }, - "premiumPurchaseAlert": { - "message": "Premium dalību ir iespējams iegādāties bitwarden.com tīmekļa glabātavā. Vai tagad apmeklēt tīmekļvietni?" - }, "premiumPurchaseAlertV2": { "message": "Premium var iegādāties Bitwarden tīmekļa lietotnē sava konta iestatījumos." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Lietotājvārdu veidotājs" }, + "useThisEmail": { + "message": "Izmantot šo e-pasta adresi" + }, "useThisPassword": { "message": "Izmantot šo paroli" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "To var mainīt iestatījumos" }, + "change": { + "message": "Mainīt" + }, + "changeButtonTitle": { + "message": "Mainīt paroli - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "Riskam pakļautās paroles" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ pieprasa mainīt $COUNT$ paroles, jo tās ir pakļautas riskam.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Apvienības pieprasa mainīt $COUNT$ paroles, jo tās ir pakļautas riskam.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Pārskatīt un mainīt vienu riskam pakļautu paroli" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Pārskatīt un mainīt $COUNT$ riskam pakļautās paroles", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Mainīt riskam pakļautās paroles ātrāk" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Jāatjaunina savi iestatījumi, lai varētu veikli aizpildīt paroles automātiski un izveidot jaunas" + }, + "turnOnAutofill": { + "message": "Ieslēgt automātisko aizpildi" + }, + "turnedOnAutofill": { + "message": "Automātiskā aizpilde ieslēgta" + }, + "dismiss": { + "message": "Noraidīt" + }, "websiteItemLabel": { "message": "Tīmekļvietne $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "Uz ierīci ir nosūtīts paziņojums." }, + "notificationSentDevicePart1": { + "message": "Bitwarden jāatslēdz savā ierīcē vai" + }, + "notificationSentDeviceAnchor": { + "message": "tīmekļa lietotnē" + }, + "notificationSentDevicePart2": { + "message": "Pirms apstiprināšanas jāpārliecinās, ka pirkstu nospieduma vārdkopa atbilst zemāk esošajai." + }, "aNotificationWasSentToYourDevice": { "message": "Uz ierīci tika nosūtīts paziņojums" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Lūgums pārliecināties, ka konts ir atslēgts un atpazīšanas vārdkopa ir tāda pati arī otrā ierīcē" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "Tiks paziņots, tiklīdz pieprasījums būs apstiprināts" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Uzsākta pieteikšanās" }, + "logInRequestSent": { + "message": "Pieprasījums nosūtīts" + }, "exposedMasterPassword": { "message": "Noplūdusi galvenā parole" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Vienuma nosaukums" }, - "cannotRemoveViewOnlyCollections": { - "message": "Nevar noņemt krājumus ar tiesībām \"Tikai skatīt\": $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Apvienība ir atspējota" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Ļoti plats" }, + "cannotRemoveViewOnlyCollections": { + "message": "Nevar noņemt krājumus ar tiesībām \"Tikai skatīt\": $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Lūgums atjaunināt darbvirsmas lietotni" }, diff --git a/apps/browser/src/_locales/ml/messages.json b/apps/browser/src/_locales/ml/messages.json index 66da0de2b53..e33dd435847 100644 --- a/apps/browser/src/_locales/ml/messages.json +++ b/apps/browser/src/_locales/ml/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "പ്രീമിയം വാങ്ങുക" }, - "premiumPurchaseAlert": { - "message": "നിങ്ങൾക്ക് bitwarden.com വെബ് വാൾട്ടിൽ പ്രീമിയം അംഗത്വം വാങ്ങാം. നിങ്ങൾക്ക് ഇപ്പോൾ വെബ്സൈറ്റ് സന്ദർശിക്കാൻ ആഗ്രഹമുണ്ടോ?" - }, "premiumPurchaseAlertV2": { "message": "You can purchase Premium from your account settings on the Bitwarden web app." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Username generator" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Use this password" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Website $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "You will be notified once the request is approved" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Login initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Exposed Master Password" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organization is deactivated" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra wide" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/mr/messages.json b/apps/browser/src/_locales/mr/messages.json index 757bce23807..9af8fb24289 100644 --- a/apps/browser/src/_locales/mr/messages.json +++ b/apps/browser/src/_locales/mr/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Purchase Premium" }, - "premiumPurchaseAlert": { - "message": "You can purchase Premium membership on the bitwarden.com web vault. Do you want to visit the website now?" - }, "premiumPurchaseAlertV2": { "message": "You can purchase Premium from your account settings on the Bitwarden web app." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Username generator" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Use this password" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Website $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "You will be notified once the request is approved" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Login initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Exposed Master Password" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organization is deactivated" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra wide" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/my/messages.json b/apps/browser/src/_locales/my/messages.json index a228cf8ff55..33ba50ddab4 100644 --- a/apps/browser/src/_locales/my/messages.json +++ b/apps/browser/src/_locales/my/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Purchase Premium" }, - "premiumPurchaseAlert": { - "message": "You can purchase Premium membership on the bitwarden.com web vault. Do you want to visit the website now?" - }, "premiumPurchaseAlertV2": { "message": "You can purchase Premium from your account settings on the Bitwarden web app." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Username generator" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Use this password" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Website $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "You will be notified once the request is approved" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Login initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Exposed Master Password" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organization is deactivated" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra wide" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/nb/messages.json b/apps/browser/src/_locales/nb/messages.json index 6eccbe93cc5..3eb30df99d5 100644 --- a/apps/browser/src/_locales/nb/messages.json +++ b/apps/browser/src/_locales/nb/messages.json @@ -7,7 +7,7 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "message": "Hjemme, på jobben eller på farten sikrer Bitwarden enkelt alle dine passord, passnøkler og sensitiv informasjon", "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { @@ -141,7 +141,7 @@ "message": "Kopiér navn" }, "copyCompany": { - "message": "Copy company" + "message": "Kopiér firma" }, "copySSN": { "message": "Kopiér fødselsnummer" @@ -281,13 +281,13 @@ "message": "Endre hovedpassordet" }, "continueToWebApp": { - "message": "Continue to web app?" + "message": "Vil du fortsette til nettappen?" }, "continueToWebAppDesc": { "message": "Explore more features of your Bitwarden account on the web app." }, "continueToHelpCenter": { - "message": "Continue to Help Center?" + "message": "Vil du fortsette til Hjelpesenteret?" }, "continueToHelpCenterDesc": { "message": "Learn more about how to use Bitwarden on the Help Center." @@ -299,7 +299,7 @@ "message": "Help others find out if Bitwarden is right for them. Visit your browser's extension store and leave a rating now." }, "changeMasterPasswordOnWebConfirmation": { - "message": "You can change your master password on the Bitwarden web app." + "message": "Du kan endre hovedpassordet ditt i Bitwardens nettapp." }, "fingerprintPhrase": { "message": "Fingeravtrykksfrase", @@ -322,16 +322,16 @@ "message": "Om" }, "moreFromBitwarden": { - "message": "More from Bitwarden" + "message": "Mer fra Bitwarden" }, "continueToBitwardenDotCom": { "message": "Vil du fortsette til bitwarden.com?" }, "bitwardenForBusiness": { - "message": "Bitwarden for Business" + "message": "Bitwarden for bedrifter" }, "bitwardenAuthenticator": { - "message": "Bitwarden Authenticator" + "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" @@ -431,7 +431,7 @@ "message": "Generer automatisk sterke og unike passord for dine innlogginger." }, "bitWebVaultApp": { - "message": "Bitwarden web app" + "message": "Bitwardens nett-app" }, "importItems": { "message": "Importer elementer" @@ -443,19 +443,19 @@ "message": "Generer et passord" }, "generatePassphrase": { - "message": "Generate passphrase" + "message": "Generér passordfrase" }, "passwordGenerated": { - "message": "Password generated" + "message": "Passord generert" }, "passphraseGenerated": { - "message": "Passphrase generated" + "message": "Passordfrase generert" }, "usernameGenerated": { - "message": "Username generated" + "message": "Brukernavn generert" }, "emailGenerated": { - "message": "Email generated" + "message": "E-postadresse generert" }, "regeneratePassword": { "message": "Omgenerer et passord" @@ -567,7 +567,7 @@ "message": "Passord" }, "totp": { - "message": "Authenticator secret" + "message": "Autentiseringsnøkkel" }, "passphrase": { "message": "Passfrase" @@ -633,7 +633,7 @@ "message": "Annet" }, "unlockMethods": { - "message": "Unlock options" + "message": "Opplåsingsalternativer" }, "unlockMethodNeededToChangeTimeoutActionDesc": { "message": "Set up an unlock method to change your vault timeout action." @@ -642,10 +642,10 @@ "message": "Set up an unlock method in Settings" }, "sessionTimeoutHeader": { - "message": "Session timeout" + "message": "Tidsavbrudd for økten" }, "vaultTimeoutHeader": { - "message": "Vault timeout" + "message": "Tidsavbrudd for hvelvet" }, "otherOptions": { "message": "Andre valg" @@ -663,16 +663,16 @@ "message": "We don't recognize this device. Enter the code sent to your email to verify your identity." }, "continueLoggingIn": { - "message": "Continue logging in" + "message": "Fortsett innloggingen" }, "yourVaultIsLocked": { "message": "Hvelvet ditt er låst. Kontroller hovedpassordet ditt for å fortsette." }, "yourVaultIsLockedV2": { - "message": "Your vault is locked" + "message": "Hvelvet ditt er låst" }, "yourAccountIsLocked": { - "message": "Your account is locked" + "message": "Kontoen din er låst" }, "or": { "message": "eller" @@ -797,10 +797,10 @@ "message": "Din nye konto har blitt opprettet! Du kan nå logge på." }, "newAccountCreated2": { - "message": "Your new account has been created!" + "message": "Den nye kontoen din er opprettet!" }, "youHaveBeenLoggedIn": { - "message": "You have been logged in!" + "message": "Du har blitt logget inn!" }, "youSuccessfullyLoggedIn": { "message": "Du har vellykket logget inn" @@ -861,7 +861,7 @@ "message": "Logget av" }, "loggedOutDesc": { - "message": "You have been logged out of your account." + "message": "Du har blitt logget ut av kontoen din." }, "loginExpired": { "message": "Din innloggingsøkt har utløpt." @@ -873,7 +873,7 @@ "message": "Logg inn på Bitwarden" }, "restartRegistration": { - "message": "Restart registration" + "message": "Start registreringen på nytt" }, "expiredLink": { "message": "Utløpt lenke" @@ -909,7 +909,7 @@ "message": "Make your account more secure by setting up two-step login in the Bitwarden web app." }, "twoStepLoginConfirmationTitle": { - "message": "Continue to web app?" + "message": "Vil du fortsette til nettappen?" }, "editedFolder": { "message": "Redigerte mappen" @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Kjøp Premium" }, - "premiumPurchaseAlert": { - "message": "Du kan kjøpe et Premium-medlemskap på bitwarden.com. Vil du besøke det nettstedet nå?" - }, "premiumPurchaseAlertV2": { "message": "You can purchase Premium from your account settings on the Bitwarden web app." }, @@ -1293,7 +1290,7 @@ "message": "Takk for at du støtter Bitwarden." }, "premiumFeatures": { - "message": "Upgrade to Premium and receive:" + "message": "Oppgrader til Premium og motta:" }, "premiumPrice": { "message": "Og alt det for %price%/år!", @@ -1480,29 +1477,29 @@ "message": "Miljø-nettadressene har blitt lagret." }, "showAutoFillMenuOnFormFields": { - "message": "Show autofill menu on form fields", + "message": "Vis autoutfyll-menyen i tekstbokser", "description": "Represents the message for allowing the user to enable the autofill overlay" }, "autofillSuggestionsSectionTitle": { "message": "Autoutfyllingsforslag" }, "showInlineMenuLabel": { - "message": "Show autofill suggestions on form fields" + "message": "Vis autoutfyll-forslag i tekstbokser" }, "showInlineMenuIdentitiesLabel": { - "message": "Display identities as suggestions" + "message": "Vis identiteter som forslag" }, "showInlineMenuCardsLabel": { - "message": "Display cards as suggestions" + "message": "Vis kort som forslag" }, "showInlineMenuOnIconSelectionLabel": { - "message": "Display suggestions when icon is selected" + "message": "Vis forslag når ikonet er valgt" }, "showInlineMenuOnFormFieldsDescAlt": { "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser's built in password manager settings to avoid conflicts." + "message": "Skru av din nettlesers innebygde passordbehandler for å unngå konflikter." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Rediger nettleserinnstillingene." @@ -1541,7 +1538,7 @@ "message": "Standard autofyll innstilling for innloggingselementer" }, "defaultAutoFillOnPageLoadDesc": { - "message": "Etter aktivering av auto-utfylling på sidelasser, kan du aktivere eller deaktivere funksjonen for individuelle innloggingselementer. Dette er standardinnstillingen for innloggingselementer som ikke er satt opp separat." + "message": "Du kan skru av auto-utfylling ved sideinnlastinger for individuelle innloggingsgjenstander fra gjenstandens «Redigér»-visning." }, "itemAutoFillOnPageLoad": { "message": "Auto-utfyll på sideinnlastning (hvis aktivert i Alternativer)" @@ -1601,7 +1598,7 @@ "message": "Boolsk verdi" }, "cfTypeCheckbox": { - "message": "Checkbox" + "message": "Avkryssingsboks" }, "cfTypeLinked": { "message": "Tilkoblet", @@ -1822,7 +1819,7 @@ "message": "Generatorhistorikk" }, "clearGeneratorHistoryTitle": { - "message": "Clear generator history" + "message": "Tøm generatorhistorikk" }, "cleargGeneratorHistoryDescription": { "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" @@ -1834,7 +1831,7 @@ "message": "Samlinger" }, "nCollections": { - "message": "$COUNT$ collections", + "message": "$COUNT$ samlinger", "placeholders": { "count": { "content": "$1", @@ -1890,7 +1887,7 @@ "description": "Domain name. Ex. website.com" }, "baseDomainOptionRecommended": { - "message": "Base domain (recommended)", + "message": "Grunndomene (anbefalt)", "description": "Domain name. Ex. website.com" }, "domainName": { @@ -1950,7 +1947,7 @@ "message": "Ingenting å vise" }, "nothingGeneratedRecently": { - "message": "You haven't generated anything recently" + "message": "Du har ikke generert noe i det siste" }, "remove": { "message": "Fjern" @@ -2020,7 +2017,7 @@ "message": "Angi PIN-koden din for å låse opp Bitwarden. PIN-innstillingene tilbakestilles hvis du logger deg helt ut av 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": "PIN-koden din vil bli brukt til å låse opp Bitwarden i stedet for hovedpassordet ditt. PIN-koden din tilbakestilles hvis du noen gang logger deg helt ut av Bitwarden." }, "pinRequired": { "message": "PIN-kode er påkrevd." @@ -2029,7 +2026,7 @@ "message": "Ugyldig PIN-kode." }, "tooManyInvalidPinEntryAttemptsLoggingOut": { - "message": "Too many invalid PIN entry attempts. Logging out." + "message": "For mange ugyldige PIN-kodeforsøk. Logger ut." }, "unlockWithBiometrics": { "message": "Lås opp med biometri" @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Brukernavngenerator" }, + "useThisEmail": { + "message": "Bruk denne E-postadressen" + }, "useThisPassword": { "message": "Bruk dette passordet" }, @@ -2078,14 +2078,14 @@ "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": "for å lage et sterkt og unikt passord", "description": "This will be used as part of a larger sentence, broken up to include the generator icon. The full sentence will read 'Use the generator [GENERATOR_ICON] to create a strong unique password'" }, "vaultTimeoutAction": { "message": "Handling ved tidsavbrudd i hvelvet" }, "vaultTimeoutAction1": { - "message": "Timeout action" + "message": "Handling ved tidsavbrudd" }, "lock": { "message": "Lås", @@ -2135,7 +2135,7 @@ "message": "Autoutfylt element" }, "insecurePageWarning": { - "message": "Warning: This is an unsecured HTTP page, and any information you submit can potentially be seen and changed by others. This Login was originally saved on a secure (HTTPS) page." + "message": "Advarsel: Dette er en usikret HTTP-side, og all informasjon du sender inn kan potensielt bli sett og endret av andre. Denne påloggingen ble opprinnelig lagret på et sikkert (HTTPS) nettsted." }, "insecurePageWarningFillPrompt": { "message": "Ønsker du likevel å fylle ut denne innloggingen?" @@ -2306,7 +2306,7 @@ "message": "Please unlock this user in the desktop application and try again." }, "biometricsNotAvailableTitle": { - "message": "Biometric unlock unavailable" + "message": "Biometrisk opplåsing er utilgjengelig" }, "biometricsNotAvailableDesc": { "message": "Biometric unlock is currently unavailable. Please try again later." @@ -2361,10 +2361,74 @@ "message": "Autofill is blocked for this website." }, "autofillBlockedNoticeGuidance": { - "message": "Change this in settings" + "message": "Endre dette i innstillingene" + }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" }, "websiteItemLabel": { - "message": "Website $number$ (URI)", + "message": "Nettsted $number$ (URİ)", "placeholders": { "number": { "content": "$1", @@ -2391,11 +2455,11 @@ "message": "Begrens visninger" }, "limitSendViewsHint": { - "message": "No one can view this Send after the limit is reached.", + "message": "Ingen kan se denne Send-en etter at grensen er nådd.", "description": "Displayed under the limit views field on Send" }, "limitSendViewsCount": { - "message": "$ACCESSCOUNT$ views left", + "message": "$ACCESSCOUNT$ visninger igjen", "description": "Displayed under the limit views field on Send", "placeholders": { "accessCount": { @@ -2409,7 +2473,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendDetails": { - "message": "Send details", + "message": "Send-detaljer", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendTypeText": { @@ -2426,7 +2490,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "hideTextByDefault": { - "message": "Hide text by default" + "message": "Skjul tekst som standard" }, "expired": { "message": "Utløpt" @@ -2506,7 +2570,7 @@ "message": "Egendefinert" }, "sendPasswordDescV3": { - "message": "Add an optional password for recipients to access this Send.", + "message": "Legg til et valgfritt passord for at mottakerne skal få tilgang til denne Send-en.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "createSend": { @@ -2561,7 +2625,7 @@ } }, "sendLinkCopied": { - "message": "Send link copied", + "message": "Send-lenken ble kopiert", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "editedSend": { @@ -2569,7 +2633,7 @@ "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": "Vil du sprette ut utvidelsen?", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendFilePopoutDialogDesc": { @@ -2586,7 +2650,7 @@ "message": "For å velge en fil med Safari, popp ut i et nytt vindu ved å klikke på dette banneret." }, "popOut": { - "message": "Pop out" + "message": "Sprett ut" }, "sendFileCalloutHeader": { "message": "Før du starter" @@ -2607,7 +2671,7 @@ "message": "Det oppstod en feil ved lagring av slettingen og utløpsdatoene." }, "hideYourEmail": { - "message": "Hide your email address from viewers." + "message": "Skjul E-postadressen din fra seere." }, "passwordPrompt": { "message": "Forespørsel om hovedpassord på nytt" @@ -2833,14 +2897,14 @@ "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": "for å unngå ytterligere datatap.", "description": "This is part of a larger sentence. The full sentence will read 'Contact customer success to avoid additional data loss.'" }, "generateUsername": { "message": "Generer brukernavn" }, "generateEmail": { - "message": "Generate email" + "message": "Generér E-post" }, "spinboxBoundariesHint": { "message": "Verdien må være mellom $MIN$ og $MAX$.", @@ -2857,7 +2921,7 @@ } }, "passwordLengthRecommendationHint": { - "message": " Use $RECOMMENDED$ characters or more to generate a strong password.", + "message": " Bruk minst $RECOMMENDED$ tegn for å generere et sterkt passord.", "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": { @@ -2912,7 +2976,7 @@ "description": "Labels the domain name email forwarder service option" }, "forwarderDomainNameHint": { - "message": "Choose a domain that is supported by the selected service", + "message": "Velg et domene som støttes av den valgte tjenesten", "description": "Guidance provided for email forwarding services that support multiple email domains." }, "forwarderError": { @@ -2944,7 +3008,7 @@ } }, "forwaderInvalidToken": { - "message": "Invalid $SERVICENAME$ API token", + "message": "Ugyldig $SERVICENAME$-API-sjetong", "description": "Displayed when the user's API token is empty or rejected by the forwarding service.", "placeholders": { "servicename": { @@ -2954,7 +3018,7 @@ } }, "forwaderInvalidTokenWithMessage": { - "message": "Invalid $SERVICENAME$ API token: $ERRORMESSAGE$", + "message": "Ugyldig $SERVICENAME$-API-sjetong: $ERRORMESSAGE$", "description": "Displayed when the user's API token is rejected by the forwarding service with an error message.", "placeholders": { "servicename": { @@ -2998,7 +3062,7 @@ } }, "forwarderUnknownError": { - "message": "Unknown $SERVICENAME$ error occurred.", + "message": "Ukjent $SERVICENAME$-feil oppstod.", "description": "Displayed when the forwarding service failed due to an unknown error.", "placeholders": { "servicename": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "Et varsel er sendt til enheten din." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "nett-app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "Et varsel ble sendt til enheten din" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "You will be notified once the request is approved" }, @@ -3136,7 +3206,10 @@ "message": "Trenger du et annet alternativ?" }, "loginInitiated": { - "message": "Login initiated" + "message": "Innlogging igangsatt" + }, + "logInRequestSent": { + "message": "Forespørsel sendt" }, "exposedMasterPassword": { "message": "Eksponert hovedpassord" @@ -3196,10 +3269,10 @@ "message": "Autofill shortcut" }, "autofillKeyboardShortcutUpdateLabel": { - "message": "Change shortcut" + "message": "Endre snarvei" }, "autofillKeyboardManagerShortcutsLabel": { - "message": "Manage shortcuts" + "message": "Behandle snarveier" }, "autofillShortcut": { "message": "Auto-utfyll tastatursnarvei" @@ -3208,7 +3281,7 @@ "message": "The autofill login shortcut is not set. Change this in the browser's settings." }, "autofillLoginShortcutText": { - "message": "The autofill login shortcut is $COMMAND$. Manage all shortcuts in the browser's settings.", + "message": "Autoutfyll-snarveien for pålogging er $COMMAND$. Håndter alle snarveiene i nettleserens innstillinger.", "placeholders": { "command": { "content": "$1", @@ -3262,16 +3335,16 @@ "message": "Oppretter en konto på" }, "checkYourEmail": { - "message": "Check your email" + "message": "Sjekk E-postinnboksen din" }, "followTheLinkInTheEmailSentTo": { - "message": "Follow the link in the email sent to" + "message": "Følg lenken i E-postadressen som ble sendt til" }, "andContinueCreatingYourAccount": { "message": "and continue creating your account." }, "noEmail": { - "message": "No email?" + "message": "Ingen E-post?" }, "goBack": { "message": "Gå tilbake" @@ -3320,11 +3393,11 @@ "message": "Enheten er betrodd" }, "sendsNoItemsTitle": { - "message": "No active Sends", + "message": "Ingen aktive Send", "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": "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." }, "inputRequired": { @@ -3401,10 +3474,10 @@ } }, "singleFieldNeedsAttention": { - "message": "1 field needs your attention." + "message": "1 felt trenger din oppmerksomhet." }, "multipleFieldsNeedAttention": { - "message": "$COUNT$ fields need your attention.", + "message": "$COUNT$ felter trenger din oppmerksomhet.", "placeholders": { "count": { "content": "$1", @@ -3440,7 +3513,7 @@ "message": "Undermeny" }, "toggleCollapse": { - "message": "Toggle collapse", + "message": "Utvid eller klapp sammen", "description": "Toggling an expand/collapse state." }, "aliasDomain": { @@ -3646,7 +3719,7 @@ "message": "Popout extension" }, "launchDuo": { - "message": "Launch Duo" + "message": "Start Duo" }, "importFormatError": { "message": "Data is not formatted correctly. Please check your import file and try again." @@ -3720,13 +3793,13 @@ "message": "Bekreft filpassord" }, "exportSuccess": { - "message": "Vault data exported" + "message": "Hvelvdataen ble eksportert" }, "typePasskey": { "message": "Passnøkkel" }, "accessing": { - "message": "Accessing" + "message": "Logger inn på" }, "loggedInExclamation": { "message": "Innlogget!" @@ -3756,7 +3829,7 @@ "message": "No matching logins for this site" }, "searchSavePasskeyNewLogin": { - "message": "Search or save passkey as new login" + "message": "Søk eller lagre passnøkkelen som en ny innlogging" }, "confirm": { "message": "Bekreft" @@ -3774,7 +3847,7 @@ "message": "Choose a passkey to log in with" }, "passkeyItem": { - "message": "Passkey Item" + "message": "Passkode-gjenstand" }, "overwritePasskey": { "message": "Overwrite passkey?" @@ -3921,7 +3994,7 @@ "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": "Vil du fortsette til Hjelpesenteret?", "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" }, "confirmContinueToHelpCenterPasswordManagementContent": { @@ -3941,7 +4014,7 @@ "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": "Vil du sette Bitwarden som din standard passordbehandler?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { @@ -3994,10 +4067,10 @@ "message": "Passkey removed" }, "autofillSuggestions": { - "message": "Autofill suggestions" + "message": "Autoutfyllingsforslag" }, "itemSuggestions": { - "message": "Suggested items" + "message": "Foreslåtte gjenstander" }, "autofillSuggestionsTip": { "message": "Save a login item for this site to autofill" @@ -4012,7 +4085,7 @@ "message": "Clear filters or try another search term" }, "copyInfoTitle": { - "message": "Copy info - $ITEMNAME$", + "message": "Kopiér info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", "placeholders": { "itemname": { @@ -4022,7 +4095,7 @@ } }, "copyNoteTitle": { - "message": "Copy Note - $ITEMNAME$", + "message": "Kopiér notat - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", "placeholders": { "itemname": { @@ -4072,7 +4145,7 @@ } }, "noValuesToCopy": { - "message": "No values to copy" + "message": "Ingen verdier å kopiere" }, "assignToCollections": { "message": "Legg til i samlinger" @@ -4081,10 +4154,10 @@ "message": "Copy email" }, "copyPhone": { - "message": "Copy phone" + "message": "Kopiér telefonnummer" }, "copyAddress": { - "message": "Copy address" + "message": "Kopiér adresse" }, "adminConsole": { "message": "Admin Console" @@ -4146,15 +4219,6 @@ "itemName": { "message": "Gjenstandens navn" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organization is deactivated" }, @@ -4178,13 +4242,13 @@ "message": "Nyligst redigert" }, "ownerYou": { - "message": "Owner: You" + "message": "Eier: Du" }, "linked": { "message": "Tilknyttet" }, "copySuccessful": { - "message": "Copy Successful" + "message": "Kopiering lyktes" }, "upload": { "message": "Last opp" @@ -4196,7 +4260,7 @@ "message": "Maksimal filstørrelse er 500 MB" }, "deleteAttachmentName": { - "message": "Delete attachment $NAME$", + "message": "Slett $NAME$-vedlegget", "placeholders": { "name": { "content": "$1", @@ -4272,10 +4336,10 @@ "message": "Autoutfyllings-innstillinger" }, "websiteUri": { - "message": "Website (URI)" + "message": "Nettsted (URİ)" }, "websiteUriCount": { - "message": "Website (URI) $COUNT$", + "message": "Nettsted (URİ) $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": { @@ -4403,7 +4467,7 @@ "message": "Feltetikett" }, "textHelpText": { - "message": "Use text fields for data like security questions" + "message": "Bruk tekstfelter for data som sikkerhetsspørsmål" }, "hiddenHelpText": { "message": "Use hidden fields for sensitive data like a password" @@ -4421,7 +4485,7 @@ "message": "Rediger felt" }, "editFieldLabel": { - "message": "Edit $LABEL$", + "message": "Rediger $LABEL$", "placeholders": { "label": { "content": "$1", @@ -4474,7 +4538,7 @@ } }, "selectCollectionsToAssign": { - "message": "Select collections to assign" + "message": "Velg samlinger å tilordne" }, "personalItemTransferWarningSingular": { "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." @@ -4514,10 +4578,10 @@ "message": "Successfully assigned collections" }, "nothingSelected": { - "message": "You have not selected anything." + "message": "Du har ikke valgt noe." }, "movedItemsToOrg": { - "message": "Selected items moved to $ORGNAME$", + "message": "De valgte gjenstandene ble flyttet til $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -4526,7 +4590,7 @@ } }, "itemsMovedToOrg": { - "message": "Items moved to $ORGNAME$", + "message": "Gjenstandene ble flyttet til $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -4535,7 +4599,7 @@ } }, "itemMovedToOrg": { - "message": "Item moved to $ORGNAME$", + "message": "Gjenstanden ble flyttet til $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -4576,13 +4640,13 @@ "message": "Text Sends" }, "accountActions": { - "message": "Account actions" + "message": "Kontohandlinger" }, "showNumberOfAutofillSuggestions": { "message": "Show number of login autofill suggestions on extension icon" }, "showQuickCopyActions": { - "message": "Show quick copy actions on Vault" + "message": "Vis hurtigkopieringshandlinger i hvelvet" }, "systemDefault": { "message": "Systemforvalg" @@ -4618,7 +4682,7 @@ "message": "Prøv igjen" }, "vaultCustomTimeoutMinimum": { - "message": "Minimum custom timeout is 1 minute." + "message": "Minste egendefinerte tidsavbrudd er 1 minutt." }, "additionalContentAvailable": { "message": "Ytterligere innhold er tilgjengelig" @@ -4639,10 +4703,10 @@ "message": "Ingen gjenstander i papirkurven" }, "noItemsInTrashDesc": { - "message": "Items you delete will appear here and be permanently deleted after 30 days" + "message": "Gjenstander du sletter, vises her og slettes permanent etter 30 dager" }, "trashWarning": { - "message": "Items that have been in trash more than 30 days will automatically be deleted" + "message": "Gjenstander som har ligget i papirkurven i mer enn 30 dager, blir automatisk slettet" }, "restore": { "message": "Gjenopprett" @@ -4657,7 +4721,7 @@ "message": "Biometric unlock is unavailable because PIN or password unlock is required first." }, "biometricsStatusHelptextHardwareUnavailable": { - "message": "Biometric unlock is currently unavailable." + "message": "Biometrisk opplåsing er utilgjengelig for øyeblikket." }, "biometricsStatusHelptextAutoSetupNeeded": { "message": "Biometric unlock is unavailable due to misconfigured system files." @@ -4684,11 +4748,11 @@ "message": "Autentiserer" }, "fillGeneratedPassword": { - "message": "Fill generated password", + "message": "Fyll inn generert passord", "description": "Heading for the password generator within the inline menu" }, "passwordRegenerated": { - "message": "Password regenerated", + "message": "Passord ble generert på nytt", "description": "Notification message for when a password has been regenerated" }, "saveLoginToBitwarden": { @@ -4855,7 +4919,7 @@ "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." }, "remindMeLater": { - "message": "Remind me later" + "message": "Minn meg på det senere" }, "newDeviceVerificationNoticePageOneFormContent": { "message": "Do you have reliable access to your email, $EMAIL$?", @@ -4873,7 +4937,7 @@ "message": "Yes, I can reliably access my email" }, "turnOnTwoStepLogin": { - "message": "Turn on two-step login" + "message": "Slå på 2-trinnsinnlogging" }, "changeAcctEmail": { "message": "Endre kontoens E-postadresse" @@ -4887,10 +4951,19 @@ "extraWide": { "message": "Ekstra bred" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { - "message": "Please update your desktop application" + "message": "Vennligst oppdater skrivebordsprogrammet ditt" }, "updateDesktopAppOrDisableFingerprintDialogMessage": { - "message": "To use biometric unlock, please update your desktop application, or disable fingerprint unlock in the desktop settings." + "message": "For å bruke biometrisk opplåsing, må du oppdatere skrivebordsprogrammet eller skru av fingeravtrykksopplåsing i skrivebordsinnstillingene." } } diff --git a/apps/browser/src/_locales/ne/messages.json b/apps/browser/src/_locales/ne/messages.json index a228cf8ff55..33ba50ddab4 100644 --- a/apps/browser/src/_locales/ne/messages.json +++ b/apps/browser/src/_locales/ne/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Purchase Premium" }, - "premiumPurchaseAlert": { - "message": "You can purchase Premium membership on the bitwarden.com web vault. Do you want to visit the website now?" - }, "premiumPurchaseAlertV2": { "message": "You can purchase Premium from your account settings on the Bitwarden web app." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Username generator" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Use this password" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Website $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "You will be notified once the request is approved" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Login initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Exposed Master Password" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organization is deactivated" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra wide" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/nl/messages.json b/apps/browser/src/_locales/nl/messages.json index d2e323aff4f..915ae7163f6 100644 --- a/apps/browser/src/_locales/nl/messages.json +++ b/apps/browser/src/_locales/nl/messages.json @@ -1005,7 +1005,7 @@ "message": "Vraag om een item toe te voegen als het niet is gevonden is je kluis. Dit geld voor alle ingelogde accounts." }, "showCardsInVaultViewV2": { - "message": "Kaarten altijd als Autofill-suggesties in de kluisweergave weergeven" + "message": "Kaarten altijd als auto-invullen suggesties in de kluisweergave weergeven" }, "showCardsCurrentTab": { "message": "Kaarten weergeven op tabpagina" @@ -1014,7 +1014,7 @@ "message": "Kaartenitems weergeven op de tabpagina voor gemakkelijk automatisch invullen." }, "showIdentitiesInVaultViewV2": { - "message": "Identiteiten altijd als Autofill-suggesties in de kluisweergave weergeven" + "message": "Identiteiten altijd als auto-invullen suggesties in de kluisweergave weergeven" }, "showIdentitiesCurrentTab": { "message": "Identiteiten weergeven op tabpagina" @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Premium aanschaffen" }, - "premiumPurchaseAlert": { - "message": "Je kunt een Premium-abonnement aanschaffen in de webkluis op bitwarden.com. Wil je de website nu bezoeken?" - }, "premiumPurchaseAlertV2": { "message": "Je kunt Premium via je accountinstellingen in de Bitwarden-webapp kopen." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Gebruikersnaamgenerator" }, + "useThisEmail": { + "message": "Dit e-mailadres gebruiken" + }, "useThisPassword": { "message": "Dit wachtwoord gebruiken" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Dit aanpassen in instellingen" }, + "change": { + "message": "Wijzigen" + }, + "changeButtonTitle": { + "message": "Wachtwoord wijzigen - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "Wachtwoorden in gevaar" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ vraagt je om de $COUNT$ wachtwoorden te wijzigen omdat ze een risico vormen.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Je organisatie(s) vragen je de $COUNT$ wachtwoorden te wijzigen omdat ze een risico vormen.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Eén risicovol wachtwoord beoordelen en wijzigen" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "$COUNT$ risicovolle wachtwoorden beoordelen en wijzigen", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Risicovolle wachtwoorden sneller wijzigen" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Werk je instellingen bij voor het snel automatisch invullen van je wachtwoorden en genereren van nieuwe" + }, + "turnOnAutofill": { + "message": "Automatisch invullen inschakelen" + }, + "turnedOnAutofill": { + "message": "Automatisch invullen ingeschakeld" + }, + "dismiss": { + "message": "Sluiten" + }, "websiteItemLabel": { "message": "Website $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "Er is een melding naar je apparaat verzonden." }, + "notificationSentDevicePart1": { + "message": "Ontgrendel Bitwarden op je apparaat of op de" + }, + "notificationSentDeviceAnchor": { + "message": "webapp" + }, + "notificationSentDevicePart2": { + "message": "Zorg ervoor dat de vingerafdrukzin overeenkomt met de onderstaande voor je deze goedkeurt." + }, "aNotificationWasSentToYourDevice": { "message": "Er is een melding naar je apparaat verzonden" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Zorg ervoor dat je kluis is ontgrendeld en de vingerafdrukzin hetzelfde is op het andere apparaat" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "Je krijgt een melding zodra de aanvraag is goedgekeurd" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Inloggen gestart" }, + "logInRequestSent": { + "message": "Verzoek verzonden" + }, "exposedMasterPassword": { "message": "Gelekt hoofdwachtwoord" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Itemnaam" }, - "cannotRemoveViewOnlyCollections": { - "message": "Je kunt verzamelingen niet verwijderen met alleen rechten voor weergeven: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organisatie is gedeactiveerd" }, @@ -4887,10 +4951,19 @@ "extraWide": { "message": "Extra breed" }, + "cannotRemoveViewOnlyCollections": { + "message": "Je kunt verzamelingen niet verwijderen met alleen rechten voor weergeven: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Werk je desktopapplicatie bij" }, "updateDesktopAppOrDisableFingerprintDialogMessage": { - "message": "Als u biometrische gegevens wilt gebruiken, moet je de desktopapplicatie bijwerken of vingerafdrukontgrendeling uitschakelen in de instellingen van de desktopapplicatie." + "message": "Als je biometrische gegevens wilt gebruiken, moet je de desktopapplicatie bijwerken of vingerafdrukontgrendeling uitschakelen in de instellingen van de desktopapplicatie." } } diff --git a/apps/browser/src/_locales/nn/messages.json b/apps/browser/src/_locales/nn/messages.json index a228cf8ff55..33ba50ddab4 100644 --- a/apps/browser/src/_locales/nn/messages.json +++ b/apps/browser/src/_locales/nn/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Purchase Premium" }, - "premiumPurchaseAlert": { - "message": "You can purchase Premium membership on the bitwarden.com web vault. Do you want to visit the website now?" - }, "premiumPurchaseAlertV2": { "message": "You can purchase Premium from your account settings on the Bitwarden web app." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Username generator" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Use this password" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Website $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "You will be notified once the request is approved" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Login initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Exposed Master Password" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organization is deactivated" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra wide" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/or/messages.json b/apps/browser/src/_locales/or/messages.json index a228cf8ff55..33ba50ddab4 100644 --- a/apps/browser/src/_locales/or/messages.json +++ b/apps/browser/src/_locales/or/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Purchase Premium" }, - "premiumPurchaseAlert": { - "message": "You can purchase Premium membership on the bitwarden.com web vault. Do you want to visit the website now?" - }, "premiumPurchaseAlertV2": { "message": "You can purchase Premium from your account settings on the Bitwarden web app." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Username generator" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Use this password" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Website $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "You will be notified once the request is approved" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Login initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Exposed Master Password" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organization is deactivated" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra wide" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/pl/messages.json b/apps/browser/src/_locales/pl/messages.json index 60d454c6d88..044a22d6863 100644 --- a/apps/browser/src/_locales/pl/messages.json +++ b/apps/browser/src/_locales/pl/messages.json @@ -23,7 +23,7 @@ "message": "Nowy użytkownik Bitwarden?" }, "logInWithPasskey": { - "message": "Zaloguj się używając passkey" + "message": "Zaloguj się używając klucza dostępu" }, "useSingleSignOn": { "message": "Użyj jednokrotnego logowania" @@ -120,7 +120,7 @@ "message": "Kopiuj hasło" }, "copyPassphrase": { - "message": "Kopiuj frazę bezpieczeństwa" + "message": "Skopiuj hasło wyrazowe" }, "copyNote": { "message": "Kopiuj notatkę" @@ -147,7 +147,7 @@ "message": "Kopiuj numer PESEL" }, "copyPassportNumber": { - "message": "Kopiuj numer paszportu" + "message": "Skopiuj numer paszportu" }, "copyLicenseNumber": { "message": "Kopiuj numer licencji" @@ -443,19 +443,19 @@ "message": "Wygeneruj hasło" }, "generatePassphrase": { - "message": "Wygenruj frazę zabezpieczającą" + "message": "Wygeneruj hasło wyrazowe" }, "passwordGenerated": { - "message": "Password generated" + "message": "Hasło zostało wygenerowane" }, "passphraseGenerated": { - "message": "Passphrase generated" + "message": "Hasło wyrazowe zostało wygenerowane" }, "usernameGenerated": { - "message": "Username generated" + "message": "Nazwa użytkownika została wygenerowana" }, "emailGenerated": { - "message": "Email generated" + "message": "E-mail został wygenerowany" }, "regeneratePassword": { "message": "Wygeneruj ponownie hasło" @@ -660,10 +660,10 @@ "message": "Zweryfikuj tożsamość" }, "weDontRecognizeThisDevice": { - "message": "We don't recognize this device. Enter the code sent to your email to verify your identity." + "message": "Nie rozpoznajemy tego urządzenia. Wpisz kod wysłany na Twój e-mail, aby zweryfikować tożsamość." }, "continueLoggingIn": { - "message": "Continue logging in" + "message": "Kontynuuj logowanie" }, "yourVaultIsLocked": { "message": "Sejf jest zablokowany. Zweryfikuj swoją tożsamość, aby kontynuować." @@ -806,7 +806,7 @@ "message": "Zalogowałeś się pomyślnie" }, "youMayCloseThisWindow": { - "message": "Możesz zamknąć to okno." + "message": "Możesz zamknąć to okno" }, "masterPassSent": { "message": "Wysłaliśmy Tobie wiadomość e-mail z podpowiedzią do hasła głównego." @@ -1005,7 +1005,7 @@ "message": "Poproś o dodanie elementu, jeśli nie zostanie znaleziony w Twoim sejfie. Dotyczy wszystkich zalogowanych kont." }, "showCardsInVaultViewV2": { - "message": "Always show cards as Autofill suggestions on Vault view" + "message": "Zawsze pokazuj karty jako sugestie autouzupełniania w widoku sejfu" }, "showCardsCurrentTab": { "message": "Pokaż karty na stronie głównej" @@ -1014,7 +1014,7 @@ "message": "Pokaż elementy karty na stronie głównej, aby ułatwić autouzupełnianie." }, "showIdentitiesInVaultViewV2": { - "message": "Always show identities as Autofill suggestions on Vault view" + "message": "Zawsze pokazuj tożsamości jako sugestie autouzupełniania w widoku sejfu" }, "showIdentitiesCurrentTab": { "message": "Pokaż tożsamości na stronie głównej" @@ -1049,10 +1049,10 @@ "message": "Poproś o aktualizację hasła, gdy zmiana zostanie wykryta na stronie. Dotyczy wszystkich zalogowanych kont." }, "enableUsePasskeys": { - "message": "Pytaj o zapisywanie i używanie passkey" + "message": "Pytaj o zapisywanie i używanie kluczy dostępu" }, "usePasskeysDesc": { - "message": "Pytaj o zapisywanie nowych passkey albo danych logowania z passkey w Twoim sejfie. Dotyczy wszystkich zalogowanych kont." + "message": "Pytaj o zapisywanie nowych kluczy dostępu albo danych logowania z kluczy w Twoim sejfie. Dotyczy wszystkich zalogowanych kont." }, "notificationChangeDesc": { "message": "Czy chcesz zaktualizować to hasło w Bitwarden?" @@ -1073,7 +1073,7 @@ "message": "Pokaż opcje menu kontekstowego" }, "contextMenuItemDesc": { - "message": "Użyj drugiego kliknięcia, aby uzyskać dostęp do generowania haseł i pasujących danych logowania do witryny. " + "message": "Użyj drugiego kliknięcia, aby uzyskać dostęp do generowania haseł i pasujących danych logowania do witryny." }, "contextMenuItemDescAlt": { "message": "Użyj drugiego kliknięcia, aby uzyskać dostęp do generowania haseł i pasujących danych logowania do witryny. Dotyczy wszystkich zalogowanych kont." @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Kup konto Premium" }, - "premiumPurchaseAlert": { - "message": "Konto Premium możesz zakupić na stronie sejfu bitwarden.com. Czy chcesz otworzyć tę stronę?" - }, "premiumPurchaseAlertV2": { "message": "Możesz kupić Premium w ustawieniach konta w aplikacji internetowej Bitwarden." }, @@ -1496,7 +1493,7 @@ "message": "Pokazuj karty jako sugestie" }, "showInlineMenuOnIconSelectionLabel": { - "message": "Wyświetlaj sugestie kiedy ikona jest zaznaczona" + "message": "Wyświetlaj sugestie, kiedy ikona jest zaznaczona" }, "showInlineMenuOnFormFieldsDescAlt": { "message": "Dotyczy wszystkich zalogowanych kont." @@ -1541,7 +1538,7 @@ "message": "Domyślne ustawienie autouzupełniania" }, "defaultAutoFillOnPageLoadDesc": { - "message": "Po włączeniu autouzupełnianiu po załadowaniu strony, możesz włączyć lub wyłączyć tę funkcję dla poszczególnych wpisów." + "message": "Po włączeniu autouzupełnianiu po załadowaniu strony możesz włączyć lub wyłączyć tę funkcję dla poszczególnych wpisów." }, "itemAutoFillOnPageLoad": { "message": "Automatycznie uzupełniaj po załadowaniu strony (jeśli włączono w opcjach)" @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Generator nazw użytkownika" }, + "useThisEmail": { + "message": "Użyj tego adresu e-mail" + }, "useThisPassword": { "message": "Użyj tego hasła" }, @@ -2132,7 +2132,7 @@ "message": "URI został zapisany i automatycznie uzupełniony" }, "autoFillSuccess": { - "message": "Element został automatycznie uzupełniony" + "message": "Element został automatycznie uzupełniony " }, "insecurePageWarning": { "message": "Ostrzeżenie: Jest to niezabezpieczona strona HTTP i wszelkie przekazane informacje mogą być potencjalnie widoczne i zmienione przez innych. Ten login został pierwotnie zapisany na stronie bezpiecznej (HTTPS)." @@ -2141,7 +2141,7 @@ "message": "Nadal chcesz uzupełnić ten login?" }, "autofillIframeWarning": { - "message": "Formularz jest hostowany przez inną domenę niż zapisany adres URI dla tego loginu. Wybierz OK, aby i tak automatycznie wypełnić lub anuluj aby zatrzymać." + "message": "Formularz jest hostowany przez inną domenę niż zapisany adres URI dla tego loginu. Wybierz OK, aby i tak automatycznie wypełnić lub anuluj, aby zatrzymać." }, "autofillIframeWarningTip": { "message": "Aby zapobiec temu ostrzeżeniu w przyszłości, zapisz ten URI, $HOSTNAME$, dla tej witryny.", @@ -2285,7 +2285,7 @@ "message": "Klucz biometryczny jest niepoprawny" }, "nativeMessagingWrongUserKeyDesc": { - "message": "Odblokowanie biometryczne nie powiodło się. Sekretny klucz biometryczny nie odblokował sejfu. Spróbuj skonfigurować biometrię ponownie." + "message": "Odblokowanie biometryczne się nie powiodło. Sekretny klucz biometryczny nie odblokował sejfu. Spróbuj skonfigurować biometrię ponownie." }, "biometricsNotEnabledTitle": { "message": "Dane biometryczne są wyłączone" @@ -2355,7 +2355,7 @@ "message": "Aplikacja Bitwarden nie będzie proponować zapisywania danych logowania dla tych domen dla wszystkich zalogowanych kont. Musisz odświeżyć stronę, aby zastosowywać zmiany." }, "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": "Autouzupełnianie i inne powiązane funkcje nie będą oferowane dla tych stron. Aby zmiany zaczęły obowiązywać, musisz odświeżyć stronę." }, "autofillBlockedNoticeV2": { "message": "Autouzupełnianie jest zablokowane dla tej witryny." @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Zmień to w ustawieniach" }, + "change": { + "message": "Zmień" + }, + "changeButtonTitle": { + "message": "Zmień hasło - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "Zagrożone hasła" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ prosi o zmianę $COUNT$ haseł, ponieważ są one zagrożone.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Twoje organizacje proszą o zmianę $COUNT$ haseł, ponieważ są one zagrożone.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Przejrzyj i zmień jedno zagrożone hasło" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Przejrzyj i zmień $COUNT$ zagrożonych haseł ", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Zmień zagrożone hasła szybciej" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Zaktualizuj swoje ustawienia, aby szybko autouzupełniać hasła i generować nowe" + }, + "turnOnAutofill": { + "message": "Włącz autouzupełnienie" + }, + "turnedOnAutofill": { + "message": "Włączono autouzupełnianie" + }, + "dismiss": { + "message": "Odrzuć" + }, "websiteItemLabel": { "message": "Strona internetowa $number$ (URI)", "placeholders": { @@ -2573,7 +2637,7 @@ "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": "Aby utworzyć plik Send, musisz wysunąć rozszerzenie do nowego okna.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendLinuxChromiumFileWarning": { @@ -2829,11 +2893,11 @@ "message": "Bitwarden nie mógł odszyfrować elementów sejfu wymienionych poniżej." }, "contactCSToAvoidDataLossPart1": { - "message": "Contact customer success", + "message": "Skontaktuj się z działem obsługi klienta,", "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": "aby uniknąć dalszej utraty danych.", "description": "This is part of a larger sentence. The full sentence will read 'Contact customer success to avoid additional data loss.'" }, "generateUsername": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "Powiadomienie zostało wysłane na urządzenie." }, + "notificationSentDevicePart1": { + "message": "Odblokuj Bitwarden na swoim urządzeniu lub w" + }, + "notificationSentDeviceAnchor": { + "message": "aplikacji internetowej" + }, + "notificationSentDevicePart2": { + "message": "Upewnij się, że fraza odcisku palca zgadza się z tą poniżej, zanim zatwierdzisz." + }, "aNotificationWasSentToYourDevice": { "message": "Powiadomienie zostało wysłane na twoje urządzenie" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Upewnij się, że Twoje konto jest odblokowane, a unikalny identyfikator konta pasuje do drugiego urządzenia" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "Zostaniesz powiadomiony po zatwierdzeniu prośby" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Logowanie rozpoczęte" }, + "logInRequestSent": { + "message": "Żądanie wysłane" + }, "exposedMasterPassword": { "message": "Ujawnione hasło główne" }, @@ -3169,7 +3242,7 @@ } }, "autofillPageLoadPolicyActivated": { - "message": "Twoja organizacji włączyła autouzupełnianie podczas wczytywania strony." + "message": "Twoja organizacja włączyła autouzupełnianie podczas wczytywania strony." }, "howToAutofill": { "message": "Jak autouzupełniać" @@ -3244,7 +3317,7 @@ "message": "Zapamiętaj to urządzenie" }, "uncheckIfPublicDevice": { - "message": "Odznacz jeśli używasz publicznego urządzenia" + "message": "Odznacz, jeśli używasz publicznego urządzenia" }, "approveFromYourOtherDevice": { "message": "Zatwierdź z innego twojego urządzenia" @@ -3447,7 +3520,7 @@ "message": "Domena aliasu" }, "passwordRepromptDisabledAutofillOnPageLoad": { - "message": "Elementy z pytaniem o hasło głównege nie mogą być automatycznie wypełniane przy wczytywaniu strony. Automatyczne wypełnianie po wczytywania strony zostało wyłączone.", + "message": "Elementy z pytaniem o hasło główne nie mogą być autouzupełniane przy wczytywaniu strony. Autouzupełnianie podczas wczytywania strony zostało wyłączone.", "description": "Toast message for describing that master password re-prompt cannot be autofilled on page load." }, "autofillOnPageLoadSetToDefault": { @@ -3493,7 +3566,7 @@ "description": "Screen reader text (aria-label) for unlock account button in overlay" }, "totpCodeAria": { - "message": "Time-based One-Time Password Verification Code", + "message": "Kod weryfikacyjny jednorazowego hasła oparty na czasie", "description": "Aria label for the totp code displayed in the inline menu for autofill" }, "totpSecondsSpanAria": { @@ -3723,7 +3796,7 @@ "message": "Dane sejfu zostały wyeksportowane" }, "typePasskey": { - "message": "Passkey" + "message": "Klucz dostępu" }, "accessing": { "message": "Uzyskiwanie dostępu" @@ -3732,22 +3805,22 @@ "message": "Zalogowano!" }, "passkeyNotCopied": { - "message": "Passkey nie zostanie skopiowany" + "message": "Klucz dostępu nie zostanie skopiowany" }, "passkeyNotCopiedAlert": { - "message": "Passkey nie zostanie skopiowane do sklonowanego elementu. Czy chcesz kontynuować klonowanie tego elementu?" + "message": "Klucz dostępu nie zostanie skopiowany do sklonowanego elementu. Czy chcesz kontynuować klonowanie tego elementu?" }, "passkeyFeatureIsNotImplementedForAccountsWithoutMasterPassword": { "message": "Weryfikacja jest wymagana przez stronę inicjującą. Ta funkcja nie jest jeszcze zaimplementowana dla kont bez hasła głównego." }, "logInWithPasskeyQuestion": { - "message": "Zaloguj się za pomocą passkey?" + "message": "Zalogować za pomocą klucza dostępu?" }, "passkeyAlreadyExists": { - "message": "Passkey już istnieje dla tej aplikacji." + "message": "Klucz dostępu już istnieje dla tej aplikacji." }, "noPasskeysFoundForThisApplication": { - "message": "Nie znaleziono passkey'a dla tej aplikacji." + "message": "Nie znaleziono klucza dostępu dla tej aplikacji." }, "noMatchingPasskeyLogin": { "message": "Nie masz pasujących danych logowania do tej witryny." @@ -3756,37 +3829,37 @@ "message": "Brak pasujących loginów dla tej witryny" }, "searchSavePasskeyNewLogin": { - "message": "Wyszukaj alb zapisz passkey jako nowy login" + "message": "Wyszukaj albo zapisz klucz dostępu jako nowy login" }, "confirm": { "message": "Potwierdź" }, "savePasskey": { - "message": "Zapisz passkey" + "message": "Zapisz klucz dostępu" }, "savePasskeyNewLogin": { - "message": "Zapisz passkey jako nowe dane logowania" + "message": "Zapisz klucz dostępu jako nowe dane logowania" }, "chooseCipherForPasskeySave": { - "message": "Wybierz dane logowania do których przypisać passkey" + "message": "Wybierz dane logowania, do których przypisać klucz dostępu" }, "chooseCipherForPasskeyAuth": { - "message": "Wybierz passkey żeby się zalogować" + "message": "Wybierz klucz dostępu, żeby się zalogować" }, "passkeyItem": { - "message": "Element Passkey" + "message": "Element klucza dostępu" }, "overwritePasskey": { - "message": "Zastąpić passkey?" + "message": "Zastąpić klucz dostępu?" }, "overwritePasskeyAlert": { - "message": "Ten element zawiera już passkey. Czy na pewno chcesz nadpisać bieżący passkey?" + "message": "Ten element zawiera już klucz dostępu. Czy na pewno chcesz nadpisać bieżący klucza dostępu?" }, "featureNotSupported": { "message": "Funkcja nie jest jeszcze obsługiwana" }, "yourPasskeyIsLocked": { - "message": "Wymagane uwierzytelnienie aby używać passkey. Sprawdź swoją tożsamość, aby kontynuować." + "message": "Wymagane uwierzytelnienie, aby używać klucza dostępu. Sprawdź swoją tożsamość, aby kontynuować." }, "multifactorAuthenticationCancelled": { "message": "Uwierzytelnianie wieloskładnikowe zostało anulowane" @@ -3988,10 +4061,10 @@ "message": "Sukces" }, "removePasskey": { - "message": "Usuń passkey" + "message": "Usuń klucz dostępu" }, "passkeyRemoved": { - "message": "Passkey został usunięty" + "message": "Klucz dostępu został usunięty" }, "autofillSuggestions": { "message": "Sugestie autouzupełniania" @@ -4146,15 +4219,6 @@ "itemName": { "message": "Nazwa elementu" }, - "cannotRemoveViewOnlyCollections": { - "message": "Nie można usunąć kolekcji z uprawnieniami tylko do przeglądania: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organizacja jest wyłączona" }, @@ -4358,7 +4422,7 @@ "message": "Dane" }, "passkeys": { - "message": "Passkeys", + "message": "Klucze dostępu", "description": "A section header for a list of passkeys." }, "passwords": { @@ -4366,7 +4430,7 @@ "description": "A section header for a list of passwords." }, "logInWithPasskeyAriaLabel": { - "message": "Zaloguj się za pomocą passkey", + "message": "Zaloguj się za pomocą klucza dostępu", "description": "ARIA label for the inline menu button that logs in with a passkey." }, "assign": { @@ -4448,7 +4512,7 @@ } }, "reorderToggleButton": { - "message": "Zmień kolejność $LABEL$. Użyj klawiszy że strzałkami aby przenieść element w górę lub w dół.", + "message": "Zmień kolejność $LABEL$. Użyj klawiszy ze strzałkami, aby przenieść element w górę lub w dół.", "placeholders": { "label": { "content": "$1", @@ -4564,16 +4628,16 @@ "message": "Lokalizacja elementu" }, "fileSend": { - "message": "File Send" + "message": "Wysyłka pliku" }, "fileSends": { - "message": "File Sends" + "message": "Wysyłki plików" }, "textSend": { - "message": "Text Send" + "message": "Wysyłka tekstu" }, "textSends": { - "message": "Text Sends" + "message": "Wysyłki tekstów" }, "accountActions": { "message": "Akcje konta" @@ -4704,7 +4768,7 @@ "description": "Represents the ~ key in screen reader content as a readable word" }, "backtickCharacterDescriptor": { - "message": "Backtick", + "message": "Grawis", "description": "Represents the ` key in screen reader content as a readable word" }, "exclamationCharacterDescriptor": { @@ -4728,7 +4792,7 @@ "description": "Represents the % key in screen reader content as a readable word" }, "caretCharacterDescriptor": { - "message": "Caret", + "message": "Daszek", "description": "Represents the ^ key in screen reader content as a readable word" }, "ampersandCharacterDescriptor": { @@ -4784,7 +4848,7 @@ "description": "Represents the | key in screen reader content as a readable word" }, "backSlashCharacterDescriptor": { - "message": "Back slash", + "message": "Ukośnik wsteczny", "description": "Represents the back slash key in screen reader content as a readable word" }, "colonCharacterDescriptor": { @@ -4824,7 +4888,7 @@ "description": "Represents the ? key in screen reader content as a readable word" }, "forwardSlashCharacterDescriptor": { - "message": "Forward slash", + "message": "Ukośnik prawy", "description": "Represents the / key in screen reader content as a readable word" }, "lowercaseAriaLabel": { @@ -4852,7 +4916,7 @@ "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." + "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" @@ -4887,10 +4951,19 @@ "extraWide": { "message": "Bardzo szerokie" }, + "cannotRemoveViewOnlyCollections": { + "message": "Nie można usunąć kolekcji z uprawnieniami tylko do przeglądania: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { - "message": "Please update your desktop application" + "message": "Zaktualizuj aplikację na komputer" }, "updateDesktopAppOrDisableFingerprintDialogMessage": { - "message": "To use biometric unlock, please update your desktop application, or disable fingerprint unlock in the desktop settings." + "message": "Aby używać odblokowywania biometrycznego, zaktualizuj aplikację na komputerze lub wyłącz odblokowywanie odciskiem palca w ustawieniach aplikacji na komputerze." } } diff --git a/apps/browser/src/_locales/pt_BR/messages.json b/apps/browser/src/_locales/pt_BR/messages.json index 050df835041..d0002a7f419 100644 --- a/apps/browser/src/_locales/pt_BR/messages.json +++ b/apps/browser/src/_locales/pt_BR/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Comprar Premium" }, - "premiumPurchaseAlert": { - "message": "Você pode comprar a assinatura premium no cofre web em bitwarden.com. Você deseja visitar o site agora?" - }, "premiumPurchaseAlertV2": { "message": "Você pode comprar Premium nas configurações de sua conta no aplicativo web do Bitwarden." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Gerador de usuário" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Use esta senha" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Site $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "Uma notificação foi enviada para seu dispositivo." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "Uma notificação foi enviada para o seu dispositivo" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Certifique-se que sua conta esteja desbloqueada e que a frase de identificação corresponda à do outro dispositivo" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "Você será notificado assim que a requisição for aprovada" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Login iniciado" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Senha mestra comprometida" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Nome do item" }, - "cannotRemoveViewOnlyCollections": { - "message": "Você não pode remover coleções com permissões de Somente leitura: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "A organização está desativada" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra Grande" }, + "cannotRemoveViewOnlyCollections": { + "message": "Você não pode remover coleções com permissões de Somente leitura: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/pt_PT/messages.json b/apps/browser/src/_locales/pt_PT/messages.json index b12204dd3c9..5e6a8e54701 100644 --- a/apps/browser/src/_locales/pt_PT/messages.json +++ b/apps/browser/src/_locales/pt_PT/messages.json @@ -62,7 +62,7 @@ "message": "Uma dica da palavra-passe mestra pode ajudá-lo a lembrar-se da sua palavra-passe, caso se esqueça dela." }, "masterPassHintText": { - "message": "Se se esquecer da sua palavra-passe, a dica da palavra-passe pode ser enviada para o seu e-mail. Máximo de $CURRENT$/$MAXIMUM$ caracteres.", + "message": "Se se esquecer da sua palavra-passe, a dica da palavra-passe pode ser enviada para o seu e-mail. Máximo de $CURRENT$/$MAXIMUM$ carateres.", "placeholders": { "current": { "content": "$1", @@ -296,7 +296,7 @@ "message": "Continuar para a loja de extensões do navegador?" }, "continueToBrowserExtensionStoreDesc": { - "message": "Ajude outras pessoas a descobrir se o Bitwarden lhes é adequado. Visite a loja de extensões do seu navegador e deixe uma avaliação agora." + "message": "Ajude outras pessoas a descobrir se o Bitwarden lhes é adequado. Visite a loja de extensões do seu navegador e deixe uma classificação agora." }, "changeMasterPasswordOnWebConfirmation": { "message": "Pode alterar a sua palavra-passe mestra na aplicação Web Bitwarden." @@ -340,7 +340,7 @@ "message": "Gestor de Segredos Bitwarden" }, "continueToSecretsManagerPageDesc": { - "message": "Armazene, gira e partilhe segredos de programador de forma segura com o Gestor de Segredos Bitwarden. Saiba mais no site bitwarden.com." + "message": "Armazene, faça a gestão e partilhe de forma segura os segredos dos programadores com o Gestor de Segredos Bitwarden. Saiba mais no site bitwarden.com." }, "passwordlessDotDev": { "message": "Passwordless.dev" @@ -379,7 +379,7 @@ "message": "Nome da pasta" }, "folderHintText": { - "message": "Aninhe uma pasta adicionando o nome da pasta principal seguido de um \"/\". Exemplo: Redes Sociais/Fóruns" + "message": "Crie uma subpasta adicionando o nome da pasta principal seguido de um \"/\". Exemplo: Redes Sociais/Fóruns" }, "noFoldersAdded": { "message": "Nenhuma pasta adicionada" @@ -479,7 +479,7 @@ "description": "deprecated. Use numbersLabel instead." }, "specialCharacters": { - "message": "Caracteres especiais (!@#$%^&*)", + "message": "Carateres especiais (!@#$%^&*)", "description": "deprecated. Use specialCharactersLabel instead." }, "include": { @@ -487,7 +487,7 @@ "description": "Card header for password generator include block" }, "uppercaseDescription": { - "message": "Incluir caracteres em maiúsculas", + "message": "Incluir carateres em maiúsculas", "description": "Tooltip for the password generator uppercase character checkbox" }, "uppercaseLabel": { @@ -495,7 +495,7 @@ "description": "Label for the password generator uppercase character checkbox" }, "lowercaseDescription": { - "message": "Incluir caracteres em minúsculas", + "message": "Incluir carateres em minúsculas", "description": "Full description for the password generator lowercase character checkbox" }, "lowercaseLabel": { @@ -511,7 +511,7 @@ "description": "Label for the password generator numbers checkbox" }, "specialCharactersDescription": { - "message": "Incluir caracteres especiais", + "message": "Incluir carateres especiais", "description": "Full description for the password generator special characters checkbox" }, "specialCharactersLabel": { @@ -535,10 +535,10 @@ "message": "Mínimo de números" }, "minSpecial": { - "message": "Mínimo de caracteres especiais" + "message": "Mínimo de carateres especiais" }, "avoidAmbiguous": { - "message": "Evitar caracteres ambíguos", + "message": "Evitar carateres ambíguos", "description": "Label for the avoid ambiguous characters checkbox." }, "generatorPolicyInEffect": { @@ -651,7 +651,7 @@ "message": "Outras opções" }, "rateExtension": { - "message": "Avaliar a extensão" + "message": "Classificar a extensão" }, "browserNotSupportClipboard": { "message": "O seu navegador Web não suporta a cópia fácil da área de transferência. Em vez disso, copie manualmente." @@ -781,7 +781,7 @@ "message": "É necessário reescrever a palavra-passe mestra." }, "masterPasswordMinlength": { - "message": "A palavra-passe mestra deve ter pelo menos $VALUE$ caracteres.", + "message": "A palavra-passe mestra deve ter pelo menos $VALUE$ carateres.", "description": "The Master Password must be at least a specific number of characters long.", "placeholders": { "value": { @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Adquirir Premium" }, - "premiumPurchaseAlert": { - "message": "Pode adquirir uma subscrição Premium no cofre web em bitwarden.com. Pretende visitar o site agora?" - }, "premiumPurchaseAlertV2": { "message": "Pode adquirir o Premium a partir das definições da sua conta na aplicação Web Bitwarden." }, @@ -1601,7 +1598,7 @@ "message": "Booleano" }, "cfTypeCheckbox": { - "message": "Checkbox" + "message": "Caixa de verificação" }, "cfTypeLinked": { "message": "Associado", @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Gerador de nomes de utilizador" }, + "useThisEmail": { + "message": "Utilizar este e-mail" + }, "useThisPassword": { "message": "Utilizar esta palavra-passe" }, @@ -2186,16 +2186,16 @@ } }, "policyInEffectUppercase": { - "message": "Contém um ou mais caracteres em maiúsculas" + "message": "Contém um ou mais carateres em maiúsculas" }, "policyInEffectLowercase": { - "message": "Contém um ou mais caracteres em minúsculas" + "message": "Contém um ou mais carateres em minúsculas" }, "policyInEffectNumbers": { "message": "Contém um ou mais números" }, "policyInEffectSpecial": { - "message": "Contém um ou mais dos seguintes caracteres especiais $CHARS$", + "message": "Contém um ou mais dos seguintes carateres especiais $CHARS$", "placeholders": { "chars": { "content": "$1", @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Alterar esta opção nas definições" }, + "change": { + "message": "Alterar" + }, + "changeButtonTitle": { + "message": "Alterar palavra-passe - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "Palavras-passe em risco" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "A $ORGANIZATION$ pede-lhe que altere as $COUNT$ palavras-passe por estarem em risco.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "As suas organizações pedem-lhe que altere as $COUNT$ palavras-passe por estarem em risco.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Rever e alterar uma palavra-passe em risco" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Rever e alterar as $COUNT$ palavras-passe em risco", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Alterar mais rapidamente as palavras-passe em risco" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Atualize as suas definições para poder preencher automaticamente as suas palavras-passe e gerar novas palavras-passe" + }, + "turnOnAutofill": { + "message": "Ativar o preenchimento automático" + }, + "turnedOnAutofill": { + "message": "Preenchimento automático ativado" + }, + "dismiss": { + "message": "Dispensar" + }, "websiteItemLabel": { "message": "Site $number$ (URI)", "placeholders": { @@ -2790,7 +2854,7 @@ "message": "Saiu da organização." }, "toggleCharacterCount": { - "message": "Mostrar/ocultar contagem de caracteres" + "message": "Mostrar/ocultar contagem de carateres" }, "sessionTimeout": { "message": "A sua sessão expirou. Por favor, volte atrás e tente iniciar sessão novamente." @@ -2857,7 +2921,7 @@ } }, "passwordLengthRecommendationHint": { - "message": " Utilize $RECOMMENDED$ caracteres ou mais para gerar uma palavra-passe forte.", + "message": " Utilize $RECOMMENDED$ carateres ou mais para gerar uma palavra-passe forte.", "description": "Appended to `spinboxBoundariesHint` to recommend a length to the user. This must include any language-specific 'sentence' separator characters (e.g. a space in english).", "placeholders": { "recommended": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "Foi enviada uma notificação para o seu dispositivo." }, + "notificationSentDevicePart1": { + "message": "Desbloqueie o Bitwarden no seu dispositivo ou no " + }, + "notificationSentDeviceAnchor": { + "message": "aplicação web" + }, + "notificationSentDevicePart2": { + "message": "Certifique-se de que a frase da impressão digital corresponde à frase abaixo indicada antes de a aprovar." + }, "aNotificationWasSentToYourDevice": { "message": "Foi enviada uma notificação para o seu dispositivo" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Certifique-se de que a sua conta está desbloqueada e que a frase de impressão digital corresponde à do outro dispositivo" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "Será notificado quando o pedido for aprovado" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "A preparar o início de sessão" }, + "logInRequestSent": { + "message": "Pedido enviado" + }, "exposedMasterPassword": { "message": "Palavra-passe mestra exposta" }, @@ -3160,7 +3233,7 @@ "message": "A sua palavra-passe mestra não pode ser recuperada se a esquecer!" }, "characterMinimum": { - "message": "$LENGTH$ caracteres no mínimo", + "message": "$LENGTH$ carateres no mínimo", "placeholders": { "length": { "content": "$1", @@ -3208,7 +3281,7 @@ "message": "O atalho de preenchimento automático de credenciais não está definido. Altere-o nas definições do navegador." }, "autofillLoginShortcutText": { - "message": "O atalho de preenchimento automático de credenciais é $COMMAND$. Gira todos os atalhos nas definidções do navegador.", + "message": "O atalho de preenchimento automático de credenciais é $COMMAND$. Organize todos os atalhos nas definições do navegador.", "placeholders": { "command": { "content": "$1", @@ -3337,7 +3410,7 @@ "message": "Procurar" }, "inputMinLength": { - "message": "O campo deve ter pelo menos $COUNT$ caracteres.", + "message": "O campo deve ter pelo menos $COUNT$ carateres.", "placeholders": { "count": { "content": "$1", @@ -3346,7 +3419,7 @@ } }, "inputMaxLength": { - "message": "O campo não pode exceder os $COUNT$ caracteres de comprimento.", + "message": "O campo não pode exceder os $COUNT$ carateres de comprimento.", "placeholders": { "count": { "content": "$1", @@ -3355,7 +3428,7 @@ } }, "inputForbiddenCharacters": { - "message": "Não são permitidos os seguintes caracteres: $CHARACTERS$", + "message": "Não são permitidos os seguintes carateres: $CHARACTERS$", "placeholders": { "characters": { "content": "$1", @@ -3364,7 +3437,7 @@ } }, "inputMinValue": { - "message": "O valor do campo tem de ser, pelo menos, $MIN$ caracteres.", + "message": "O valor do campo tem de ser, pelo menos, $MIN$ carateres.", "placeholders": { "min": { "content": "$1", @@ -3373,7 +3446,7 @@ } }, "inputMaxValue": { - "message": "O valor do campo não pode exceder os $MAX$ caracteres.", + "message": "O valor do campo não pode exceder os $MAX$ carateres.", "placeholders": { "max": { "content": "$1", @@ -4096,7 +4169,7 @@ "message": "Notificações" }, "appearance": { - "message": "Aparência" + "message": "Aspeto" }, "errorAssigningTargetCollection": { "message": "Erro ao atribuir a coleção de destino." @@ -4146,15 +4219,6 @@ "itemName": { "message": "Nome do item" }, - "cannotRemoveViewOnlyCollections": { - "message": "Não é possível remover coleções com permissões de Apenas visualização: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "A organização está desativada" }, @@ -4627,10 +4691,10 @@ "message": "Ficheiro guardado no dispositivo. Gira-o a partir das transferências do seu dispositivo." }, "showCharacterCount": { - "message": "Mostrar contagem de caracteres" + "message": "Mostrar contagem de carateres" }, "hideCharacterCount": { - "message": "Ocultar contagem de caracteres" + "message": "Ocultar contagem de carateres" }, "itemsInTrash": { "message": "Itens no lixo" @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Muito ampla" }, + "cannotRemoveViewOnlyCollections": { + "message": "Não é possível remover coleções com permissões de Apenas visualização: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Por favor, atualize a sua aplicação para computador" }, diff --git a/apps/browser/src/_locales/ro/messages.json b/apps/browser/src/_locales/ro/messages.json index 24826693796..b61afdf9c2c 100644 --- a/apps/browser/src/_locales/ro/messages.json +++ b/apps/browser/src/_locales/ro/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Achiziționare abonament Premium" }, - "premiumPurchaseAlert": { - "message": "Puteți achiziționa un abonament Premium pe website-ul bitwarden.com. Doriți să vizitați site-ul acum?" - }, "premiumPurchaseAlertV2": { "message": "You can purchase Premium from your account settings on the Bitwarden web app." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Username generator" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Use this password" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Website $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "O notificare a fost trimisă pe dispozitivul dvs." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "You will be notified once the request is approved" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Conectare inițiată" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Parolă principală compromisă" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organization is deactivated" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra wide" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/ru/messages.json b/apps/browser/src/_locales/ru/messages.json index b1946be68b9..de00e2ceb25 100644 --- a/apps/browser/src/_locales/ru/messages.json +++ b/apps/browser/src/_locales/ru/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Купить Премиум" }, - "premiumPurchaseAlert": { - "message": "Вы можете купить Премиум на bitwarden.com. Перейти на сайт сейчас?" - }, "premiumPurchaseAlertV2": { "message": "Премиум можно приобрести в настройках аккаунта в веб-версии Bitwarden." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Генератор имени пользователя" }, + "useThisEmail": { + "message": "Использовать этот email" + }, "useThisPassword": { "message": "Использовать этот пароль" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Измените это в настройках" }, + "change": { + "message": "Изменить" + }, + "changeButtonTitle": { + "message": "Изменить пароль - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "Пароли, подверженные риску" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Сайт $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "На ваше устройство отправлено уведомление." }, + "notificationSentDevicePart1": { + "message": "Разблокируйте Bitwarden на своем устройстве или" + }, + "notificationSentDeviceAnchor": { + "message": "веб-приложении" + }, + "notificationSentDevicePart2": { + "message": "Перед одобрением убедитесь, что фраза отпечатка совпадает с приведенной ниже." + }, "aNotificationWasSentToYourDevice": { "message": "На ваше устройство было отправлено уведомление" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Убедитесь, что ваш аккаунт разблокирован и фраза отпечатка совпадает с фразой на другом устройстве" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "Вы получите уведомление, когда запрос будет одобрен" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Вход инициирован" }, + "logInRequestSent": { + "message": "Запрос отправлен" + }, "exposedMasterPassword": { "message": "Мастер-пароль скомпрометирован" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Название элемента" }, - "cannotRemoveViewOnlyCollections": { - "message": "Вы не можете удалить коллекции с правами только на просмотр: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Организация деактивирована" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Очень широкое" }, + "cannotRemoveViewOnlyCollections": { + "message": "Вы не можете удалить коллекции с правами только на просмотр: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Пожалуйста, обновите приложение для компьютера" }, diff --git a/apps/browser/src/_locales/si/messages.json b/apps/browser/src/_locales/si/messages.json index 1d0a40e167c..651f40eb404 100644 --- a/apps/browser/src/_locales/si/messages.json +++ b/apps/browser/src/_locales/si/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "වාරික මිලදී" }, - "premiumPurchaseAlert": { - "message": "ඔබට bitwarden.com වෙබ් සුරක්ෂිතාගාරයේ වාරික සාමාජිකත්වය මිලදී ගත හැකිය. ඔබට දැන් වෙබ් අඩවියට පිවිසීමට අවශ්යද?" - }, "premiumPurchaseAlertV2": { "message": "You can purchase Premium from your account settings on the Bitwarden web app." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Username generator" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Use this password" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Website $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "You will be notified once the request is approved" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Login initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Exposed Master Password" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organization is deactivated" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra wide" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/sk/messages.json b/apps/browser/src/_locales/sk/messages.json index ab6de031efc..e4d221e02a6 100644 --- a/apps/browser/src/_locales/sk/messages.json +++ b/apps/browser/src/_locales/sk/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Zakúpiť Prémiový účet" }, - "premiumPurchaseAlert": { - "message": "Svoje prémiové členstvo si môžete zakúpiť vo webovom trezore bitwarden.com. Chcete navštíviť túto stránku teraz?" - }, "premiumPurchaseAlertV2": { "message": "Prémiové členstvo si môžete zakúpiť v nastaveniach svojho účtu vo webovej aplikácii Bitwarden." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Generátor používateľského mena" }, + "useThisEmail": { + "message": "Použiť tento e-mail" + }, "useThisPassword": { "message": "Použiť toto heslo" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Zmeňte to v nastaveniach" }, + "change": { + "message": "Zmeniť" + }, + "changeButtonTitle": { + "message": "Zmeniť heslo - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "Rizikové heslá" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ vás žiada o zmenu $COUNT$ hesiel, pretože sú ohrozené.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Vaše organizácie vás žiadajú o zmenu $COUNT$ hesiel, pretože sú ohrozené.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Skontrolujte a zmeňte jedno ohrozené heslo" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Skontrolujte a zmeňte $COUNT$ ohrozené heslá", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Zmeňte rizikové heslá rýchlejšie" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Aktualizujte nastavenia, aby ste mohli rýchlo vypĺňať svoje heslá a vygenerovať nové" + }, + "turnOnAutofill": { + "message": "Zapnúť automatické vypĺňanie" + }, + "turnedOnAutofill": { + "message": "Zapnuté automatické vypĺňanie" + }, + "dismiss": { + "message": "Zrušiť" + }, "websiteItemLabel": { "message": "Webstránka $number$ (URI)", "placeholders": { @@ -2902,7 +2966,7 @@ "message": "Služba" }, "forwardedEmail": { - "message": "Alias preposlaného e-mailu" + "message": "Alias presmerovaného e-mailu" }, "forwardedEmailDesc": { "message": "Vytvoriť e-mailový alias pomocou externej služby preposielania." @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "Do vášho zariadenia bolo odoslané upozornenie." }, + "notificationSentDevicePart1": { + "message": "Odomknúť Bitwarden vo svojom zariadení alebo vo" + }, + "notificationSentDeviceAnchor": { + "message": "webovej aplikácii" + }, + "notificationSentDevicePart2": { + "message": "Pred schválením sa uistite, že sa odtlačok prístupovej frázy zhoduje s tou uvedenou nižšie." + }, "aNotificationWasSentToYourDevice": { "message": "Do vášho zariadenia bolo odoslané upozornenie" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Uistite sa, že je váš účet odomknutý a fráza odtlačku prsta sa zhoduje s frázou na druhom zariadení" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "Po schválení žiadosti budete informovaní" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Iniciované prihlásenie" }, + "logInRequestSent": { + "message": "Požiadavka bola odoslaná" + }, "exposedMasterPassword": { "message": "Odhalené hlavné heslo" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Názov položky" }, - "cannotRemoveViewOnlyCollections": { - "message": "Zbierky, ktoré môžete len zobraziť nemôžete odstrániť: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organizácia je vypnutá" }, @@ -4858,7 +4922,7 @@ "message": "Pripomenúť neskôr" }, "newDeviceVerificationNoticePageOneFormContent": { - "message": "Máte spoľahlivý prístup k svojmu e-mailu, $EMAIL$?", + "message": "Máte zaručený prístup k e-mailu $EMAIL$?", "placeholders": { "email": { "content": "$1", @@ -4870,7 +4934,7 @@ "message": "Nie, nemám" }, "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Áno, mám spoľahlivý prístup k svojmu e-mailu" + "message": "Áno, mám zaručený prístup k e-mailu" }, "turnOnTwoStepLogin": { "message": "Zapnúť dvojstupňové prihlásenie" @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra široké" }, + "cannotRemoveViewOnlyCollections": { + "message": "Zbierky, ktoré môžete len zobraziť nemôžete odstrániť: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Aktualizujte desktopovú aplikáciu" }, diff --git a/apps/browser/src/_locales/sl/messages.json b/apps/browser/src/_locales/sl/messages.json index af594791920..757ea673a9a 100644 --- a/apps/browser/src/_locales/sl/messages.json +++ b/apps/browser/src/_locales/sl/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Kupite premium članstvo" }, - "premiumPurchaseAlert": { - "message": "Premium članstvo lahko kupite na spletnem trezoju bitwarden.com. Želite obiskati spletno stran zdaj?" - }, "premiumPurchaseAlertV2": { "message": "You can purchase Premium from your account settings on the Bitwarden web app." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Username generator" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Use this password" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Website $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "You will be notified once the request is approved" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Login initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Exposed Master Password" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organization is deactivated" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra wide" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/sr/messages.json b/apps/browser/src/_locales/sr/messages.json index 811800511c0..f694f8f3bde 100644 --- a/apps/browser/src/_locales/sr/messages.json +++ b/apps/browser/src/_locales/sr/messages.json @@ -159,7 +159,7 @@ "message": "Копирај јавни кључ" }, "copyFingerprint": { - "message": "Копирати отисак" + "message": "Копирај отисак прста" }, "copyCustomField": { "message": "Копирати $FIELD$", @@ -446,16 +446,16 @@ "message": "Генеришите приступну фразу" }, "passwordGenerated": { - "message": "Password generated" + "message": "Лозинка генерисана" }, "passphraseGenerated": { - "message": "Passphrase generated" + "message": "Приступна фраза је генерисана" }, "usernameGenerated": { - "message": "Username generated" + "message": "Корисничко име генерисано" }, "emailGenerated": { - "message": "Email generated" + "message": "Имејл генерисан" }, "regeneratePassword": { "message": "Поново генериши лозинку" @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Купити премијум" }, - "premiumPurchaseAlert": { - "message": "Можете купити премијум претплату на bitwarden.com. Да ли желите да посетите веб сајт сада?" - }, "premiumPurchaseAlertV2": { "message": "Можете да купите Премиум у подешавањима налога у веб апликацији Bitwarden." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Генератор корисничког имена" }, + "useThisEmail": { + "message": "Користи ову епошту" + }, "useThisPassword": { "message": "Употреби ову лозинку" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Промените ово у подешавањима" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Сајт $number$ (УРЛ)", "placeholders": { @@ -2829,11 +2893,11 @@ "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": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "Обавештење је послато на ваш уређај." }, + "notificationSentDevicePart1": { + "message": "Откључај Bitwarden на твом уређају или на" + }, + "notificationSentDeviceAnchor": { + "message": "веб апликација" + }, + "notificationSentDevicePart2": { + "message": "Потврдите да се фраза отиска прста поклапа са овом испод пре одобравања." + }, "aNotificationWasSentToYourDevice": { "message": "Обавештење је послато на ваш уређај" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Уверите се да је ваш налог откључан и да се фраза отиска подудара на другом уређају" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "Бићете обавештени када захтев буде одобрен" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Пријава је покренута" }, + "logInRequestSent": { + "message": "Захтев је послат" + }, "exposedMasterPassword": { "message": "Изложена главна лозинка" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Име ставке" }, - "cannotRemoveViewOnlyCollections": { - "message": "Не можете уклонити колекције са дозволама само за приказ: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Организација је деактивирана" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Врло широко" }, + "cannotRemoveViewOnlyCollections": { + "message": "Не можете уклонити колекције са дозволама само за приказ: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Молим вас надоградите вашу апликацију на рачунару" }, diff --git a/apps/browser/src/_locales/sv/messages.json b/apps/browser/src/_locales/sv/messages.json index fb377af7679..de10dbabbe8 100644 --- a/apps/browser/src/_locales/sv/messages.json +++ b/apps/browser/src/_locales/sv/messages.json @@ -14,7 +14,7 @@ "message": "Logga in eller skapa ett nytt konto för att komma åt ditt säkra valv." }, "inviteAccepted": { - "message": "Invitation accepted" + "message": "Inbjudan accepterades" }, "createAccount": { "message": "Skapa konto" @@ -35,7 +35,7 @@ "message": "Ställ in ett starkt lösenord" }, "finishCreatingYourAccountBySettingAPassword": { - "message": "Finish creating your account by setting a password" + "message": "Slutför skapandet av ditt konto genom att ange ett lösenord" }, "enterpriseSingleSignOn": { "message": "Single Sign-On för företag" @@ -81,10 +81,10 @@ "message": "Huvudlösenordsledtråd (valfri)" }, "joinOrganization": { - "message": "Join organization" + "message": "Gå med i organisation" }, "joinOrganizationName": { - "message": "Join $ORGANIZATIONNAME$", + "message": "Gå med i $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -193,7 +193,7 @@ "message": "Autofyll identitet" }, "fillVerificationCode": { - "message": "Fill verification code" + "message": "Fyll i verifieringskod" }, "fillVerificationCodeAria": { "message": "Fill Verification Code", @@ -239,7 +239,7 @@ "message": "Lägg till objekt" }, "accountEmail": { - "message": "Account email" + "message": "Kontots e-post" }, "requestHint": { "message": "Begär ledtråd" @@ -446,16 +446,16 @@ "message": "Generera lösenfras" }, "passwordGenerated": { - "message": "Password generated" + "message": "Lösenord genererades" }, "passphraseGenerated": { - "message": "Passphrase generated" + "message": "Lösenordsfras genererades" }, "usernameGenerated": { - "message": "Username generated" + "message": "Användarnamn genererades" }, "emailGenerated": { - "message": "Email generated" + "message": "E-post genererades" }, "regeneratePassword": { "message": "Återskapa lösenord" @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Köp Premium" }, - "premiumPurchaseAlert": { - "message": "Du kan köpa premium-medlemskap i Bitwardens webbvalv. Vill du besöka webbplatsen nu?" - }, "premiumPurchaseAlertV2": { "message": "You can purchase Premium from your account settings on the Bitwarden web app." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Username generator" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Use this password" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Webbplats $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "En avisering har skickats till din enhet." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "You will be notified once the request is approved" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Inloggning påbörjad" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Huvudlösenordet har exponerats" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Objektnamn" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organization is deactivated" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra wide" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/te/messages.json b/apps/browser/src/_locales/te/messages.json index a228cf8ff55..33ba50ddab4 100644 --- a/apps/browser/src/_locales/te/messages.json +++ b/apps/browser/src/_locales/te/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Purchase Premium" }, - "premiumPurchaseAlert": { - "message": "You can purchase Premium membership on the bitwarden.com web vault. Do you want to visit the website now?" - }, "premiumPurchaseAlertV2": { "message": "You can purchase Premium from your account settings on the Bitwarden web app." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Username generator" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Use this password" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Website $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "You will be notified once the request is approved" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Login initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Exposed Master Password" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organization is deactivated" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra wide" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/th/messages.json b/apps/browser/src/_locales/th/messages.json index d97d992674c..9cb50903730 100644 --- a/apps/browser/src/_locales/th/messages.json +++ b/apps/browser/src/_locales/th/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Purchase Premium" }, - "premiumPurchaseAlert": { - "message": "You can purchase Premium membership on the bitwarden.com web vault. Do you want to visit the website now?" - }, "premiumPurchaseAlertV2": { "message": "You can purchase Premium from your account settings on the Bitwarden web app." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Username generator" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Use this password" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Website $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "You will be notified once the request is approved" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Login initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Exposed Master Password" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Organization is deactivated" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra wide" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/tr/messages.json b/apps/browser/src/_locales/tr/messages.json index bc16c627b5b..82485207575 100644 --- a/apps/browser/src/_locales/tr/messages.json +++ b/apps/browser/src/_locales/tr/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Premium satın al" }, - "premiumPurchaseAlert": { - "message": "Premium üyeliği bitwarden.com web kasası üzerinden satın alabilirsiniz. Şimdi siteye gitmek ister misiniz?" - }, "premiumPurchaseAlertV2": { "message": "Bitwarden web uygulamasındaki hesap ayarlarınızdan Premium abonelik satın alabilirsiniz." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Kullanıcı adı üreteci" }, + "useThisEmail": { + "message": "Bu e-postayı kullan" + }, "useThisPassword": { "message": "Bu parolayı kullan" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Bunu ayarlardan değiştirebilirsiniz" }, + "change": { + "message": "Değiştir" + }, + "changeButtonTitle": { + "message": "Parolayı değiştir - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "Riskli parolalar" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Otomatik doldurmayı etkinleştir" + }, + "turnedOnAutofill": { + "message": "Otomatik doldurma etkinleştirildi" + }, + "dismiss": { + "message": "Kapat" + }, "websiteItemLabel": { "message": "Web sitesi $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "Cihazınıza bir bildirim gönderildi." }, + "notificationSentDevicePart1": { + "message": "Bitwarden kilidini cihazınızdan veya" + }, + "notificationSentDeviceAnchor": { + "message": "web uygulamasından açın" + }, + "notificationSentDevicePart2": { + "message": "Onay vermeden önce parmak izi ifadesinin aşağıdakiyle eşleştiğini kontrol edin." + }, "aNotificationWasSentToYourDevice": { "message": "Cihazınıza bir bildirim gönderildi" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Lütfen hesabınızın kilidinin açık olduğundan ve parmak izi ifadesinin diğer cihazla eşleştiğinden emin olun" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "İsteğiniz onaylanınca size haber vereceğiz" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Giriş başlatıldı" }, + "logInRequestSent": { + "message": "İstek gönderildi" + }, "exposedMasterPassword": { "message": "Açığa Çıkmış Ana Parola" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Kayıt adı" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Kuruluş pasifleştirilmiş" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Ekstra geniş" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Lütfen masaüstü uygulamanızı güncelleyin" }, diff --git a/apps/browser/src/_locales/uk/messages.json b/apps/browser/src/_locales/uk/messages.json index f14c252e52d..b81c32ac569 100644 --- a/apps/browser/src/_locales/uk/messages.json +++ b/apps/browser/src/_locales/uk/messages.json @@ -446,16 +446,16 @@ "message": "Генерувати парольну фразу" }, "passwordGenerated": { - "message": "Password generated" + "message": "Пароль згенеровано" }, "passphraseGenerated": { - "message": "Passphrase generated" + "message": "Парольну фразу згенеровано" }, "usernameGenerated": { - "message": "Username generated" + "message": "Ім'я користувача згенеровано" }, "emailGenerated": { - "message": "Email generated" + "message": "Адресу е-пошти згенеровано" }, "regeneratePassword": { "message": "Генерувати новий" @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Придбати преміум" }, - "premiumPurchaseAlert": { - "message": "Ви можете передплатити преміум у сховищі на bitwarden.com. Хочете перейти на вебсайт зараз?" - }, "premiumPurchaseAlertV2": { "message": "Ви можете придбати Преміум у налаштуваннях облікового запису вебпрограмі Bitwarden." }, @@ -1621,10 +1618,10 @@ "message": "Показувати піктограми вебсайтів" }, "faviconDesc": { - "message": "Показувати впізнаване зображення біля кожного запису." + "message": "Показувати зображення біля кожного запису." }, "faviconDescAlt": { - "message": "Показати впізнаване зображення поруч з кожним записом. Застосовується для всіх облікових записів, до яких виконано вхід." + "message": "Показувати зображення поруч з кожним записом. Застосовується для всіх облікових записів, до яких виконано вхід." }, "enableBadgeCounter": { "message": "Показувати лічильник" @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Генератор імені користувача" }, + "useThisEmail": { + "message": "Використати цю е-пошту" + }, "useThisPassword": { "message": "Використати цей пароль" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Змінити в налаштуваннях" }, + "change": { + "message": "Змінити" + }, + "changeButtonTitle": { + "message": "Змінити пароль – $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "Ризиковані паролі" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ вимагає зміни $COUNT$ паролів, оскільки вони ризиковані.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Ваші організації вимагають зміни $COUNT$ паролів, оскільки вони ризиковані.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Перегляньте і змініть один ризикований пароль" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Перегляньте і змініть $COUNT$ ризикованих паролів", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Швидше змінюйте ризиковані паролі" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Оновіть налаштування, щоб швидше автоматично заповнювати й створювати паролі" + }, + "turnOnAutofill": { + "message": "Увімкніть автозаповнення" + }, + "turnedOnAutofill": { + "message": "Автозаповнення увімкнено" + }, + "dismiss": { + "message": "Відхилити" + }, "websiteItemLabel": { "message": "Вебсайт $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "Сповіщення було надіслано на ваш пристрій." }, + "notificationSentDevicePart1": { + "message": "Розблокуйте Bitwarden на своєму пристрої або у" + }, + "notificationSentDeviceAnchor": { + "message": "вебпрограмі" + }, + "notificationSentDevicePart2": { + "message": "Перш ніж підтверджувати, обов'язково перевірте відповідність зазначеної нижче фрази відбитка." + }, "aNotificationWasSentToYourDevice": { "message": "Сповіщення надіслано на ваш пристрій" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Переконайтеся, що ваш обліковий запис розблоковано і фраза відбитка на іншому пристрої збігається" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "Після схвалення запиту ви отримаєте сповіщення" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Ініційовано вхід" }, + "logInRequestSent": { + "message": "Запит надіслано" + }, "exposedMasterPassword": { "message": "Головний пароль викрито" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Назва запису" }, - "cannotRemoveViewOnlyCollections": { - "message": "Ви не можете вилучати збірки, маючи дозвіл лише на перегляд: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Організацію деактивовано" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Дуже широке" }, + "cannotRemoveViewOnlyCollections": { + "message": "Ви не можете вилучати збірки, маючи дозвіл лише на перегляд: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Оновіть свою комп'ютерну програму" }, diff --git a/apps/browser/src/_locales/vi/messages.json b/apps/browser/src/_locales/vi/messages.json index 78173858e82..92a37d53bd9 100644 --- a/apps/browser/src/_locales/vi/messages.json +++ b/apps/browser/src/_locales/vi/messages.json @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "Mua bản Cao Cấp" }, - "premiumPurchaseAlert": { - "message": "Bạn có thể nâng cấp làm thành viên cao cấp trong kho bitwarden nền web. Bạn có muốn truy cập trang web bây giờ?" - }, "premiumPurchaseAlertV2": { "message": "Bạn có thể mua gói Premium từ cài đặt tài khoản trên trang Bitwarden." }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "Bộ tạo tên người dùng" }, + "useThisEmail": { + "message": "Use this email" + }, "useThisPassword": { "message": "Use this password" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "Change this in settings" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "Trang Web $number$ (URI)", "placeholders": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "Một thông báo đã được gửi đến thiết bị của bạn." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "You will be notified once the request is approved" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "Bắt đầu đăng nhập" }, + "logInRequestSent": { + "message": "Request sent" + }, "exposedMasterPassword": { "message": "Mật khẩu chính bị lộ" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "Tên mục" }, - "cannotRemoveViewOnlyCollections": { - "message": "Bạn không thể xóa các bộ sưu tập với quyền chỉ xem: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "Tổ chức không còn hoạt động" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "Extra wide" }, + "cannotRemoveViewOnlyCollections": { + "message": "Bạn không thể xóa các bộ sưu tập với quyền chỉ xem: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "Please update your desktop application" }, diff --git a/apps/browser/src/_locales/zh_CN/messages.json b/apps/browser/src/_locales/zh_CN/messages.json index ac43df7a5a4..9de6683a609 100644 --- a/apps/browser/src/_locales/zh_CN/messages.json +++ b/apps/browser/src/_locales/zh_CN/messages.json @@ -56,7 +56,7 @@ "message": "主密码" }, "masterPassDesc": { - "message": "主密码是您访问密码库的唯一密码。它非常重要,请您不要忘记。一旦忘记,无任何办法恢复此密码。" + "message": "主密码是用于访问您的密码库的密码。不要忘记您的主密码,这一点非常重要。一旦忘记,无任何办法恢复此密码。" }, "masterPassHintDesc": { "message": "主密码提示可以在您忘记密码时帮您回忆起来。" @@ -379,7 +379,7 @@ "message": "文件夹名称" }, "folderHintText": { - "message": "通过在父文件夹名后面跟随「/」来嵌套文件夹。示例:Social/Forums" + "message": "通过在父文件夹名后面添加「/」来嵌套文件夹。示例:Social/Forums" }, "noFoldersAdded": { "message": "未添加文件夹" @@ -591,7 +591,7 @@ "message": "私密备注" }, "note": { - "message": "备注" + "message": "笔记" }, "editItem": { "message": "编辑项目" @@ -766,7 +766,7 @@ "message": "主密码提示" }, "errorOccurred": { - "message": "发生了一个错误" + "message": "发生错误" }, "emailRequired": { "message": "必须填写电子邮箱地址。" @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "购买高级版" }, - "premiumPurchaseAlert": { - "message": "您可以在 bitwarden.com 网页版密码库购买高级会员。现在要访问吗?" - }, "premiumPurchaseAlertV2": { "message": "您可以在 Bitwarden 网页 App 的账户设置中购买高级版。" }, @@ -1874,7 +1871,7 @@ "message": "检查密码是否已经被公开。" }, "passwordExposed": { - "message": "此密码在泄露数据中已被公开 $VALUE$ 次。请立即修改。", + "message": "此密码在数据泄露中已被暴露 $VALUE$ 次。请立即修改。", "placeholders": { "value": { "content": "$1", @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "用户名生成器" }, + "useThisEmail": { + "message": "使用此电子邮箱" + }, "useThisPassword": { "message": "使用此密码" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "在设置中更改它" }, + "change": { + "message": "更改" + }, + "changeButtonTitle": { + "message": "更改密码 - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "有风险的密码" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ 要求您更改 $COUNT$ 个密码,因为它们存在风险。", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "您的组织要求您更改 $COUNT$ 个密码,因为它们存在风险。", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "审查并更改某个有风险的密码" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "审查并更改 $COUNT$ 个有风险的密码", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "尽快更改有风险的密码" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "更新您的设置,以便您可以快速自动填充密码并生成新的密码" + }, + "turnOnAutofill": { + "message": "打开自动填充" + }, + "turnedOnAutofill": { + "message": "已打开自动填充" + }, + "dismiss": { + "message": "忽略" + }, "websiteItemLabel": { "message": "网站 $number$ (URI)", "placeholders": { @@ -2506,7 +2570,7 @@ "message": "自定义" }, "sendPasswordDescV3": { - "message": "添加一个用于收件人访问此 Send 的可选密码。", + "message": "添加一个用于接收者访问此 Send 的可选密码。", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "createSend": { @@ -2664,7 +2728,7 @@ "description": "Used as a card title description on the set password page to explain why the user is there" }, "cardMetrics": { - "message": "$TOTAL$ 不足", + "message": "总计 $TOTAL$", "placeholders": { "total": { "content": "$1", @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "通知已发送到您的设备。" }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "网页 App" + }, + "notificationSentDevicePart2": { + "message": "在批准前,请确保指纹短语与下面的相匹配。" + }, "aNotificationWasSentToYourDevice": { "message": "通知已发送到您的设备" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "确保您的账户已解锁,并且指纹短语与其他设备上的相匹配。" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "请求获得批准后,您将收到通知" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "登录已发起" }, + "logInRequestSent": { + "message": "请求已发送" + }, "exposedMasterPassword": { "message": "已暴露的主密码" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "项目名称" }, - "cannotRemoveViewOnlyCollections": { - "message": "您无法删除仅具有「查看」权限的集合:$COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "组织已停用" }, @@ -4226,7 +4290,7 @@ "message": "筛选" }, "filterVault": { - "message": "密码库筛选" + "message": "筛选密码库" }, "filterApplied": { "message": "已应用一个筛选" @@ -4887,6 +4951,15 @@ "extraWide": { "message": "超宽" }, + "cannotRemoveViewOnlyCollections": { + "message": "您无法删除仅具有「查看」权限的集合:$COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "请更新您的桌面应用程序" }, diff --git a/apps/browser/src/_locales/zh_TW/messages.json b/apps/browser/src/_locales/zh_TW/messages.json index c76929cd5c4..274da967618 100644 --- a/apps/browser/src/_locales/zh_TW/messages.json +++ b/apps/browser/src/_locales/zh_TW/messages.json @@ -35,7 +35,7 @@ "message": "設定一個強密碼" }, "finishCreatingYourAccountBySettingAPassword": { - "message": "設定密碼以完成創建您的帳戶。" + "message": "設定密碼以完成建立您的帳號" }, "enterpriseSingleSignOn": { "message": "企業單一登入" @@ -446,7 +446,7 @@ "message": "產生密碼短語" }, "passwordGenerated": { - "message": "Password generated" + "message": "已產生密碼" }, "passphraseGenerated": { "message": "Passphrase generated" @@ -660,10 +660,10 @@ "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": "您的密碼庫已鎖定。請驗證身分以繼續。" @@ -763,7 +763,7 @@ "message": "若您忘記主密碼,將會無法找回!" }, "masterPassHintLabel": { - "message": "您已成功創建新帳戶!" + "message": "主密碼提示" }, "errorOccurred": { "message": "發生錯誤" @@ -797,7 +797,7 @@ "message": "帳戶已建立!現在可以登入了。" }, "newAccountCreated2": { - "message": "您已成功創建新帳戶!" + "message": "您已成功建立新帳號!" }, "youHaveBeenLoggedIn": { "message": "你已經登入!" @@ -1005,7 +1005,7 @@ "message": "如果在您的密碼庫中找不到項目,則詢問是否新增項目。適用於所有已登入的帳戶。" }, "showCardsInVaultViewV2": { - "message": "Always show cards as Autofill suggestions on Vault view" + "message": "一律在密碼庫介面中顯示支付卡自動填入建議" }, "showCardsCurrentTab": { "message": "於分頁頁面顯示支付卡" @@ -1014,7 +1014,7 @@ "message": "於分頁頁面顯示信用卡以便於自動填入。" }, "showIdentitiesInVaultViewV2": { - "message": "Always show identities as Autofill suggestions on Vault view" + "message": "一律在密碼庫介面中顯示身分自動填入建議" }, "showIdentitiesCurrentTab": { "message": "於分頁頁面顯示身分" @@ -1280,9 +1280,6 @@ "premiumPurchase": { "message": "升級為進階會員" }, - "premiumPurchaseAlert": { - "message": "您可以在 bitwarden.com 網頁版密碼庫購買進階會員資格。現在要前往嗎?" - }, "premiumPurchaseAlertV2": { "message": "您可以在 Bitwarden 網頁 App 的帳號設定中購買進階版。" }, @@ -2064,6 +2061,9 @@ "usernameGenerator": { "message": "使用者名稱產生器" }, + "useThisEmail": { + "message": "使用此電子郵件" + }, "useThisPassword": { "message": "使用此密碼" }, @@ -2363,6 +2363,70 @@ "autofillBlockedNoticeGuidance": { "message": "您可以於設定中進行更改" }, + "change": { + "message": "Change" + }, + "changeButtonTitle": { + "message": "Change password - $ITEMNAME$", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "atRiskPasswords": { + "message": "At-risk passwords" + }, + "atRiskPasswordsDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + }, + "count": { + "content": "$2", + "example": "2" + } + } + }, + "atRiskPasswordsDescMultiOrg": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "reviewAndChangeAtRiskPassword": { + "message": "Review and change one at-risk password" + }, + "reviewAndChangeAtRiskPasswordsPlural": { + "message": "Review and change $COUNT$ at-risk passwords", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, + "changeAtRiskPasswordsFaster": { + "message": "Change at-risk passwords faster" + }, + "changeAtRiskPasswordsFasterDesc": { + "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + }, + "turnOnAutofill": { + "message": "Turn on autofill" + }, + "turnedOnAutofill": { + "message": "Turned on autofill" + }, + "dismiss": { + "message": "Dismiss" + }, "websiteItemLabel": { "message": "網站 $number$ (URI)", "placeholders": { @@ -2529,7 +2593,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "createdSendSuccessfully": { - "message": "Send 創建成功!", + "message": "Send 建立成功!", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendExpiresInHoursSingle": { @@ -3123,12 +3187,18 @@ "notificationSentDevice": { "message": "已傳送通知至您的裝置。" }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the" + }, + "notificationSentDeviceAnchor": { + "message": "網頁應用程式" + }, + "notificationSentDevicePart2": { + "message": "在核准前請確保您的指紋短語與下面完全相符。" + }, "aNotificationWasSentToYourDevice": { "message": "已傳送通知至您的裝置" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "請確保您的帳號已解鎖,並且指紋短語與其他裝置一致。" - }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "一旦您的請求被通過,您會獲得通知。" }, @@ -3138,6 +3208,9 @@ "loginInitiated": { "message": "登入已啟動" }, + "logInRequestSent": { + "message": "已傳送請求" + }, "exposedMasterPassword": { "message": "已洩露的主密碼" }, @@ -4146,15 +4219,6 @@ "itemName": { "message": "項目名稱" }, - "cannotRemoveViewOnlyCollections": { - "message": "若您只有檢視權限,無法移除集合 $COLLECTIONS$。", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "organizationIsDeactivated": { "message": "組織已被停用" }, @@ -4887,6 +4951,15 @@ "extraWide": { "message": "更寬" }, + "cannotRemoveViewOnlyCollections": { + "message": "若您只有檢視權限,無法移除集合 $COLLECTIONS$。", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "updateDesktopAppOrDisableFingerprintDialogTitle": { "message": "請更新您的桌面應用程式" }, diff --git a/apps/browser/src/auth/popup/login-via-auth-request-v1.component.html b/apps/browser/src/auth/popup/login-via-auth-request-v1.component.html index e7fafbb252c..34c0cbe9614 100644 --- a/apps/browser/src/auth/popup/login-via-auth-request-v1.component.html +++ b/apps/browser/src/auth/popup/login-via-auth-request-v1.component.html @@ -7,13 +7,20 @@
-

{{ "loginInitiated" | i18n }}

+

{{ "logInRequestSent" | i18n }}

-

{{ "notificationSentDevice" | i18n }}

-

- {{ "fingerprintMatchInfo" | i18n }} + {{ "notificationSentDevicePart1" | i18n }} + {{ "notificationSentDeviceAnchor" | i18n }}. {{ "notificationSentDevicePart2" | i18n }}

diff --git a/apps/browser/src/auth/popup/register.component.html b/apps/browser/src/auth/popup/register.component.html deleted file mode 100644 index e2f4f2e7d12..00000000000 --- a/apps/browser/src/auth/popup/register.component.html +++ /dev/null @@ -1,147 +0,0 @@ -
-
-
- -
-

- {{ "createAccount" | i18n }} -

-
- -
-
-
-
-
-
- - -
-
-
-
- - -
-
- -
-
- - -
-
- -
-
-
-
-
- - -
-
- -
-
-
- - -
-
- -
-
- - -
-
-
-
- -
-
-
-
- - -
-
-
-
-
diff --git a/apps/browser/src/auth/popup/register.component.ts b/apps/browser/src/auth/popup/register.component.ts deleted file mode 100644 index 50475b2204d..00000000000 --- a/apps/browser/src/auth/popup/register.component.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 { Component } from "@angular/core"; -import { UntypedFormBuilder } from "@angular/forms"; -import { Router } from "@angular/router"; - -import { RegisterComponent as BaseRegisterComponent } from "@bitwarden/angular/auth/components/register.component"; -import { FormValidationErrorsService } from "@bitwarden/angular/platform/abstractions/form-validation-errors.service"; -import { LoginStrategyServiceAbstraction } from "@bitwarden/auth/common"; -import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { AuditService } from "@bitwarden/common/abstractions/audit.service"; -import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { DialogService, ToastService } from "@bitwarden/components"; -import { KeyService } from "@bitwarden/key-management"; - -@Component({ - selector: "app-register", - templateUrl: "register.component.html", -}) -export class RegisterComponent extends BaseRegisterComponent { - color: string; - text: string; - - constructor( - formValidationErrorService: FormValidationErrorsService, - formBuilder: UntypedFormBuilder, - loginStrategyService: LoginStrategyServiceAbstraction, - router: Router, - i18nService: I18nService, - keyService: KeyService, - apiService: ApiService, - platformUtilsService: PlatformUtilsService, - environmentService: EnvironmentService, - logService: LogService, - auditService: AuditService, - dialogService: DialogService, - toastService: ToastService, - ) { - super( - formValidationErrorService, - formBuilder, - loginStrategyService, - router, - i18nService, - keyService, - apiService, - platformUtilsService, - environmentService, - logService, - auditService, - dialogService, - toastService, - ); - } -} diff --git a/apps/browser/src/autofill/background/notification.background.spec.ts b/apps/browser/src/autofill/background/notification.background.spec.ts index 37c05a55a3a..40c4d07cadf 100644 --- a/apps/browser/src/autofill/background/notification.background.spec.ts +++ b/apps/browser/src/autofill/background/notification.background.spec.ts @@ -825,6 +825,7 @@ describe("NotificationBackground", () => { queueMessage.newPassword, message.edit, sender.tab, + "testId", ); expect(updateWithServerSpy).toHaveBeenCalled(); expect(tabSendMessageSpy).toHaveBeenCalledWith(sender.tab, { @@ -862,6 +863,7 @@ describe("NotificationBackground", () => { queueMessage.password, message.edit, sender.tab, + "testId", ); expect(editItemSpy).not.toHaveBeenCalled(); expect(createWithServerSpy).not.toHaveBeenCalled(); @@ -895,6 +897,7 @@ describe("NotificationBackground", () => { queueMessage.newPassword, message.edit, sender.tab, + "testId", ); expect(editItemSpy).toHaveBeenCalled(); expect(updateWithServerSpy).not.toHaveBeenCalled(); @@ -904,10 +907,13 @@ describe("NotificationBackground", () => { expect(tabSendMessageSpy).toHaveBeenCalledWith(sender.tab, { command: "editedCipher", }); - expect(setAddEditCipherInfoSpy).toHaveBeenCalledWith({ - cipher: cipherView, - collectionIds: cipherView.collectionIds, - }); + expect(setAddEditCipherInfoSpy).toHaveBeenCalledWith( + { + cipher: cipherView, + collectionIds: cipherView.collectionIds, + }, + "testId", + ); expect(openAddEditVaultItemPopoutSpy).toHaveBeenCalledWith(sender.tab, { cipherId: cipherView.id, }); @@ -945,7 +951,7 @@ describe("NotificationBackground", () => { queueMessage, message.folder, ); - expect(editItemSpy).toHaveBeenCalledWith(cipherView, sender.tab); + expect(editItemSpy).toHaveBeenCalledWith(cipherView, "testId", sender.tab); expect(tabSendMessageSpy).toHaveBeenCalledWith(sender.tab, { command: "closeNotificationBar", }); diff --git a/apps/browser/src/autofill/background/notification.background.ts b/apps/browser/src/autofill/background/notification.background.ts index ad3bee97d8a..1a99425b7de 100644 --- a/apps/browser/src/autofill/background/notification.background.ts +++ b/apps/browser/src/autofill/background/notification.background.ts @@ -1,12 +1,13 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { firstValueFrom, map } from "rxjs"; +import { firstValueFrom } from "rxjs"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { PolicyType } from "@bitwarden/common/admin-console/enums"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; +import { getOptionalUserId } from "@bitwarden/common/auth/services/account.service"; import { ExtensionCommand, ExtensionCommandType, @@ -22,9 +23,11 @@ import { EnvironmentService } from "@bitwarden/common/platform/abstractions/envi import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { ThemeStateService } from "@bitwarden/common/platform/theming/theme-state.service"; +import { UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; import { CipherType } from "@bitwarden/common/vault/enums"; +import { buildCipherIcon } from "@bitwarden/common/vault/icon/build-cipher-icon"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { LoginUriView } from "@bitwarden/common/vault/models/view/login-uri.view"; import { LoginView } from "@bitwarden/common/vault/models/view/login.view"; @@ -32,6 +35,7 @@ import { LoginView } from "@bitwarden/common/vault/models/view/login.view"; import { openUnlockPopout } from "../../auth/popup/utils/auth-popout-window"; import { BrowserApi } from "../../platform/browser/browser-api"; import { openAddEditVaultItemPopout } from "../../vault/popup/utils/vault-popout-window"; +import { NotificationCipherData } from "../content/components/cipher/types"; import { NotificationQueueMessageType } from "../enums/notification-queue-message-type.enum"; import { AutofillService } from "../services/abstractions/autofill.service"; @@ -82,10 +86,9 @@ export default class NotificationBackground { bgGetActiveUserServerConfig: () => this.getActiveUserServerConfig(), getWebVaultUrlForNotification: () => this.getWebVaultUrl(), notificationRefreshFlagValue: () => this.getNotificationFlag(), + bgGetDecryptedCiphers: () => this.getNotificationCipherData(), }; - private activeUserId$ = this.accountService.activeAccount$.pipe(map((a) => a?.id)); - constructor( private autofillService: AutofillService, private cipherService: CipherService, @@ -132,6 +135,46 @@ export default class NotificationBackground { return await firstValueFrom(this.domainSettingsService.neverDomains$); } + /** + * + * Gets the current active tab and retrieves all decrypted ciphers + * for the tab's URL. It constructs and returns an array of `NotificationCipherData` objects. + * If no active tab or URL is found, it returns an empty array. + * + * @returns {Promise} + */ + + async getNotificationCipherData(): Promise { + const [currentTab, showFavicons, env] = await Promise.all([ + BrowserApi.getTabFromCurrentWindow(), + firstValueFrom(this.domainSettingsService.showFavicons$), + firstValueFrom(this.environmentService.environment$), + ]); + const iconsServerUrl = env.getIconsUrl(); + const activeUserId = await firstValueFrom( + this.accountService.activeAccount$.pipe(getOptionalUserId), + ); + const decryptedCiphers = await this.cipherService.getAllDecryptedForUrl( + currentTab.url, + activeUserId, + ); + + return decryptedCiphers.map((view) => { + const { id, name, reprompt, favorite, login } = view; + return { + id, + name, + type: CipherType.Login, + reprompt, + favorite, + icon: buildCipherIcon(iconsServerUrl, view, showFavicons), + login: login && { + username: login.username, + }, + }; + }); + } + /** * Gets the active user server config from the config service. */ @@ -267,7 +310,14 @@ export default class NotificationBackground { return; } - const ciphers = await this.cipherService.getAllDecryptedForUrl(loginInfo.url); + const activeUserId = await firstValueFrom( + this.accountService.activeAccount$.pipe(getOptionalUserId), + ); + if (activeUserId == null) { + return; + } + + const ciphers = await this.cipherService.getAllDecryptedForUrl(loginInfo.url, activeUserId); const usernameMatches = ciphers.filter( (c) => c.login.username != null && c.login.username.toLowerCase() === normalizedUsername, ); @@ -345,7 +395,14 @@ export default class NotificationBackground { } let id: string = null; - const ciphers = await this.cipherService.getAllDecryptedForUrl(changeData.url); + const activeUserId = await firstValueFrom( + this.accountService.activeAccount$.pipe(getOptionalUserId), + ); + if (activeUserId == null) { + return; + } + + const ciphers = await this.cipherService.getAllDecryptedForUrl(changeData.url, activeUserId); if (changeData.currentPassword != null) { const passwordMatches = ciphers.filter( (c) => c.login.password === changeData.currentPassword, @@ -498,37 +555,42 @@ export default class NotificationBackground { 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); - await this.updatePassword(cipherView, queueMessage.newPassword, edit, tab); + const cipherView = await this.getDecryptedCipherById(queueMessage.cipherId, activeUserId); + await this.updatePassword(cipherView, queueMessage.newPassword, edit, tab, activeUserId); return; } // 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(queueMessage.uri); + const allCiphers = await this.cipherService.getAllDecryptedForUrl( + queueMessage.uri, + activeUserId, + ); const existingCipher = allCiphers.find( (c) => c.login.username != null && c.login.username.toLowerCase() === queueMessage.username, ); if (existingCipher != null) { - await this.updatePassword(existingCipher, queueMessage.password, edit, tab); + await this.updatePassword(existingCipher, queueMessage.password, edit, tab, activeUserId); return; } } - folderId = (await this.folderExists(folderId)) ? folderId : null; + folderId = (await this.folderExists(folderId, activeUserId)) ? folderId : null; const newCipher = this.convertAddLoginQueueMessageToCipherView(queueMessage, folderId); if (edit) { - await this.editItem(newCipher, tab); + await this.editItem(newCipher, activeUserId, tab); await BrowserApi.tabSendMessage(tab, { command: "closeNotificationBar" }); return; } - const activeUserId = await firstValueFrom(this.activeUserId$); - const cipher = await this.cipherService.encrypt(newCipher, activeUserId); try { await this.cipherService.createWithServer(cipher); @@ -551,24 +613,25 @@ export default class NotificationBackground { * @param newPassword - The new password to update the cipher with * @param edit - Identifies if the cipher should be edited or simply updated * @param tab - The tab that the message was sent from + * @param userId - The active account user ID */ private async updatePassword( cipherView: CipherView, newPassword: string, edit: boolean, tab: chrome.tabs.Tab, + userId: UserId, ) { cipherView.login.password = newPassword; if (edit) { - await this.editItem(cipherView, tab); + await this.editItem(cipherView, userId, tab); await BrowserApi.tabSendMessage(tab, { command: "closeNotificationBar" }); await BrowserApi.tabSendMessage(tab, { command: "editedCipher" }); return; } - const activeUserId = await firstValueFrom(this.activeUserId$); - const cipher = await this.cipherService.encrypt(cipherView, activeUserId); + const cipher = await this.cipherService.encrypt(cipherView, userId); try { // We've only updated the password, no need to broadcast editedCipher message await this.cipherService.updateWithServer(cipher); @@ -585,33 +648,34 @@ export default class NotificationBackground { * and opens the add/edit vault item popout. * * @param cipherView - The cipher to edit + * @param userId - The active account user ID * @param senderTab - The tab that the message was sent from */ - private async editItem(cipherView: CipherView, senderTab: chrome.tabs.Tab) { - await this.cipherService.setAddEditCipherInfo({ - cipher: cipherView, - collectionIds: cipherView.collectionIds, - }); + private async editItem(cipherView: CipherView, userId: UserId, senderTab: chrome.tabs.Tab) { + await this.cipherService.setAddEditCipherInfo( + { + cipher: cipherView, + collectionIds: cipherView.collectionIds, + }, + userId, + ); await this.openAddEditVaultItemPopout(senderTab, { cipherId: cipherView.id }); } - private async folderExists(folderId: string) { + private async folderExists(folderId: string, userId: UserId) { if (Utils.isNullOrWhitespace(folderId) || folderId === "null") { return false; } - const activeUserId = await firstValueFrom(this.activeUserId$); - const folders = await firstValueFrom(this.folderService.folderViews$(activeUserId)); + const folders = await firstValueFrom(this.folderService.folderViews$(userId)); return folders.some((x) => x.id === folderId); } - private async getDecryptedCipherById(cipherId: string) { - const cipher = await this.cipherService.get(cipherId); + private async getDecryptedCipherById(cipherId: string, userId: UserId) { + const cipher = await this.cipherService.get(cipherId, userId); if (cipher != null && cipher.type === CipherType.Login) { - const activeUserId = await firstValueFrom(this.activeUserId$); - return await cipher.decrypt( - await this.cipherService.getKeyForCipherKeyDecryption(cipher, activeUserId), + await this.cipherService.getKeyForCipherKeyDecryption(cipher, userId), ); } return null; @@ -648,7 +712,9 @@ export default class NotificationBackground { * Returns the first value found from the folder service's folderViews$ observable. */ private async getFolderData() { - const activeUserId = await firstValueFrom(this.activeUserId$); + const activeUserId = await firstValueFrom( + this.accountService.activeAccount$.pipe(getOptionalUserId), + ); return await firstValueFrom(this.folderService.folderViews$(activeUserId)); } diff --git a/apps/browser/src/autofill/background/overlay.background.spec.ts b/apps/browser/src/autofill/background/overlay.background.spec.ts index c3a6357ed05..22531788d37 100644 --- a/apps/browser/src/autofill/background/overlay.background.spec.ts +++ b/apps/browser/src/autofill/background/overlay.background.spec.ts @@ -206,6 +206,7 @@ describe("OverlayBackground", () => { inlineMenuFieldQualificationService, themeStateService, totpService, + accountService, generatedPasswordCallbackMock, addPasswordCallbackMock, ); @@ -849,7 +850,7 @@ describe("OverlayBackground", () => { await flushPromises(); expect(BrowserApi.getTabFromCurrentWindowId).toHaveBeenCalled(); - expect(cipherService.getAllDecryptedForUrl).toHaveBeenCalledWith(url, [ + expect(cipherService.getAllDecryptedForUrl).toHaveBeenCalledWith(url, mockUserId, [ CipherType.Card, CipherType.Identity, ]); @@ -872,7 +873,7 @@ describe("OverlayBackground", () => { await flushPromises(); expect(BrowserApi.getTabFromCurrentWindowId).toHaveBeenCalled(); - expect(cipherService.getAllDecryptedForUrl).toHaveBeenCalledWith(url); + expect(cipherService.getAllDecryptedForUrl).toHaveBeenCalledWith(url, mockUserId); expect(cipherService.sortCiphersByLastUsedThenName).toHaveBeenCalled(); expect(overlayBackground["inlineMenuCiphers"]).toStrictEqual( new Map([ @@ -891,7 +892,7 @@ describe("OverlayBackground", () => { await flushPromises(); expect(BrowserApi.getTabFromCurrentWindowId).toHaveBeenCalled(); - expect(cipherService.getAllDecryptedForUrl).toHaveBeenCalledWith(url, [ + expect(cipherService.getAllDecryptedForUrl).toHaveBeenCalledWith(url, mockUserId, [ CipherType.Card, CipherType.Identity, ]); diff --git a/apps/browser/src/autofill/background/overlay.background.ts b/apps/browser/src/autofill/background/overlay.background.ts index 3d2b1ec783c..1d55a154ee3 100644 --- a/apps/browser/src/autofill/background/overlay.background.ts +++ b/apps/browser/src/autofill/background/overlay.background.ts @@ -13,8 +13,10 @@ import { } from "rxjs"; import { parse } from "tldts"; +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 { getOptionalUserId, getUserId } from "@bitwarden/common/auth/services/account.service"; import { AutofillOverlayVisibility, SHOW_AUTOFILL_BUTTON, @@ -34,6 +36,7 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { ThemeStateService } from "@bitwarden/common/platform/theming/theme-state.service"; +import { UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { TotpService } from "@bitwarden/common/vault/abstractions/totp.service"; import { VaultSettingsService } from "@bitwarden/common/vault/abstractions/vault-settings/vault-settings.service"; @@ -225,6 +228,7 @@ export class OverlayBackground implements OverlayBackgroundInterface { private inlineMenuFieldQualificationService: InlineMenuFieldQualificationService, private themeStateService: ThemeStateService, private totpService: TotpService, + private accountService: AccountService, private generatePasswordCallback: () => Promise, private addPasswordCallback: (password: string) => Promise, ) { @@ -405,13 +409,20 @@ export class OverlayBackground implements OverlayBackgroundInterface { currentTab: chrome.tabs.Tab, updateAllCipherTypes: boolean, ): Promise { - if (updateAllCipherTypes || !this.cardAndIdentityCiphers) { - return this.getAllCipherTypeViews(currentTab); + const activeUserId = await firstValueFrom( + this.accountService.activeAccount$.pipe(getOptionalUserId), + ); + if (!activeUserId) { + return []; } - const cipherViews = (await this.cipherService.getAllDecryptedForUrl(currentTab.url || "")).sort( - (a, b) => this.cipherService.sortCiphersByLastUsedThenName(a, b), - ); + if (updateAllCipherTypes || !this.cardAndIdentityCiphers) { + return this.getAllCipherTypeViews(currentTab, activeUserId); + } + + const cipherViews = ( + await this.cipherService.getAllDecryptedForUrl(currentTab.url || "", activeUserId) + ).sort((a, b) => this.cipherService.sortCiphersByLastUsedThenName(a, b)); return this.cardAndIdentityCiphers ? cipherViews.concat(...this.cardAndIdentityCiphers) @@ -422,15 +433,19 @@ export class OverlayBackground implements OverlayBackgroundInterface { * Queries all cipher types from the user's vault returns them sorted by last used. * * @param currentTab - The current tab + * @param userId - The active user id */ - private async getAllCipherTypeViews(currentTab: chrome.tabs.Tab): Promise { + private async getAllCipherTypeViews( + currentTab: chrome.tabs.Tab, + userId: UserId, + ): Promise { if (!this.cardAndIdentityCiphers) { this.cardAndIdentityCiphers = new Set([]); } this.cardAndIdentityCiphers.clear(); const cipherViews = ( - await this.cipherService.getAllDecryptedForUrl(currentTab.url || "", [ + await this.cipherService.getAllDecryptedForUrl(currentTab.url || "", userId, [ CipherType.Card, CipherType.Identity, ]) @@ -2399,10 +2414,14 @@ export class OverlayBackground implements OverlayBackgroundInterface { try { this.closeInlineMenu(sender); - await this.cipherService.setAddEditCipherInfo({ - cipher: cipherView, - collectionIds: cipherView.collectionIds, - }); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + await this.cipherService.setAddEditCipherInfo( + { + cipher: cipherView, + collectionIds: cipherView.collectionIds, + }, + activeUserId, + ); await this.openAddEditVaultItemPopout(sender.tab, { cipherId: cipherView.id, diff --git a/apps/browser/src/autofill/background/web-request.background.ts b/apps/browser/src/autofill/background/web-request.background.ts index 2c14358a359..22e10a3dd0a 100644 --- a/apps/browser/src/autofill/background/web-request.background.ts +++ b/apps/browser/src/autofill/background/web-request.background.ts @@ -1,7 +1,11 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore +import { firstValueFrom } from "rxjs"; + +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 { getOptionalUserId } from "@bitwarden/common/auth/services/account.service"; import { UriMatchStrategy } from "@bitwarden/common/models/domain/domain-service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; @@ -14,6 +18,7 @@ export default class WebRequestBackground { platformUtilsService: PlatformUtilsService, private cipherService: CipherService, private authService: AuthService, + private accountService: AccountService, private readonly webRequest: typeof chrome.webRequest, ) { this.isFirefox = platformUtilsService.isFirefox(); @@ -55,7 +60,16 @@ export default class WebRequestBackground { // eslint-disable-next-line private async resolveAuthCredentials(domain: string, success: Function, error: Function) { - if ((await this.authService.getAuthStatus()) < AuthenticationStatus.Unlocked) { + const activeUserId = await firstValueFrom( + this.accountService.activeAccount$.pipe(getOptionalUserId), + ); + if (activeUserId == null) { + error(); + return; + } + + const authStatus = await firstValueFrom(this.authService.authStatusFor$(activeUserId)); + if (authStatus < AuthenticationStatus.Unlocked) { error(); return; } @@ -63,6 +77,7 @@ export default class WebRequestBackground { try { const ciphers = await this.cipherService.getAllDecryptedForUrl( domain, + activeUserId, null, UriMatchStrategy.Host, ); diff --git a/apps/browser/src/autofill/browser/cipher-context-menu-handler.spec.ts b/apps/browser/src/autofill/browser/cipher-context-menu-handler.spec.ts index 4fed9eee5ef..3228aed4688 100644 --- a/apps/browser/src/autofill/browser/cipher-context-menu-handler.spec.ts +++ b/apps/browser/src/autofill/browser/cipher-context-menu-handler.spec.ts @@ -2,6 +2,8 @@ import { mock, MockProxy } from "jest-mock-extended"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; +import { mockAccountServiceWith } from "@bitwarden/common/spec"; +import { UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CipherType } from "@bitwarden/common/vault/enums"; import { CipherRepromptType } from "@bitwarden/common/vault/enums/cipher-reprompt-type"; @@ -14,6 +16,9 @@ describe("CipherContextMenuHandler", () => { let authService: MockProxy; let cipherService: MockProxy; + const mockUserId = "UserId" as UserId; + const accountService = mockAccountServiceWith(mockUserId); + let sut: CipherContextMenuHandler; beforeEach(() => { @@ -24,7 +29,12 @@ describe("CipherContextMenuHandler", () => { jest.spyOn(MainContextMenuHandler, "removeAll").mockResolvedValue(); - sut = new CipherContextMenuHandler(mainContextMenuHandler, authService, cipherService); + sut = new CipherContextMenuHandler( + mainContextMenuHandler, + authService, + cipherService, + accountService, + ); }); afterEach(() => jest.resetAllMocks()); @@ -119,10 +129,11 @@ describe("CipherContextMenuHandler", () => { expect(cipherService.getAllDecryptedForUrl).toHaveBeenCalledTimes(1); - expect(cipherService.getAllDecryptedForUrl).toHaveBeenCalledWith("https://test.com", [ - CipherType.Card, - CipherType.Identity, - ]); + expect(cipherService.getAllDecryptedForUrl).toHaveBeenCalledWith( + "https://test.com", + mockUserId, + [CipherType.Card, CipherType.Identity], + ); expect(mainContextMenuHandler.loadOptions).toHaveBeenCalledTimes(3); diff --git a/apps/browser/src/autofill/browser/cipher-context-menu-handler.ts b/apps/browser/src/autofill/browser/cipher-context-menu-handler.ts index b112ff00efe..038f4e85c9a 100644 --- a/apps/browser/src/autofill/browser/cipher-context-menu-handler.ts +++ b/apps/browser/src/autofill/browser/cipher-context-menu-handler.ts @@ -1,5 +1,9 @@ +import { firstValueFrom } from "rxjs"; + +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 { getOptionalUserId } from "@bitwarden/common/auth/services/account.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CipherType } from "@bitwarden/common/vault/enums"; @@ -14,6 +18,7 @@ export class CipherContextMenuHandler { private mainContextMenuHandler: MainContextMenuHandler, private authService: AuthService, private cipherService: CipherService, + private accountService: AccountService, ) {} async update(url: string) { @@ -35,7 +40,14 @@ export class CipherContextMenuHandler { return; } - const ciphers = await this.cipherService.getAllDecryptedForUrl(url, [ + const activeUserId = await firstValueFrom( + this.accountService.activeAccount$.pipe(getOptionalUserId), + ); + if (activeUserId == null) { + return; + } + + const ciphers = await this.cipherService.getAllDecryptedForUrl(url, activeUserId, [ CipherType.Card, CipherType.Identity, ]); diff --git a/apps/browser/src/autofill/browser/context-menu-clicked-handler.spec.ts b/apps/browser/src/autofill/browser/context-menu-clicked-handler.spec.ts index 6ef004f7979..c8cb7e81f72 100644 --- a/apps/browser/src/autofill/browser/context-menu-clicked-handler.spec.ts +++ b/apps/browser/src/autofill/browser/context-menu-clicked-handler.spec.ts @@ -61,6 +61,8 @@ describe("ContextMenuClickedHandler", () => { return cipherView; }; + const mockUserId = "UserId" as UserId; + let copyToClipboard: CopyToClipboardAction; let generatePasswordToClipboard: GeneratePasswordToClipboardAction; let autofill: AutofillAction; @@ -79,7 +81,7 @@ describe("ContextMenuClickedHandler", () => { autofill = jest.fn, [tab: chrome.tabs.Tab, cipher: CipherView]>(); authService = mock(); cipherService = mock(); - accountService = mockAccountServiceWith("userId" as UserId); + accountService = mockAccountServiceWith(mockUserId as UserId); totpService = mock(); eventCollectionService = mock(); @@ -191,7 +193,11 @@ describe("ContextMenuClickedHandler", () => { expect(cipherService.getAllDecryptedForUrl).toHaveBeenCalledTimes(1); - expect(cipherService.getAllDecryptedForUrl).toHaveBeenCalledWith("https://test.com", []); + expect(cipherService.getAllDecryptedForUrl).toHaveBeenCalledWith( + "https://test.com", + mockUserId, + [], + ); expect(copyToClipboard).toHaveBeenCalledTimes(1); @@ -215,7 +221,11 @@ describe("ContextMenuClickedHandler", () => { expect(cipherService.getAllDecryptedForUrl).toHaveBeenCalledTimes(1); - expect(cipherService.getAllDecryptedForUrl).toHaveBeenCalledWith("https://test.com", []); + expect(cipherService.getAllDecryptedForUrl).toHaveBeenCalledWith( + "https://test.com", + mockUserId, + [], + ); }); }); }); diff --git a/apps/browser/src/autofill/browser/context-menu-clicked-handler.ts b/apps/browser/src/autofill/browser/context-menu-clicked-handler.ts index 597d75575b0..69c8b6e70b8 100644 --- a/apps/browser/src/autofill/browser/context-menu-clicked-handler.ts +++ b/apps/browser/src/autofill/browser/context-menu-clicked-handler.ts @@ -1,12 +1,13 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { firstValueFrom, map } from "rxjs"; +import { firstValueFrom } from "rxjs"; import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; +import { getOptionalUserId } from "@bitwarden/common/auth/services/account.service"; import { AUTOFILL_CARD_ID, AUTOFILL_ID, @@ -105,6 +106,13 @@ export class ContextMenuClickedHandler { menuItemId as string, ); + const activeUserId = await firstValueFrom( + this.accountService.activeAccount$.pipe(getOptionalUserId), + ); + if (activeUserId == null) { + return; + } + if (isCreateCipherAction) { // pass; defer to logic below } else if (menuItemId === NOOP_COMMAND_SUFFIX) { @@ -120,12 +128,13 @@ export class ContextMenuClickedHandler { // in scenarios like unlock on autofill const ciphers = await this.cipherService.getAllDecryptedForUrl( tab.url, + activeUserId, additionalCiphersToGet, ); cipher = ciphers[0]; } else { - const ciphers = await this.cipherService.getAllDecrypted(); + const ciphers = await this.cipherService.getAllDecrypted(activeUserId); cipher = ciphers.find(({ id }) => id === menuItemId); } @@ -133,9 +142,6 @@ export class ContextMenuClickedHandler { return; } - const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), - ); await this.accountService.setAccountActivity(activeUserId, new Date()); switch (info.parentMenuItemId) { case AUTOFILL_ID: diff --git a/apps/browser/src/autofill/clipboard/clear-clipboard.spec.ts b/apps/browser/src/autofill/clipboard/clear-clipboard.spec.ts deleted file mode 100644 index 7bfe7934046..00000000000 --- a/apps/browser/src/autofill/clipboard/clear-clipboard.spec.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { BrowserApi } from "../../platform/browser/browser-api"; - -import { ClearClipboard } from "./clear-clipboard"; - -describe("clearClipboard", () => { - describe("run", () => { - it("Does not clear clipboard when no active tabs are retrieved", async () => { - jest.spyOn(BrowserApi, "getActiveTabs").mockResolvedValue([] as any); - - jest.spyOn(BrowserApi, "sendTabsMessage").mockReturnValue(); - - await ClearClipboard.run(); - - expect(jest.spyOn(BrowserApi, "sendTabsMessage")).not.toHaveBeenCalled(); - - expect(jest.spyOn(BrowserApi, "sendTabsMessage")).not.toHaveBeenCalledWith(1, { - command: "clearClipboard", - }); - }); - - it("Sends a message to the content script to clear the clipboard", async () => { - jest.spyOn(BrowserApi, "getActiveTabs").mockResolvedValue([ - { - id: 1, - }, - ] as any); - - jest.spyOn(BrowserApi, "sendTabsMessage").mockReturnValue(); - - await ClearClipboard.run(); - - expect(jest.spyOn(BrowserApi, "sendTabsMessage")).toHaveBeenCalledTimes(1); - - expect(jest.spyOn(BrowserApi, "sendTabsMessage")).toHaveBeenCalledWith(1, { - command: "clearClipboard", - }); - }); - }); -}); diff --git a/apps/browser/src/autofill/clipboard/clear-clipboard.ts b/apps/browser/src/autofill/clipboard/clear-clipboard.ts deleted file mode 100644 index 93674df0ad9..00000000000 --- a/apps/browser/src/autofill/clipboard/clear-clipboard.ts +++ /dev/null @@ -1,22 +0,0 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore -import { BrowserApi } from "../../platform/browser/browser-api"; - -export class ClearClipboard { - /** - We currently rely on an active tab with an injected content script (`../content/misc-utils.ts`) to clear the clipboard via `window.navigator.clipboard.writeText(text)` - - With https://bugs.chromium.org/p/chromium/issues/detail?id=1160302 it was said that service workers, - would have access to the clipboard api and then we could migrate to a simpler solution - */ - static async run() { - const activeTabs = await BrowserApi.getActiveTabs(); - if (!activeTabs || activeTabs.length === 0) { - return; - } - - BrowserApi.sendTabsMessage(activeTabs[0].id, { - command: "clearClipboard", - }); - } -} diff --git a/apps/browser/src/autofill/clipboard/copy-to-clipboard-command.ts b/apps/browser/src/autofill/clipboard/copy-to-clipboard-command.ts deleted file mode 100644 index 92d35e70e57..00000000000 --- a/apps/browser/src/autofill/clipboard/copy-to-clipboard-command.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { BrowserApi } from "../../platform/browser/browser-api"; - -/** - * Copies text to the clipboard in a MV3 safe way. - * @param tab - The tab that the text will be sent to so that it can be copied to the users clipboard this needs to be an active tab or the DOM won't be able to be used to do the action. The tab sent in here should be from a user started action or queried for active tabs. - * @param text - The text that you want added to the users clipboard. - */ -export const copyToClipboard = async (tab: chrome.tabs.Tab, text: string) => { - if (tab.id == null) { - throw new Error("Cannot copy text to clipboard with a tab that does not have an id."); - } - - BrowserApi.sendTabsMessage(tab.id, { - command: "copyText", - text: text, - }); -}; diff --git a/apps/browser/src/autofill/clipboard/generate-password-to-clipboard-command.spec.ts b/apps/browser/src/autofill/clipboard/generate-password-to-clipboard-command.spec.ts deleted file mode 100644 index d0d42cc06f7..00000000000 --- a/apps/browser/src/autofill/clipboard/generate-password-to-clipboard-command.spec.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { mock, MockProxy } from "jest-mock-extended"; -import { firstValueFrom, Subscription } from "rxjs"; - -import { AutofillSettingsService } from "@bitwarden/common/autofill/services/autofill-settings.service"; -import { ScheduledTaskNames } from "@bitwarden/common/platform/scheduling"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; - -import { BrowserApi } from "../../platform/browser/browser-api"; -import { BrowserTaskSchedulerService } from "../../platform/services/abstractions/browser-task-scheduler.service"; - -import { ClearClipboard } from "./clear-clipboard"; -import { GeneratePasswordToClipboardCommand } from "./generate-password-to-clipboard-command"; - -jest.mock("rxjs", () => { - const actual = jest.requireActual("rxjs"); - return { - ...actual, - firstValueFrom: jest.fn(), - }; -}); - -describe("GeneratePasswordToClipboardCommand", () => { - let passwordGenerationService: MockProxy; - let autofillSettingsService: MockProxy; - let browserTaskSchedulerService: MockProxy; - - let sut: GeneratePasswordToClipboardCommand; - - beforeEach(() => { - passwordGenerationService = mock(); - autofillSettingsService = mock(); - browserTaskSchedulerService = mock({ - setTimeout: jest.fn((taskName, timeoutInMs) => { - const timeoutHandle = setTimeout(() => { - if (taskName === ScheduledTaskNames.generatePasswordClearClipboardTimeout) { - void ClearClipboard.run(); - } - }, timeoutInMs); - - return new Subscription(() => clearTimeout(timeoutHandle)); - }), - }); - - passwordGenerationService.getOptions.mockResolvedValue([{ length: 8 }, {} as any]); - - passwordGenerationService.generatePassword.mockResolvedValue("PASSWORD"); - - jest.spyOn(BrowserApi, "sendTabsMessage").mockReturnValue(); - - sut = new GeneratePasswordToClipboardCommand( - passwordGenerationService, - autofillSettingsService, - browserTaskSchedulerService, - ); - }); - - afterEach(() => { - jest.resetAllMocks(); - }); - - describe("generatePasswordToClipboard", () => { - it("has clear clipboard value", async () => { - jest.useFakeTimers(); - jest.spyOn(ClearClipboard, "run"); - (firstValueFrom as jest.Mock).mockResolvedValue(2 * 60); // 2 minutes - - await sut.generatePasswordToClipboard({ id: 1 } as any); - jest.advanceTimersByTime(2 * 60 * 1000); - - expect(jest.spyOn(BrowserApi, "sendTabsMessage")).toHaveBeenCalledTimes(1); - expect(jest.spyOn(BrowserApi, "sendTabsMessage")).toHaveBeenCalledWith(1, { - command: "copyText", - text: "PASSWORD", - }); - expect(browserTaskSchedulerService.setTimeout).toHaveBeenCalledTimes(1); - expect(browserTaskSchedulerService.setTimeout).toHaveBeenCalledWith( - ScheduledTaskNames.generatePasswordClearClipboardTimeout, - expect.any(Number), - ); - expect(ClearClipboard.run).toHaveBeenCalledTimes(1); - }); - - it("does not have clear clipboard value", async () => { - jest.spyOn(sut as any, "getClearClipboard").mockImplementation(() => null); - - await sut.generatePasswordToClipboard({ id: 1 } as any); - - expect(jest.spyOn(BrowserApi, "sendTabsMessage")).toHaveBeenCalledTimes(1); - - expect(jest.spyOn(BrowserApi, "sendTabsMessage")).toHaveBeenCalledWith(1, { - command: "copyText", - text: "PASSWORD", - }); - expect(browserTaskSchedulerService.setTimeout).not.toHaveBeenCalled(); - }); - }); -}); diff --git a/apps/browser/src/autofill/clipboard/generate-password-to-clipboard-command.ts b/apps/browser/src/autofill/clipboard/generate-password-to-clipboard-command.ts deleted file mode 100644 index 5fb6e8667a4..00000000000 --- a/apps/browser/src/autofill/clipboard/generate-password-to-clipboard-command.ts +++ /dev/null @@ -1,48 +0,0 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore -import { firstValueFrom, Subscription } from "rxjs"; - -import { AutofillSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/autofill-settings.service"; -import { TaskSchedulerService, ScheduledTaskNames } from "@bitwarden/common/platform/scheduling"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; - -import { ClearClipboard } from "./clear-clipboard"; -import { copyToClipboard } from "./copy-to-clipboard-command"; - -export class GeneratePasswordToClipboardCommand { - private clearClipboardSubscription: Subscription; - - constructor( - private passwordGenerationService: PasswordGenerationServiceAbstraction, - private autofillSettingsService: AutofillSettingsServiceAbstraction, - private taskSchedulerService: TaskSchedulerService, - ) { - this.taskSchedulerService.registerTaskHandler( - ScheduledTaskNames.generatePasswordClearClipboardTimeout, - () => ClearClipboard.run(), - ); - } - - async getClearClipboard() { - return await firstValueFrom(this.autofillSettingsService.clearClipboardDelay$); - } - - async generatePasswordToClipboard(tab: chrome.tabs.Tab) { - const [options] = await this.passwordGenerationService.getOptions(); - const password = await this.passwordGenerationService.generatePassword(options); - - await copyToClipboard(tab, password); - - const clearClipboardDelayInSeconds = await this.getClearClipboard(); - if (!clearClipboardDelayInSeconds) { - return; - } - - const timeoutInMs = clearClipboardDelayInSeconds * 1000; - this.clearClipboardSubscription?.unsubscribe(); - this.clearClipboardSubscription = this.taskSchedulerService.setTimeout( - ScheduledTaskNames.generatePasswordClearClipboardTimeout, - timeoutInMs, - ); - } -} diff --git a/apps/browser/src/autofill/clipboard/index.ts b/apps/browser/src/autofill/clipboard/index.ts deleted file mode 100644 index 3682afd5054..00000000000 --- a/apps/browser/src/autofill/clipboard/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from "./clear-clipboard"; -export * from "./copy-to-clipboard-command"; -export * from "./generate-password-to-clipboard-command"; 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 157682160ed..9068bbfc27d 100644 --- a/apps/browser/src/autofill/content/components/.lit-storybook/main.ts +++ b/apps/browser/src/autofill/content/components/.lit-storybook/main.ts @@ -8,7 +8,7 @@ const getAbsolutePath = (value: string): string => dirname(require.resolve(join(value, "package.json"))); const config: StorybookConfig = { - stories: ["../lit-stories/**/*.lit-stories.@(js|jsx|ts|tsx)"], + stories: ["../lit-stories/**/*.lit-stories.@(js|jsx|ts|tsx)", "../lit-stories/**/*.mdx"], addons: [ getAbsolutePath("@storybook/addon-links"), getAbsolutePath("@storybook/addon-essentials"), diff --git a/apps/browser/src/autofill/content/components/cipher/cipher-info.ts b/apps/browser/src/autofill/content/components/cipher/cipher-info.ts index de374b44a97..6ff32353938 100644 --- a/apps/browser/src/autofill/content/components/cipher/cipher-info.ts +++ b/apps/browser/src/autofill/content/components/cipher/cipher-info.ts @@ -6,10 +6,10 @@ import { Theme } from "@bitwarden/common/platform/enums"; import { themes, typography } from "../../../content/components/constants/styles"; import { CipherInfoIndicatorIcons } from "./cipher-indicator-icons"; -import { CipherData } from "./types"; +import { NotificationCipherData } from "./types"; // @TODO support other cipher types (card, identity, notes, etc) -export function CipherInfo({ cipher, theme }: { cipher: CipherData; theme: Theme }) { +export function CipherInfo({ cipher, theme }: { cipher: NotificationCipherData; theme: Theme }) { const { name, login } = cipher; 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 651c20cac3a..96b44d2c0cc 100644 --- a/apps/browser/src/autofill/content/components/cipher/cipher-item.ts +++ b/apps/browser/src/autofill/content/components/cipher/cipher-item.ts @@ -12,7 +12,7 @@ import { import { CipherAction } from "./cipher-action"; import { CipherIcon } from "./cipher-icon"; import { CipherInfo } from "./cipher-info"; -import { CipherData } from "./types"; +import { NotificationCipherData } from "./types"; const cipherIconWidth = "24px"; @@ -22,7 +22,7 @@ export function CipherItem({ notificationType, theme = ThemeTypes.Light, }: { - cipher: CipherData; + cipher: NotificationCipherData; handleAction?: (e: Event) => void; notificationType?: NotificationType; theme: Theme; diff --git a/apps/browser/src/autofill/content/components/cipher/types.ts b/apps/browser/src/autofill/content/components/cipher/types.ts index acdee756570..ff29f9b559f 100644 --- a/apps/browser/src/autofill/content/components/cipher/types.ts +++ b/apps/browser/src/autofill/content/components/cipher/types.ts @@ -1,6 +1,4 @@ -// FIXME: Remove when updating file. Eslint update -// eslint-disable-next-line @typescript-eslint/no-unused-vars -const CipherTypes = { +export const CipherTypes = { Login: 1, SecureNote: 2, Card: 3, @@ -9,9 +7,7 @@ const CipherTypes = { type CipherType = (typeof CipherTypes)[keyof typeof CipherTypes]; -// FIXME: Remove when updating file. Eslint update -// eslint-disable-next-line @typescript-eslint/no-unused-vars -const CipherRepromptTypes = { +export const CipherRepromptTypes = { None: 0, Password: 1, } as const; @@ -25,13 +21,16 @@ export type WebsiteIconData = { icon: string; }; -export type CipherData = { +type BaseCipherData = { id: string; name: string; - type: CipherType; + type: CipherTypeValue; reprompt: CipherRepromptType; favorite: boolean; icon: WebsiteIconData; +}; + +export type CipherData = BaseCipherData & { accountCreationFieldType?: string; login?: { username: string; @@ -46,3 +45,9 @@ export type CipherData = { username?: string; }; }; + +export type NotificationCipherData = BaseCipherData & { + login?: { + username: string; + }; +}; diff --git a/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/action-button.mdx b/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/action-button.mdx new file mode 100644 index 00000000000..d3c1968b32f --- /dev/null +++ b/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/action-button.mdx @@ -0,0 +1,64 @@ +import { Meta, Controls, Primary } from "@storybook/addon-docs"; + +import * as stories from "./action-button.lit-stories"; + + + +## Action Button + +The `ActionButton` component is a customizable button built using the `lit` library and styled with +`@emotion/css`. This component supports themes, handles click events, and includes a disabled state. +It is designed with accessibility and responsive design in mind. + + + + +## Props + +| **Prop** | **Type** | **Required** | **Description** | +| -------------- | -------------------------- | ------------ | ----------------------------------------------------------- | +| `buttonAction` | `(e: Event) => void` | Yes | The function to execute when the button is clicked. | +| `buttonText` | `string` | Yes | The text to display on the button. | +| `disabled` | `boolean` (default: false) | No | Disables the button when set to `true`. | +| `theme` | `Theme` | Yes | The theme to style the button. Must match the `Theme` enum. | + +## Installation and Setup + +1. Ensure you have the necessary dependencies installed: + + - `lit`: Used to render the component. + - `@emotion/css`: Used for styling the component. + +2. Pass the required props to the component when rendering: + - `buttonAction`: A function that handles the click event. + - `buttonText`: The text displayed on the button. + - `disabled` (optional): A boolean indicating whether the button is disabled. + - `theme`: The theme to style the button (must be a valid `Theme`). + +## Accessibility (WCAG) Compliance + +The `ActionButton` component follows the +[W3C ARIA button pattern](https://www.w3.org/WAI/ARIA/apg/patterns/button/). Below is a breakdown of +key accessibility considerations: + +### Keyboard Accessibility + +- The button supports keyboard interaction through the `@click` event. +- Users can activate the button using the `Enter` or `Space` key. + +### Screen Reader Compatibility + +- The `title` attribute is dynamically set to the button's text (`buttonText`), ensuring it is read + by screen readers. +- The semantic ` + + + + +

{{ pageDescription$ | async }}

+ + + + + + + + + +
+ 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 new file mode 100644 index 00000000000..39b9650538a --- /dev/null +++ b/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.spec.ts @@ -0,0 +1,272 @@ +import { Component, Input } from "@angular/core"; +import { ComponentFixture, TestBed } from "@angular/core/testing"; +import { By } from "@angular/platform-browser"; +import { mock } from "jest-mock-extended"; +import { BehaviorSubject, firstValueFrom, of } from "rxjs"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { IconComponent } from "@bitwarden/angular/vault/components/icon.component"; +import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; +import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { AutofillOverlayVisibility } from "@bitwarden/common/autofill/constants"; +import { AutofillSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/autofill-settings.service"; +import { InlineMenuVisibilitySetting } from "@bitwarden/common/autofill/types"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; +import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; +import { ToastService } from "@bitwarden/components"; +import { + ChangeLoginPasswordService, + DefaultChangeLoginPasswordService, + PasswordRepromptService, + SecurityTask, + SecurityTaskType, + TaskService, +} from "@bitwarden/vault"; + +import { PopupHeaderComponent } from "../../../../platform/popup/layout/popup-header.component"; +import { PopupPageComponent } from "../../../../platform/popup/layout/popup-page.component"; + +import { AtRiskPasswordPageService } from "./at-risk-password-page.service"; +import { AtRiskPasswordsComponent } from "./at-risk-passwords.component"; + +@Component({ + standalone: true, + selector: "popup-header", + template: ``, +}) +class MockPopupHeaderComponent { + @Input() pageTitle: string | undefined; + @Input() backAction: (() => void) | undefined; +} + +@Component({ + standalone: true, + selector: "popup-page", + template: ``, +}) +class MockPopupPageComponent { + @Input() loading: boolean | undefined; +} + +@Component({ + standalone: true, + selector: "app-vault-icon", + template: ``, +}) +class MockAppIcon { + @Input() cipher: CipherView | undefined; +} + +describe("AtRiskPasswordsComponent", () => { + let component: AtRiskPasswordsComponent; + let fixture: ComponentFixture; + + let mockTasks$: BehaviorSubject; + let mockCiphers$: BehaviorSubject; + let mockOrgs$: BehaviorSubject; + let mockInlineMenuVisibility$: BehaviorSubject; + let calloutDismissed$: BehaviorSubject; + const setInlineMenuVisibility = jest.fn(); + const mockToastService = mock(); + const mockAtRiskPasswordPageService = mock(); + const mockChangeLoginPasswordService = mock(); + + beforeEach(async () => { + mockTasks$ = new BehaviorSubject([ + { + id: "task", + organizationId: "org", + cipherId: "cipher", + type: SecurityTaskType.UpdateAtRiskCredential, + } as SecurityTask, + ]); + mockCiphers$ = new BehaviorSubject([ + { + id: "cipher", + organizationId: "org", + name: "Item 1", + } as CipherView, + { + id: "cipher2", + organizationId: "org", + name: "Item 2", + } as CipherView, + ]); + mockOrgs$ = new BehaviorSubject([ + { + id: "org", + name: "Org 1", + } as Organization, + ]); + + mockInlineMenuVisibility$ = new BehaviorSubject( + AutofillOverlayVisibility.Off, + ); + + calloutDismissed$ = new BehaviorSubject(false); + setInlineMenuVisibility.mockClear(); + mockToastService.showToast.mockClear(); + mockAtRiskPasswordPageService.isCalloutDismissed.mockReturnValue(calloutDismissed$); + + await TestBed.configureTestingModule({ + imports: [AtRiskPasswordsComponent], + providers: [ + { + provide: TaskService, + useValue: { + pendingTasks$: () => mockTasks$, + }, + }, + { + provide: OrganizationService, + useValue: { + organizations$: () => mockOrgs$, + }, + }, + { + provide: CipherService, + useValue: { + cipherViews$: () => mockCiphers$, + }, + }, + { provide: I18nService, useValue: { t: (key: string) => key } }, + { provide: AccountService, useValue: { activeAccount$: of({ id: "user" }) } }, + { provide: PlatformUtilsService, useValue: mock() }, + { provide: PasswordRepromptService, useValue: mock() }, + { + provide: AutofillSettingsServiceAbstraction, + useValue: { + inlineMenuVisibility$: mockInlineMenuVisibility$, + setInlineMenuVisibility: setInlineMenuVisibility, + }, + }, + { provide: ToastService, useValue: mockToastService }, + ], + }) + .overrideModule(JslibModule, { + remove: { + imports: [IconComponent], + exports: [IconComponent], + }, + add: { + imports: [MockAppIcon], + exports: [MockAppIcon], + }, + }) + .overrideComponent(AtRiskPasswordsComponent, { + remove: { + imports: [PopupHeaderComponent, PopupPageComponent], + providers: [ + AtRiskPasswordPageService, + { provide: ChangeLoginPasswordService, useClass: DefaultChangeLoginPasswordService }, + ], + }, + add: { + imports: [MockPopupHeaderComponent, MockPopupPageComponent], + providers: [ + { provide: AtRiskPasswordPageService, useValue: mockAtRiskPasswordPageService }, + { provide: ChangeLoginPasswordService, useValue: mockChangeLoginPasswordService }, + ], + }, + }) + .compileComponents(); + + fixture = TestBed.createComponent(AtRiskPasswordsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it("should create", () => { + expect(component).toBeTruthy(); + }); + + describe("pending atRiskItems$", () => { + it("should list pending at risk item tasks", async () => { + const items = await firstValueFrom(component["atRiskItems$"]); + expect(items).toHaveLength(1); + expect(items[0].name).toBe("Item 1"); + }); + }); + + describe("pageDescription$", () => { + it("should use single org description when tasks belong to one org", async () => { + const description = await firstValueFrom(component["pageDescription$"]); + expect(description).toBe("atRiskPasswordsDescSingleOrg"); + }); + + it("should use multiple org description when tasks belong to multiple orgs", async () => { + mockTasks$.next([ + { + id: "task", + organizationId: "org", + cipherId: "cipher", + type: SecurityTaskType.UpdateAtRiskCredential, + } as SecurityTask, + { + id: "task2", + organizationId: "org2", + cipherId: "cipher2", + type: SecurityTaskType.UpdateAtRiskCredential, + } as SecurityTask, + ]); + const description = await firstValueFrom(component["pageDescription$"]); + expect(description).toBe("atRiskPasswordsDescMultiOrg"); + }); + }); + + describe("autofill callout", () => { + it("should show the callout if inline autofill is disabled", async () => { + mockInlineMenuVisibility$.next(AutofillOverlayVisibility.Off); + calloutDismissed$.next(false); + fixture.detectChanges(); + const callout = fixture.debugElement.query(By.css('[data-testid="autofill-callout"]')); + + expect(callout).toBeTruthy(); + }); + + it("should hide the callout if inline autofill is enabled", async () => { + mockInlineMenuVisibility$.next(AutofillOverlayVisibility.OnButtonClick); + calloutDismissed$.next(false); + fixture.detectChanges(); + const callout = fixture.debugElement.query(By.css('[data-testid="autofill-callout"]')); + + expect(callout).toBeFalsy(); + }); + + it("should hide the callout if the user has previously dismissed it", async () => { + mockInlineMenuVisibility$.next(AutofillOverlayVisibility.Off); + calloutDismissed$.next(true); + fixture.detectChanges(); + const callout = fixture.debugElement.query(By.css('[data-testid="autofill-callout"]')); + + expect(callout).toBeFalsy(); + }); + + it("should call dismissCallout when the dismiss callout button is clicked", async () => { + mockInlineMenuVisibility$.next(AutofillOverlayVisibility.Off); + fixture.detectChanges(); + const dismissButton = fixture.debugElement.query( + By.css('[data-testid="dismiss-callout-button"]'), + ); + dismissButton.nativeElement.click(); + expect(mockAtRiskPasswordPageService.dismissCallout).toHaveBeenCalled(); + }); + + describe("turn on autofill button", () => { + it("should call the service to turn on inline autofill and show a toast", () => { + const button = fixture.debugElement.query( + By.css('[data-testid="turn-on-autofill-button"]'), + ); + button.nativeElement.click(); + + expect(setInlineMenuVisibility).toHaveBeenCalledWith( + AutofillOverlayVisibility.OnButtonClick, + ); + expect(mockToastService.showToast).toHaveBeenCalled(); + }); + }); + }); +}); 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 new file mode 100644 index 00000000000..4753bc77ecb --- /dev/null +++ b/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.ts @@ -0,0 +1,184 @@ +import { CommonModule } from "@angular/common"; +import { Component, inject, signal } from "@angular/core"; +import { Router } from "@angular/router"; +import { combineLatest, firstValueFrom, map, of, shareReplay, startWith, switchMap } from "rxjs"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { + getOrganizationById, + OrganizationService, +} from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { AutofillOverlayVisibility } from "@bitwarden/common/autofill/constants"; +import { AutofillSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/autofill-settings.service"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; +import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; +import { + BadgeModule, + ButtonModule, + CalloutModule, + ItemModule, + ToastService, + TypographyModule, +} from "@bitwarden/components"; +import { + ChangeLoginPasswordService, + DefaultChangeLoginPasswordService, + filterOutNullish, + PasswordRepromptService, + SecurityTaskType, + TaskService, +} from "@bitwarden/vault"; + +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 { AtRiskPasswordPageService } from "./at-risk-password-page.service"; + +@Component({ + imports: [ + PopupPageComponent, + PopupHeaderComponent, + PopOutComponent, + ItemModule, + CommonModule, + JslibModule, + TypographyModule, + CalloutModule, + ButtonModule, + BadgeModule, + ], + providers: [ + AtRiskPasswordPageService, + { provide: ChangeLoginPasswordService, useClass: DefaultChangeLoginPasswordService }, + ], + selector: "vault-at-risk-passwords", + standalone: true, + templateUrl: "./at-risk-passwords.component.html", +}) +export class AtRiskPasswordsComponent { + private taskService = inject(TaskService); + private organizationService = inject(OrganizationService); + private cipherService = inject(CipherService); + private i18nService = inject(I18nService); + private accountService = inject(AccountService); + private passwordRepromptService = inject(PasswordRepromptService); + private router = inject(Router); + private autofillSettingsService = inject(AutofillSettingsServiceAbstraction); + private toastService = inject(ToastService); + private atRiskPasswordPageService = inject(AtRiskPasswordPageService); + private changeLoginPasswordService = inject(ChangeLoginPasswordService); + private platformUtilsService = inject(PlatformUtilsService); + + /** + * The cipher that is currently being launched. Used to show a loading spinner on the badge button. + * The UI utilize a bitBadge which does not support async actions (like bitButton does). + * @protected + */ + protected launchingCipher = signal(null); + + private activeUserData$ = this.accountService.activeAccount$.pipe( + filterOutNullish(), + switchMap((user) => + combineLatest([ + this.taskService.pendingTasks$(user.id), + this.cipherService.cipherViews$(user.id).pipe( + filterOutNullish(), + map((ciphers) => Object.fromEntries(ciphers.map((c) => [c.id, c]))), + ), + of(user), + ]), + ), + map(([tasks, ciphers, user]) => ({ + tasks, + ciphers, + userId: user.id, + })), + shareReplay({ bufferSize: 1, refCount: true }), + ); + + protected loading$ = this.activeUserData$.pipe( + map(() => false), + startWith(true), + ); + + protected calloutDismissed$ = this.activeUserData$.pipe( + switchMap(({ userId }) => this.atRiskPasswordPageService.isCalloutDismissed(userId)), + ); + + protected inlineAutofillSettingEnabled$ = this.autofillSettingsService.inlineMenuVisibility$.pipe( + map((setting) => setting !== AutofillOverlayVisibility.Off), + ); + + protected atRiskItems$ = this.activeUserData$.pipe( + map(({ tasks, ciphers }) => + tasks + .filter( + (t) => + t.type === SecurityTaskType.UpdateAtRiskCredential && + t.cipherId != null && + ciphers[t.cipherId] != null, + ) + .map((t) => ciphers[t.cipherId!]), + ), + ); + + protected pageDescription$ = this.activeUserData$.pipe( + switchMap(({ tasks, userId }) => { + const orgIds = new Set(tasks.map((t) => t.organizationId)); + if (orgIds.size === 1) { + const [orgId] = orgIds; + return this.organizationService.organizations$(userId).pipe( + getOrganizationById(orgId), + map((org) => this.i18nService.t("atRiskPasswordsDescSingleOrg", org?.name, tasks.length)), + ); + } + + return of(this.i18nService.t("atRiskPasswordsDescMultiOrg", tasks.length)); + }), + ); + + async viewCipher(cipher: CipherView) { + const repromptPassed = await this.passwordRepromptService.passwordRepromptCheck(cipher); + if (!repromptPassed) { + return; + } + await this.router.navigate(["/view-cipher"], { + queryParams: { cipherId: cipher.id, type: cipher.type }, + }); + } + + async activateInlineAutofillMenuVisibility() { + await this.autofillSettingsService.setInlineMenuVisibility( + AutofillOverlayVisibility.OnButtonClick, + ); + this.toastService.showToast({ + variant: "success", + message: this.i18nService.t("turnedOnAutofill"), + title: "", + }); + } + + async dismissCallout() { + const { userId } = await firstValueFrom(this.activeUserData$); + await this.atRiskPasswordPageService.dismissCallout(userId); + } + + launchChangePassword = async (cipher: CipherView) => { + try { + this.launchingCipher.set(cipher); + const url = await this.changeLoginPasswordService.getChangePasswordUrl(cipher); + + if (url == null) { + return; + } + + this.platformUtilsService.launchUri(url); + } finally { + this.launchingCipher.set(null); + } + }; +} diff --git a/apps/browser/src/vault/popup/components/vault-v2/add-edit/add-edit-v2.component.spec.ts b/apps/browser/src/vault/popup/components/vault-v2/add-edit/add-edit-v2.component.spec.ts index 3252f030fc3..6974e6f7359 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/add-edit/add-edit-v2.component.spec.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/add-edit/add-edit-v2.component.spec.ts @@ -1,14 +1,17 @@ import { ComponentFixture, fakeAsync, TestBed, tick } from "@angular/core/testing"; import { ActivatedRoute, Router } from "@angular/router"; import { mock, MockProxy } from "jest-mock-extended"; -import { BehaviorSubject, Observable } from "rxjs"; +import { BehaviorSubject } from "rxjs"; import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { EventType } from "@bitwarden/common/enums"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { mockAccountServiceWith } from "@bitwarden/common/spec"; +import { UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CipherType } from "@bitwarden/common/vault/enums"; import { Cipher } from "@bitwarden/common/vault/models/domain/cipher"; @@ -58,9 +61,9 @@ describe("AddEditV2Component", () => { collect.mockClear(); addEditCipherInfo$ = new BehaviorSubject(null); - cipherServiceMock = mock(); - cipherServiceMock.addEditCipherInfo$ = - addEditCipherInfo$.asObservable() as Observable; + cipherServiceMock = mock({ + addEditCipherInfo$: jest.fn().mockReturnValue(addEditCipherInfo$), + }); await TestBed.configureTestingModule({ imports: [AddEditV2Component], @@ -81,6 +84,7 @@ describe("AddEditV2Component", () => { canDeleteCipher$: jest.fn().mockReturnValue(true), }, }, + { provide: AccountService, useValue: mockAccountServiceWith("UserId" as UserId) }, ], }) .overrideProvider(CipherFormConfigService, { 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 b46b1d61509..1dcb48c918d 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 @@ -9,10 +9,12 @@ import { firstValueFrom, map, Observable, switchMap } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { 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 { CipherId, CollectionId, OrganizationId } from "@bitwarden/common/types/guid"; +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 { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; @@ -180,6 +182,7 @@ export class AddEditV2Component implements OnInit { private toastService: ToastService, private dialogService: DialogService, protected cipherAuthorizationService: CipherAuthorizationService, + private accountService: AccountService, ) { this.subscribeToParams(); } @@ -281,9 +284,15 @@ export class AddEditV2Component implements OnInit { config.initialValues = this.setInitialValuesFromParams(params); + const activeUserId = await firstValueFrom( + this.accountService.activeAccount$.pipe(getUserId), + ); + // The browser notification bar and overlay use addEditCipherInfo$ to pass modified cipher details to the form // Attempt to fetch them here and overwrite the initialValues if present - const cachedCipherInfo = await firstValueFrom(this.cipherService.addEditCipherInfo$); + const cachedCipherInfo = await firstValueFrom( + this.cipherService.addEditCipherInfo$(activeUserId), + ); if (cachedCipherInfo != null) { // Cached cipher info has priority over queryParams @@ -292,7 +301,7 @@ export class AddEditV2Component implements OnInit { ...mapAddEditCipherInfoToInitialValues(cachedCipherInfo), }; // Be sure to clear the "cached" cipher info, so it doesn't get used again - await this.cipherService.setAddEditCipherInfo(null); + await this.cipherService.setAddEditCipherInfo(null, activeUserId); } if (["edit", "partial-edit"].includes(config.mode) && config.originalCipher?.id) { @@ -371,7 +380,8 @@ export class AddEditV2Component implements OnInit { } try { - await this.deleteCipher(); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + await this.deleteCipher(activeUserId); } catch (e) { this.logService.error(e); return false; @@ -388,10 +398,10 @@ export class AddEditV2Component implements OnInit { return true; }; - protected deleteCipher() { + protected deleteCipher(userId: UserId) { return this.config.originalCipher.deletedDate - ? this.cipherService.deleteWithServer(this.config.originalCipher.id) - : this.cipherService.softDeleteWithServer(this.config.originalCipher.id); + ? this.cipherService.deleteWithServer(this.config.originalCipher.id, userId) + : this.cipherService.softDeleteWithServer(this.config.originalCipher.id, userId); } } 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 51ebe9bdb62..27f3b7e5e18 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 @@ -5,12 +5,13 @@ import { Component } from "@angular/core"; import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; import { ReactiveFormsModule } from "@angular/forms"; import { ActivatedRoute } from "@angular/router"; -import { Observable, combineLatest, first, map, switchMap } from "rxjs"; +import { Observable, combineLatest, filter, first, map, switchMap } from "rxjs"; 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 { @@ -58,16 +59,19 @@ export class AssignCollections { private accountService: AccountService, route: ActivatedRoute, ) { - const cipher$: Observable = route.queryParams.pipe( - switchMap(({ cipherId }) => this.cipherService.get(cipherId)), - switchMap((cipherDomain) => - this.accountService.activeAccount$.pipe( - map((account) => account?.id), - switchMap((userId) => - this.cipherService - .getKeyForCipherKeyDecryption(cipherDomain, userId) - .then(cipherDomain.decrypt.bind(cipherDomain)), - ), + const cipher$: Observable = this.accountService.activeAccount$.pipe( + map((account) => account?.id), + filter((userId) => userId != null), + switchMap((userId) => + 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); + }), ), ), ); 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 aca494716b1..1bc7e22e6d5 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 @@ -77,10 +77,10 @@ export class OpenAttachmentsComponent implements OnInit { return; } - const cipherDomain = await this.cipherService.get(this.cipherId); const activeUserId = await firstValueFrom( 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), ); diff --git a/apps/browser/src/vault/popup/components/vault-v2/autofill-vault-list-items/autofill-vault-list-items.component.html b/apps/browser/src/vault/popup/components/vault-v2/autofill-vault-list-items/autofill-vault-list-items.component.html index eae8e2cc980..071873b40c9 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/autofill-vault-list-items/autofill-vault-list-items.component.html +++ b/apps/browser/src/vault/popup/components/vault-v2/autofill-vault-list-items/autofill-vault-list-items.component.html @@ -7,4 +7,5 @@ [description]="(showEmptyAutofillTip$ | async) ? ('autofillSuggestionsTip' | i18n) : null" showAutofillButton [primaryActionAutofill]="clickItemsToAutofillVaultView" + [groupByType]="groupByType()" > 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 d2dd21be6d8..03d84120785 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 @@ -1,5 +1,6 @@ import { CommonModule } from "@angular/common"; import { Component, OnInit } from "@angular/core"; +import { toSignal } from "@angular/core/rxjs-interop"; import { combineLatest, firstValueFrom, map, Observable } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; @@ -48,6 +49,10 @@ export class AutofillVaultListItemsComponent implements OnInit { clickItemsToAutofillVaultView = false; + protected groupByType = toSignal( + this.vaultPopupItemsService.hasFilterApplied$.pipe(map((hasFilter) => !hasFilter)), + ); + /** * Observable that determines whether the empty autofill tip should be shown. * The tip is shown when there are no login ciphers to autofill, no filter is applied, and autofill is allowed in diff --git a/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.html b/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.html index 4c7067df53a..6e6e30b359b 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.html +++ b/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.html @@ -27,7 +27,7 @@ - + {{ "clone" | i18n }} diff --git a/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.ts b/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.ts index 8634d680052..94b4c2b855b 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.ts @@ -97,6 +97,9 @@ export class ItemMoreOptionsComponent implements OnInit { return this.cipher.edit; } + get canViewPassword() { + return this.cipher.viewPassword; + } /** * Determines if the cipher can be autofilled. */ 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 d57b1d2fe36..db3fff04bbb 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 @@ -11,11 +11,11 @@ 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"; +import { AddEditFolderDialogComponent } from "@bitwarden/vault"; import { BrowserApi } from "../../../../../platform/browser/browser-api"; import BrowserPopupUtils from "../../../../../platform/popup/browser-popup-utils"; import { AddEditQueryParams } from "../add-edit/add-edit-v2.component"; -import { AddEditFolderDialogComponent } from "../add-edit-folder-dialog/add-edit-folder-dialog.component"; export interface NewItemInitialValues { folderId?: string; @@ -72,6 +72,6 @@ export class NewItemDropdownV2Component implements OnInit { } openFolderDialog() { - this.dialogService.open(AddEditFolderDialogComponent); + AddEditFolderDialogComponent.open(this.dialogService); } } diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-header/vault-header-v2.component.spec.ts b/apps/browser/src/vault/popup/components/vault-v2/vault-header/vault-header-v2.component.spec.ts index 1f67dd51c21..fb5ac4b3391 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/vault-header/vault-header-v2.component.spec.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/vault-header/vault-header-v2.component.spec.ts @@ -59,7 +59,9 @@ describe("VaultHeaderV2Component", () => { providers: [ { provide: CipherService, - useValue: mock({ cipherViews$: new BehaviorSubject([]) }), + useValue: mock({ + cipherViews$: jest.fn().mockReturnValue(new BehaviorSubject([])), + }), }, { provide: VaultSettingsService, useValue: mock() }, { provide: FolderService, useValue: mock() }, 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 3b9dc9a1647..bcea2e76190 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 @@ -6,11 +6,12 @@ import { combineLatest, map, take } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { DisclosureTriggerForDirective, IconButtonModule } from "@bitwarden/components"; +import { + DisclosureComponent, + DisclosureTriggerForDirective, + IconButtonModule, +} from "@bitwarden/components"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { DisclosureComponent } from "../../../../../../../../libs/components/src/disclosure/disclosure.component"; import { runInsideAngular } from "../../../../../platform/browser/run-inside-angular.operator"; import { VaultPopupListFiltersService } from "../../../../../vault/popup/services/vault-popup-list-filters.service"; import { VaultListFiltersComponent } from "../vault-list-filters/vault-list-filters.component"; diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-list-items-container/vault-list-items-container.component.html b/apps/browser/src/vault/popup/components/vault-v2/vault-list-items-container/vault-list-items-container.component.html index 1593c747f7d..2272d3fbd6c 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/vault-list-items-container/vault-list-items-container.component.html +++ b/apps/browser/src/vault/popup/components/vault-v2/vault-list-items-container/vault-list-items-container.component.html @@ -1,9 +1,13 @@ - + - - - - - - - - - - - - + + +

+ {{ group.subHeaderKey | i18n }} +

+
+ + + + + + + + + + + + + + + + + +
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 725aaac4666..cb758e7a48d 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 @@ -9,20 +9,26 @@ import { EventEmitter, inject, Input, - OnInit, Output, Signal, signal, ViewChild, + computed, + OnInit, + ChangeDetectionStrategy, + input, } from "@angular/core"; import { Router } from "@angular/router"; import { firstValueFrom, Observable, map } 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 { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { CipherId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; +import { CipherType } from "@bitwarden/common/vault/enums"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { BadgeModule, @@ -73,6 +79,7 @@ import { ItemMoreOptionsComponent } from "../item-more-options/item-more-options selector: "app-vault-list-items-container", templateUrl: "vault-list-items-container.component.html", standalone: true, + changeDetection: ChangeDetectionStrategy.OnPush, }) export class VaultListItemsContainerComponent implements OnInit, AfterViewInit { private compactModeService = inject(CompactModeService); @@ -110,11 +117,51 @@ export class VaultListItemsContainerComponent implements OnInit, AfterViewInit { */ private viewCipherTimeout: number | null; + ciphers = input([]); + /** - * The list of ciphers to display. + * If true, we will group ciphers by type (Login, Card, Identity) + * within subheadings in a single container, converted to a WritableSignal. */ - @Input() - ciphers: PopupCipherView[] = []; + groupByType = input(false); + + /** + * Computed signal for a grouped list of ciphers with an optional header + */ + cipherGroups$ = computed< + { + subHeaderKey?: string | null; + ciphers: PopupCipherView[]; + }[] + >(() => { + const groups: { [key: string]: CipherView[] } = {}; + + this.ciphers().forEach((cipher) => { + let groupKey; + + if (this.groupByType()) { + switch (cipher.type) { + case CipherType.Card: + groupKey = "cards"; + break; + case CipherType.Identity: + groupKey = "identities"; + break; + } + } + + if (!groups[groupKey]) { + groups[groupKey] = []; + } + + groups[groupKey].push(cipher); + }); + + return Object.keys(groups).map((key) => ({ + subHeaderKey: this.groupByType ? key : "", + ciphers: groups[key], + })); + }); /** * Title for the vault list item section. @@ -220,6 +267,7 @@ export class VaultListItemsContainerComponent implements OnInit, AfterViewInit { private router: Router, private platformUtilsService: PlatformUtilsService, private dialogService: DialogService, + private accountService: AccountService, ) {} ngOnInit(): void { @@ -266,7 +314,8 @@ export class VaultListItemsContainerComponent implements OnInit, AfterViewInit { this.viewCipherTimeout = null; } - await this.cipherService.updateLastLaunchedDate(cipher.id); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + await this.cipherService.updateLastLaunchedDate(cipher.id, activeUserId); await BrowserApi.createNewTab(cipher.login.launchUri); diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-password-history-v2/vault-password-history-v2.component.spec.ts b/apps/browser/src/vault/popup/components/vault-v2/vault-password-history-v2/vault-password-history-v2.component.spec.ts index 9ac17b49386..838ce2e9426 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/vault-password-history-v2/vault-password-history-v2.component.spec.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/vault-password-history-v2/vault-password-history-v2.component.spec.ts @@ -1,13 +1,15 @@ import { ComponentFixture, fakeAsync, TestBed, tick } from "@angular/core/testing"; import { ActivatedRoute } from "@angular/router"; import { mock } from "jest-mock-extended"; -import { BehaviorSubject, Subject } from "rxjs"; +import { Subject } from "rxjs"; import { WINDOW } from "@bitwarden/angular/services/injection-tokens"; -import { Account, AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { mockAccountServiceWith } from "@bitwarden/common/spec"; +import { UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { Cipher } from "@bitwarden/common/vault/models/domain/cipher"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; @@ -19,6 +21,7 @@ import { PasswordHistoryV2Component } from "./vault-password-history-v2.componen describe("PasswordHistoryV2Component", () => { let fixture: ComponentFixture; const params$ = new Subject(); + const mockUserId = "acct-1" as UserId; const mockCipherView = { id: "111-222-333", @@ -45,9 +48,7 @@ describe("PasswordHistoryV2Component", () => { { provide: CipherService, useValue: mock({ get: getCipher }) }, { provide: AccountService, - useValue: mock({ - activeAccount$: new BehaviorSubject({ id: "acct-1" } as Account), - }), + useValue: mockAccountServiceWith(mockUserId), }, { provide: PopupRouterCacheService, useValue: { back } }, { provide: ActivatedRoute, useValue: { queryParams: params$ } }, @@ -64,7 +65,7 @@ describe("PasswordHistoryV2Component", () => { tick(100); - expect(getCipher).toHaveBeenCalledWith(mockCipherView.id); + expect(getCipher).toHaveBeenCalledWith(mockCipherView.id, mockUserId); })); it("navigates back when a cipherId is not in the params", () => { 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 67e069d388a..5d315775b10 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 @@ -11,10 +11,8 @@ import { AccountService } from "@bitwarden/common/auth/abstractions/account.serv import { UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; +import { PasswordHistoryViewComponent } from "@bitwarden/vault"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { PasswordHistoryViewComponent } from "../../../../../../../../libs/vault/src/components/password-history-view/password-history-view.component"; import { PopOutComponent } from "../../../../../platform/popup/components/pop-out.component"; import { PopupHeaderComponent } from "../../../../../platform/popup/layout/popup-header.component"; import { PopupPageComponent } from "../../../../../platform/popup/layout/popup-page.component"; @@ -60,8 +58,6 @@ export class PasswordHistoryV2Component implements OnInit { /** Load the cipher based on the given Id */ private async loadCipher(cipherId: string) { - const cipher = await this.cipherService.get(cipherId); - const activeAccount = await firstValueFrom( this.accountService.activeAccount$.pipe(map((a: { id: string | undefined }) => a)), ); @@ -71,6 +67,8 @@ 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), ); 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 43471e56e7b..8cb538a429a 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 @@ -32,6 +32,9 @@ slot="above-scroll-area" *ngIf="vaultState !== VaultStateEnum.Empty && !(loading$ | async)" > +
@@ -69,13 +72,13 @@ ciphers.filter((c) => !c.isDeleted)), filter((ciphers) => ciphers.length > 0), @@ -153,4 +178,6 @@ export class VaultV2Component implements OnInit, AfterViewInit, OnDestroy { ngOnDestroy(): void { this.vaultScrollPositionService.stop(); } + + 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 39feb86f4fd..17464c025af 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 @@ -150,7 +150,7 @@ describe("ViewV2Component", () => { flush(); // Resolve all promises - expect(mockCipherService.get).toHaveBeenCalledWith("122-333-444"); + expect(mockCipherService.get).toHaveBeenCalledWith("122-333-444", mockUserId); expect(component.cipher).toEqual(mockCipher); })); 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 378d3251e11..209691869f0 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 @@ -5,13 +5,14 @@ import { Component } from "@angular/core"; import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; import { FormsModule } from "@angular/forms"; import { ActivatedRoute, Router } from "@angular/router"; -import { firstValueFrom, map, Observable, switchMap } from "rxjs"; +import { firstValueFrom, Observable, switchMap } from "rxjs"; import { CollectionView } from "@bitwarden/admin-console/common"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { AUTOFILL_ID, COPY_PASSWORD_ID, @@ -22,7 +23,9 @@ import { 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 { UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; +import { PremiumUpgradePromptService } from "@bitwarden/common/vault/abstractions/premium-upgrade-prompt.service"; import { ViewPasswordHistoryService } from "@bitwarden/common/vault/abstractions/view-password-history.service"; import { CipherType } from "@bitwarden/common/vault/enums"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; @@ -35,14 +38,8 @@ import { SearchModule, ToastService, } from "@bitwarden/components"; -import { CopyCipherFieldService } from "@bitwarden/vault"; +import { CipherViewComponent, CopyCipherFieldService } from "@bitwarden/vault"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { PremiumUpgradePromptService } from "../../../../../../../../libs/common/src/vault/abstractions/premium-upgrade-prompt.service"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { CipherViewComponent } from "../../../../../../../../libs/vault/src/cipher-view"; import { BrowserApi } from "../../../../../platform/browser/browser-api"; import BrowserPopupUtils from "../../../../../platform/popup/browser-popup-utils"; import { PopOutComponent } from "../../../../../platform/popup/components/pop-out.component"; @@ -92,6 +89,8 @@ type LoadAction = ], }) export class ViewV2Component { + private activeUserId: UserId; + headerText: string; cipher: CipherView; organization$: Observable; @@ -122,14 +121,20 @@ export class ViewV2Component { subscribeToParams(): void { this.route.queryParams .pipe( - switchMap(async (params): Promise => { + switchMap(async (params) => { this.loadAction = params.action; this.senderTabId = params.senderTabId ? parseInt(params.senderTabId, 10) : undefined; - return await this.getCipherData(params.cipherId); + + const activeUserId = await firstValueFrom( + this.accountService.activeAccount$.pipe(getUserId), + ); + const cipher = await this.getCipherData(params.cipherId, activeUserId); + return { activeUserId, cipher }; }), - switchMap(async (cipher) => { + switchMap(async ({ activeUserId, cipher }) => { this.cipher = cipher; this.headerText = this.setHeader(cipher.type); + this.activeUserId = activeUserId; if (this.loadAction) { await this._handleLoadAction(this.loadAction, this.senderTabId); @@ -164,13 +169,10 @@ export class ViewV2Component { } } - async getCipherData(id: string) { - const cipher = await this.cipherService.get(id); - const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), - ); + async getCipherData(id: string, userId: UserId) { + const cipher = await this.cipherService.get(id, userId); return await cipher.decrypt( - await this.cipherService.getKeyForCipherKeyDecryption(cipher, activeUserId), + await this.cipherService.getKeyForCipherKeyDecryption(cipher, userId), ); } @@ -218,7 +220,7 @@ export class ViewV2Component { restore = async (): Promise => { try { - await this.cipherService.restoreWithServer(this.cipher.id); + await this.cipherService.restoreWithServer(this.cipher.id, this.activeUserId); } catch (e) { this.logService.error(e); } @@ -233,8 +235,8 @@ export class ViewV2Component { protected deleteCipher() { return this.cipher.isDeleted - ? this.cipherService.deleteWithServer(this.cipher.id) - : this.cipherService.softDeleteWithServer(this.cipher.id); + ? this.cipherService.deleteWithServer(this.cipher.id, this.activeUserId) + : this.cipherService.softDeleteWithServer(this.cipher.id, this.activeUserId); } protected showFooter(): boolean { 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 2dad1e3034c..75352c1331a 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 @@ -21,14 +21,12 @@ import { LoginView } from "@bitwarden/common/vault/models/view/login.view"; import { ToastService } from "@bitwarden/components"; import { PasswordRepromptService } from "@bitwarden/vault"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { InlineMenuFieldQualificationService } from "../../../../../browser/src/autofill/services/inline-menu-field-qualification.service"; import { AutoFillOptions, AutofillService, PageDetail, } from "../../../autofill/services/abstractions/autofill.service"; +import { InlineMenuFieldQualificationService } from "../../../autofill/services/inline-menu-field-qualification.service"; import { BrowserApi } from "../../../platform/browser/browser-api"; import BrowserPopupUtils from "../../../platform/popup/browser-popup-utils"; diff --git a/apps/browser/src/vault/popup/services/vault-popup-autofill.service.ts b/apps/browser/src/vault/popup/services/vault-popup-autofill.service.ts index ff282d7a6d0..82188ef823b 100644 --- a/apps/browser/src/vault/popup/services/vault-popup-autofill.service.ts +++ b/apps/browser/src/vault/popup/services/vault-popup-autofill.service.ts @@ -27,13 +27,11 @@ import { LoginUriView } from "@bitwarden/common/vault/models/view/login-uri.view import { ToastService } from "@bitwarden/components"; import { PasswordRepromptService } from "@bitwarden/vault"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { InlineMenuFieldQualificationService } from "../../../../../browser/src/autofill/services/inline-menu-field-qualification.service"; import { AutofillService, PageDetail, } from "../../../autofill/services/abstractions/autofill.service"; +import { InlineMenuFieldQualificationService } from "../../../autofill/services/inline-menu-field-qualification.service"; import { BrowserApi } from "../../../platform/browser/browser-api"; import BrowserPopupUtils from "../../../platform/popup/browser-popup-utils"; import { closeViewVaultItemPopout, VaultPopoutType } from "../utils/vault-popout-window"; 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 7b241a6c108..6d7b7b57d23 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 @@ -15,11 +15,11 @@ import { CipherId, UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { VaultSettingsService } from "@bitwarden/common/vault/abstractions/vault-settings/vault-settings.service"; import { CipherType } from "@bitwarden/common/vault/enums"; +import { CipherData } from "@bitwarden/common/vault/models/data/cipher.data"; +import { LocalData } from "@bitwarden/common/vault/models/data/local.data"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { InlineMenuFieldQualificationService } from "../../../../../browser/src/autofill/services/inline-menu-field-qualification.service"; +import { InlineMenuFieldQualificationService } from "../../../autofill/services/inline-menu-field-qualification.service"; import { BrowserApi } from "../../../platform/browser/browser-api"; import { VaultPopupAutofillService } from "./vault-popup-autofill.service"; @@ -36,6 +36,10 @@ describe("VaultPopupItemsService", () => { let mockCollections: CollectionView[]; let activeUserLastSync$: BehaviorSubject; + let ciphersSubject: BehaviorSubject>; + let localDataSubject: BehaviorSubject>; + let failedToDecryptCiphersSubject: BehaviorSubject; + const cipherServiceMock = mock(); const vaultSettingsServiceMock = mock(); const organizationServiceMock = mock(); @@ -62,9 +66,21 @@ describe("VaultPopupItemsService", () => { cipherList[3].favorite = true; cipherServiceMock.getAllDecrypted.mockResolvedValue(cipherList); - cipherServiceMock.ciphers$ = new BehaviorSubject(null); - cipherServiceMock.localData$ = new BehaviorSubject(null); - cipherServiceMock.failedToDecryptCiphers$ = new BehaviorSubject([]); + + ciphersSubject = new BehaviorSubject>({}); + localDataSubject = new BehaviorSubject>({}); + failedToDecryptCiphersSubject = new BehaviorSubject([]); + + cipherServiceMock.ciphers$.mockImplementation((userId: UserId) => + ciphersSubject.asObservable(), + ); + cipherServiceMock.localData$.mockImplementation((userId: UserId) => + localDataSubject.asObservable(), + ); + cipherServiceMock.failedToDecryptCiphers$.mockImplementation((userId: UserId) => + failedToDecryptCiphersSubject.asObservable(), + ); + searchService.searchCiphers.mockImplementation(async (_, __, ciphers) => ciphers); cipherServiceMock.filterCiphersForUrl.mockImplementation(async (ciphers) => ciphers.filter((c) => ["0", "1"].includes(c.id)), @@ -120,6 +136,7 @@ describe("VaultPopupItemsService", () => { { provide: CollectionService, useValue: collectionService }, { provide: VaultPopupAutofillService, useValue: vaultAutofillServiceMock }, { provide: SyncService, useValue: syncServiceMock }, + { provide: AccountService, useValue: mockAccountServiceWith("UserId" as UserId) }, { provide: InlineMenuFieldQualificationService, useValue: inlineMenuFieldQualificationServiceMock, @@ -157,7 +174,7 @@ describe("VaultPopupItemsService", () => { await tracker.expectEmission(); - (cipherServiceMock.ciphers$ as BehaviorSubject).next(null); + ciphersSubject.next({}); await tracker.expectEmission(); @@ -171,7 +188,7 @@ describe("VaultPopupItemsService", () => { await tracker.expectEmission(); - (cipherServiceMock.localData$ as BehaviorSubject).next(null); + localDataSubject.next({}); await tracker.expectEmission(); @@ -375,7 +392,7 @@ describe("VaultPopupItemsService", () => { cipherServiceMock.getAllDecrypted.mockResolvedValue(ciphers); - (cipherServiceMock.ciphers$ as BehaviorSubject).next(null); + ciphersSubject.next({}); const deletedCiphers = await firstValueFrom(service.deletedCiphers$); expect(deletedCiphers.length).toBe(1); @@ -424,7 +441,7 @@ describe("VaultPopupItemsService", () => { it("should cycle when cipherService.ciphers$ emits", async () => { // Restart tracking tracked = new ObservableTracker(service.loading$); - (cipherServiceMock.ciphers$ as BehaviorSubject).next(null); + ciphersSubject.next({}); await trackedCiphers.pauseUntilReceived(2); diff --git a/apps/browser/src/vault/popup/services/vault-popup-items.service.ts b/apps/browser/src/vault/popup/services/vault-popup-items.service.ts index 519b8e6867f..0b3e7eba492 100644 --- a/apps/browser/src/vault/popup/services/vault-popup-items.service.ts +++ b/apps/browser/src/vault/popup/services/vault-popup-items.service.ts @@ -1,6 +1,6 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { inject, Injectable, NgZone } from "@angular/core"; +import { Injectable, NgZone } from "@angular/core"; import { BehaviorSubject, combineLatest, @@ -86,16 +86,19 @@ export class VaultPopupItemsService { * Observable that contains the list of all decrypted ciphers. * @private */ - private _allDecryptedCiphers$: Observable = merge( - this.cipherService.ciphers$, - this.cipherService.localData$, - ).pipe( - runInsideAngular(inject(NgZone)), // Workaround to ensure cipher$ state provider emissions are run inside Angular - tap(() => this._ciphersLoading$.next()), - waitUntilSync(this.syncService), - switchMap(() => Utils.asyncToObservable(() => this.cipherService.getAllDecrypted())), - withLatestFrom(this.cipherService.failedToDecryptCiphers$), - map(([ciphers, failedToDecryptCiphers]) => [...failedToDecryptCiphers, ...ciphers]), + private _allDecryptedCiphers$: Observable = this.accountService.activeAccount$.pipe( + map((a) => a?.id), + filter((userId) => userId != null), + switchMap((userId) => + merge(this.cipherService.ciphers$(userId), this.cipherService.localData$(userId)).pipe( + runInsideAngular(this.ngZone), + tap(() => this._ciphersLoading$.next()), + waitUntilSync(this.syncService), + switchMap(() => Utils.asyncToObservable(() => this.cipherService.getAllDecrypted(userId))), + withLatestFrom(this.cipherService.failedToDecryptCiphers$(userId)), + map(([ciphers, failedToDecryptCiphers]) => [...failedToDecryptCiphers, ...ciphers]), + ), + ), shareReplay({ refCount: true, bufferSize: 1 }), ); @@ -214,6 +217,7 @@ export class VaultPopupItemsService { map(([hasSearchText, filters]) => { return hasSearchText || Object.values(filters).some((filter) => filter !== null); }), + shareReplay({ bufferSize: 1, refCount: true }), ); /** @@ -280,6 +284,7 @@ export class VaultPopupItemsService { private vaultPopupAutofillService: VaultPopupAutofillService, private syncService: SyncService, private accountService: AccountService, + private ngZone: NgZone, ) {} applyFilter(newSearchText: string) { 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 7f570e8f5c9..ec823d5738f 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 @@ -41,7 +41,7 @@ describe("VaultPopupListFiltersService", () => { } as unknown as FolderService; const cipherService = { - cipherViews$, + cipherViews$: () => cipherViews$, } as unknown as CipherService; const organizationService = { 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 579319c92ab..b1451318499 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 @@ -93,16 +93,6 @@ export class VaultPopupListFiltersService { */ private cipherViews: CipherView[] = []; - /** - * Observable of cipher views - */ - private cipherViews$: Observable = this.cipherService.cipherViews$.pipe( - tap((cipherViews) => { - this.cipherViews = Object.values(cipherViews); - }), - map((ciphers) => Object.values(ciphers)), - ); - private activeUserId$ = this.accountService.activeAccount$.pipe(map((a) => a?.id)); constructor( @@ -271,8 +261,16 @@ export class VaultPopupListFiltersService { * Folder array structured to be directly passed to `ChipSelectComponent` */ folders$: Observable[]> = this.activeUserId$.pipe( - switchMap((userId) => - combineLatest([ + switchMap((userId) => { + // Observable of cipher views + const cipherViews$ = this.cipherService.cipherViews$(userId).pipe( + tap((cipherViews) => { + this.cipherViews = Object.values(cipherViews); + }), + map((ciphers) => Object.values(ciphers)), + ); + + return combineLatest([ this.filters$.pipe( distinctUntilChanged( (previousFilter, currentFilter) => @@ -281,7 +279,7 @@ export class VaultPopupListFiltersService { ), ), this.folderService.folderViews$(userId), - this.cipherViews$, + cipherViews$, ]).pipe( map(([filters, folders, cipherViews]): [PopupListFilter, FolderView[], CipherView[]] => { if (folders.length === 1 && folders[0].id === null) { @@ -330,8 +328,8 @@ export class VaultPopupListFiltersService { map((folders) => folders.nestedList.map((f) => this.convertToChipSelectOption(f, "bwi-folder")), ), - ), - ), + ); + }), ); /** 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 3aab9f935e4..deddbd444fc 100644 --- a/apps/browser/src/vault/popup/settings/appearance-v2.component.ts +++ b/apps/browser/src/vault/popup/settings/appearance-v2.component.ts @@ -14,17 +14,15 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { ThemeType } from "@bitwarden/common/platform/enums"; import { ThemeStateService } from "@bitwarden/common/platform/theming/theme-state.service"; -import { BadgeModule, CheckboxModule, Option } from "@bitwarden/components"; +import { + BadgeModule, + CardComponent, + CheckboxModule, + FormFieldModule, + Option, + SelectModule, +} from "@bitwarden/components"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { CardComponent } from "../../../../../../libs/components/src/card/card.component"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { FormFieldModule } from "../../../../../../libs/components/src/form-field/form-field.module"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { SelectModule } from "../../../../../../libs/components/src/select/select.module"; import { PopOutComponent } from "../../../platform/popup/components/pop-out.component"; import { PopupCompactModeService } from "../../../platform/popup/layout/popup-compact-mode.service"; import { PopupHeaderComponent } from "../../../platform/popup/layout/popup-header.component"; 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 9c202e26fef..6689f5a6c6d 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 @@ -14,10 +14,10 @@ import { UserId } from "@bitwarden/common/types/guid"; import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; import { FolderView } from "@bitwarden/common/vault/models/view/folder.view"; import { DialogService } from "@bitwarden/components"; +import { AddEditFolderDialogComponent } from "@bitwarden/vault"; import { PopupFooterComponent } from "../../../platform/popup/layout/popup-footer.component"; import { PopupHeaderComponent } from "../../../platform/popup/layout/popup-header.component"; -import { AddEditFolderDialogComponent } from "../components/vault-v2/add-edit-folder-dialog/add-edit-folder-dialog.component"; import { FoldersV2Component } from "./folders-v2.component"; @@ -27,8 +27,8 @@ import { FoldersV2Component } from "./folders-v2.component"; template: ``, }) class MockPopupHeaderComponent { - @Input() pageTitle: string; - @Input() backAction: () => void; + @Input() pageTitle: string = ""; + @Input() backAction: () => void = () => {}; } @Component({ @@ -37,14 +37,15 @@ class MockPopupHeaderComponent { template: ``, }) class MockPopupFooterComponent { - @Input() pageTitle: string; + @Input() pageTitle: string = ""; } describe("FoldersV2Component", () => { let component: FoldersV2Component; let fixture: ComponentFixture; const folderViews$ = new BehaviorSubject([]); - const open = jest.fn(); + const open = jest.spyOn(AddEditFolderDialogComponent, "open"); + const mockDialogService = { open: jest.fn() }; beforeEach(async () => { open.mockClear(); @@ -68,7 +69,7 @@ describe("FoldersV2Component", () => { imports: [MockPopupHeaderComponent, MockPopupFooterComponent], }, }) - .overrideProvider(DialogService, { useValue: { open } }) + .overrideProvider(DialogService, { useValue: mockDialogService }) .compileComponents(); fixture = TestBed.createComponent(FoldersV2Component); @@ -101,9 +102,7 @@ describe("FoldersV2Component", () => { editButton.triggerEventHandler("click"); - expect(open).toHaveBeenCalledWith(AddEditFolderDialogComponent, { - data: { editFolderConfig: { folder } }, - }); + expect(open).toHaveBeenCalledWith(mockDialogService, { editFolderConfig: { folder } }); }); it("opens add dialog for new folder when there are no folders", () => { @@ -114,6 +113,6 @@ describe("FoldersV2Component", () => { addButton.triggerEventHandler("click"); - expect(open).toHaveBeenCalledWith(AddEditFolderDialogComponent, { data: {} }); + expect(open).toHaveBeenCalledWith(mockDialogService, {}); }); }); 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 8abc3f906c0..f71374e5305 100644 --- a/apps/browser/src/vault/popup/settings/folders-v2.component.ts +++ b/apps/browser/src/vault/popup/settings/folders-v2.component.ts @@ -12,25 +12,14 @@ import { ButtonModule, DialogService, IconButtonModule, + ItemModule, + NoItemsModule, } from "@bitwarden/components"; -import { VaultIcons } from "@bitwarden/vault"; +import { AddEditFolderDialogComponent, VaultIcons } from "@bitwarden/vault"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { ItemGroupComponent } from "../../../../../../libs/components/src/item/item-group.component"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { ItemModule } from "../../../../../../libs/components/src/item/item.module"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { NoItemsModule } from "../../../../../../libs/components/src/no-items/no-items.module"; 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 { - AddEditFolderDialogComponent, - AddEditFolderDialogData, -} from "../components/vault-v2/add-edit-folder-dialog/add-edit-folder-dialog.component"; @Component({ standalone: true, @@ -42,7 +31,6 @@ import { PopupPageComponent, PopupHeaderComponent, ItemModule, - ItemGroupComponent, NoItemsModule, IconButtonModule, ButtonModule, @@ -78,8 +66,6 @@ export class FoldersV2Component { // If a folder is provided, the edit variant should be shown const editFolderConfig = folder ? { folder } : undefined; - this.dialogService.open(AddEditFolderDialogComponent, { - data: { editFolderConfig }, - }); + AddEditFolderDialogComponent.open(this.dialogService, { editFolderConfig }); } } 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 c56d1c7d10d..7e30ab26035 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 @@ -3,8 +3,11 @@ import { CommonModule } from "@angular/common"; import { ChangeDetectionStrategy, Component, Input } from "@angular/core"; import { Router } from "@angular/router"; +import { firstValueFrom } 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 { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { CipherId } from "@bitwarden/common/types/guid"; @@ -65,6 +68,7 @@ export class TrashListItemsContainerComponent { private i18nService: I18nService, private dialogService: DialogService, private passwordRepromptService: PasswordRepromptService, + private accountService: AccountService, private router: Router, ) {} @@ -81,7 +85,8 @@ export class TrashListItemsContainerComponent { async restore(cipher: CipherView) { try { - await this.cipherService.restoreWithServer(cipher.id); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + await this.cipherService.restoreWithServer(cipher.id, activeUserId); await this.router.navigate(["/trash"]); this.toastService.showToast({ @@ -112,7 +117,8 @@ export class TrashListItemsContainerComponent { } try { - await this.cipherService.deleteWithServer(cipher.id); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + await this.cipherService.deleteWithServer(cipher.id, activeUserId); await this.router.navigate(["/trash"]); this.toastService.showToast({ diff --git a/apps/browser/store/locales/he/copy.resx b/apps/browser/store/locales/he/copy.resx index 7f366f0e931..383f0512cb4 100644 --- a/apps/browser/store/locales/he/copy.resx +++ b/apps/browser/store/locales/he/copy.resx @@ -118,10 +118,10 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Bitwarden Password Manager + מנהל הסיסמאות Bitwarden - At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information. + בבית, בעבודה, או בדרך, Bitwarden מאבטח בקלות את כל הסיסמאות, מפתחות הגישה, והמידע הרגיש שלך. Recognized as the best password manager by PCMag, WIRED, The Verge, CNET, G2, and more! @@ -169,7 +169,7 @@ End-to-end encrypted credential management solutions from Bitwarden empower orga - At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information. + בבית, בעבודה, או בדרך, Bitwarden מאבטח בקלות את כל הסיסמאות, מפתחות הגישה, והמידע הרגיש שלך. סנכרון וגישה לכספת שלך ממגוון מכשירים diff --git a/apps/browser/store/locales/pt_PT/copy.resx b/apps/browser/store/locales/pt_PT/copy.resx index 65b81e2d2d4..fa62a0f1d5c 100644 --- a/apps/browser/store/locales/pt_PT/copy.resx +++ b/apps/browser/store/locales/pt_PT/copy.resx @@ -175,7 +175,7 @@ As soluções de gestão de credenciais encriptadas ponto a ponto do Bitwarden p Sincronize e aceda ao seu cofre através de vários dispositivos - Gira todas as suas credenciais e palavras-passe a partir de um cofre seguro + Faça a gestão de todas as suas credenciais e palavras-passe a partir de um cofre seguro Preencha rapidamente e de forma automática as suas credenciais de início de sessão em qualquer site que visite diff --git a/apps/browser/tsconfig.json b/apps/browser/tsconfig.json index 3eaa7e100a6..8055260db57 100644 --- a/apps/browser/tsconfig.json +++ b/apps/browser/tsconfig.json @@ -24,8 +24,8 @@ "@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/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"], @@ -51,8 +51,8 @@ }, "include": [ "src", - "../../libs/common/src/platform/services/**/*.worker.ts", "../../libs/common/src/autofill/constants", - "../../libs/common/custom-matchers.d.ts" + "../../libs/common/custom-matchers.d.ts", + "../../libs/common/src/key-management/crypto/services/encrypt.worker.ts" ] } diff --git a/apps/browser/webpack.config.js b/apps/browser/webpack.config.js index bce41d64d1f..b6e8a147a50 100644 --- a/apps/browser/webpack.config.js +++ b/apps/browser/webpack.config.js @@ -205,7 +205,7 @@ const mainConfig = { "./src/autofill/deprecated/overlay/pages/button/bootstrap-autofill-overlay-button.deprecated.ts", "overlay/list": "./src/autofill/deprecated/overlay/pages/list/bootstrap-autofill-overlay-list.deprecated.ts", - "encrypt-worker": "../../libs/common/src/platform/services/cryptography/encrypt.worker.ts", + "encrypt-worker": "../../libs/common/src/key-management/crypto/services/encrypt.worker.ts", "content/send-on-installed-message": "./src/vault/content/send-on-installed-message.ts", }, optimization: { @@ -317,19 +317,21 @@ if (manifestVersion == 2) { configs.push(mainConfig); } else { - // Manifest v3 needs an extra helper for utilities in the content script. - // The javascript output of this should be added to manifest.v3.json - mainConfig.entry["content/misc-utils"] = "./src/autofill/content/misc-utils.ts"; - mainConfig.entry["offscreen-document/offscreen-document"] = - "./src/platform/offscreen-document/offscreen-document.ts"; + // Firefox does not use the offscreen API + if (browser !== "firefox") { + mainConfig.entry["offscreen-document/offscreen-document"] = + "./src/platform/offscreen-document/offscreen-document.ts"; - mainConfig.plugins.push( - new HtmlWebpackPlugin({ - template: "./src/platform/offscreen-document/index.html", - filename: "offscreen-document/index.html", - chunks: ["offscreen-document/offscreen-document"], - }), - ); + mainConfig.plugins.push( + new HtmlWebpackPlugin({ + template: "./src/platform/offscreen-document/index.html", + filename: "offscreen-document/index.html", + chunks: ["offscreen-document/offscreen-document"], + }), + ); + } + + const target = browser === "firefox" ? "web" : "webworker"; /** * @type {import("webpack").Configuration} @@ -339,7 +341,7 @@ if (manifestVersion == 2) { mode: ENV, devtool: false, entry: "./src/platform/background.ts", - target: "webworker", + target: target, output: { filename: "background.js", path: path.resolve(__dirname, "build"), diff --git a/apps/cli/package.json b/apps/cli/package.json index 391c9c80808..138405d1175 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.1.3", + "version": "2025.2.0", "keywords": [ "bitwarden", "password", @@ -66,7 +66,7 @@ "form-data": "4.0.1", "https-proxy-agent": "7.0.5", "inquirer": "8.2.6", - "jsdom": "25.0.1", + "jsdom": "26.0.0", "jszip": "3.10.1", "koa": "2.15.3", "koa-bodyparser": "4.4.1", @@ -77,7 +77,7 @@ "node-fetch": "2.6.12", "node-forge": "1.3.1", "open": "8.4.2", - "papaparse": "5.4.1", + "papaparse": "5.5.2", "proper-lockfile": "4.1.2", "rxjs": "7.8.1", "tldts": "6.1.74", diff --git a/apps/cli/src/admin-console/commands/confirm.command.ts b/apps/cli/src/admin-console/commands/confirm.command.ts index 5f5f58163e3..0d5c7ba069c 100644 --- a/apps/cli/src/admin-console/commands/confirm.command.ts +++ b/apps/cli/src/admin-console/commands/confirm.command.ts @@ -5,7 +5,7 @@ import { OrganizationUserConfirmRequest, } from "@bitwarden/admin-console/common"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { KeyService } from "@bitwarden/key-management"; diff --git a/apps/cli/src/admin-console/commands/share.command.ts b/apps/cli/src/admin-console/commands/share.command.ts index e26d073326e..6d9e6c8b6c0 100644 --- a/apps/cli/src/admin-console/commands/share.command.ts +++ b/apps/cli/src/admin-console/commands/share.command.ts @@ -1,8 +1,9 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { firstValueFrom, map } from "rxjs"; +import { firstValueFrom } from "rxjs"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { Response } from "../../models/response"; @@ -48,7 +49,9 @@ export class ShareCommand { organizationId = organizationId.toLowerCase(); } - const cipher = await this.cipherService.get(id); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + + const cipher = await this.cipherService.get(id, activeUserId); if (cipher == null) { return Response.notFound(); } @@ -56,15 +59,12 @@ export class ShareCommand { return Response.badRequest("This item already belongs to an organization."); } - const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), - ); const cipherView = await cipher.decrypt( await this.cipherService.getKeyForCipherKeyDecryption(cipher, activeUserId), ); try { await this.cipherService.shareWithServer(cipherView, organizationId, req, activeUserId); - const updatedCipher = await this.cipherService.get(cipher.id); + const updatedCipher = await this.cipherService.get(cipher.id, activeUserId); const decCipher = await updatedCipher.decrypt( await this.cipherService.getKeyForCipherKeyDecryption(updatedCipher, activeUserId), ); diff --git a/apps/cli/src/commands/download.command.ts b/apps/cli/src/commands/download.command.ts index 6a7cda2ac91..01ef675d2a8 100644 --- a/apps/cli/src/commands/download.command.ts +++ b/apps/cli/src/commands/download.command.ts @@ -1,7 +1,7 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.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"; diff --git a/apps/cli/src/commands/edit.command.ts b/apps/cli/src/commands/edit.command.ts index 13152f3d29e..2d4a854135d 100644 --- a/apps/cli/src/commands/edit.command.ts +++ b/apps/cli/src/commands/edit.command.ts @@ -1,15 +1,16 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { firstValueFrom, map } from "rxjs"; +import { firstValueFrom } from "rxjs"; import { CollectionRequest } from "@bitwarden/admin-console/common"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { SelectionReadOnlyRequest } from "@bitwarden/common/admin-console/models/request/selection-read-only.request"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { getUserId } from "@bitwarden/common/auth/services/account.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { CipherExport } from "@bitwarden/common/models/export/cipher.export"; import { CollectionExport } from "@bitwarden/common/models/export/collection.export"; import { FolderExport } from "@bitwarden/common/models/export/folder.export"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { FolderApiServiceAbstraction } from "@bitwarden/common/vault/abstractions/folder/folder-api.service.abstraction"; @@ -25,8 +26,6 @@ import { CipherResponse } from "../vault/models/cipher.response"; import { FolderResponse } from "../vault/models/folder.response"; export class EditCommand { - private activeUserId$ = this.accountService.activeAccount$.pipe(map((a) => a?.id)); - constructor( private cipherService: CipherService, private folderService: FolderService, @@ -85,14 +84,12 @@ export class EditCommand { } private async editCipher(id: string, req: CipherExport) { - const cipher = await this.cipherService.get(id); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + const cipher = await this.cipherService.get(id, activeUserId); if (cipher == null) { return Response.notFound(); } - const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), - ); let cipherView = await cipher.decrypt( await this.cipherService.getKeyForCipherKeyDecryption(cipher, activeUserId), ); @@ -114,7 +111,9 @@ export class EditCommand { } private async editCipherCollections(id: string, req: string[]) { - const cipher = await this.cipherService.get(id); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + + const cipher = await this.cipherService.get(id, activeUserId); if (cipher == null) { return Response.notFound(); } @@ -123,14 +122,20 @@ export class EditCommand { "Item does not belong to an organization. Consider moving it first.", ); } + if (!cipher.viewPassword) { + return Response.noEditPermission(); + } cipher.collectionIds = req; try { - const updatedCipher = await this.cipherService.saveCollectionsWithServer(cipher); + const updatedCipher = await this.cipherService.saveCollectionsWithServer( + cipher, + activeUserId, + ); const decCipher = await updatedCipher.decrypt( await this.cipherService.getKeyForCipherKeyDecryption( updatedCipher, - await firstValueFrom(this.activeUserId$), + await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)), ), ); const res = new CipherResponse(decCipher); @@ -141,7 +146,7 @@ export class EditCommand { } private async editFolder(id: string, req: FolderExport) { - const activeUserId = await firstValueFrom(this.activeUserId$); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); const folder = await this.folderService.getFromState(id, activeUserId); if (folder == null) { return Response.notFound(); diff --git a/apps/cli/src/commands/get.command.ts b/apps/cli/src/commands/get.command.ts index c8a6f314240..92c3a8baeaf 100644 --- a/apps/cli/src/commands/get.command.ts +++ b/apps/cli/src/commands/get.command.ts @@ -13,6 +13,7 @@ import { AccountService } from "@bitwarden/common/auth/abstractions/account.serv import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { EventType } from "@bitwarden/common/enums"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { CardExport } from "@bitwarden/common/models/export/card.export"; import { CipherExport } from "@bitwarden/common/models/export/cipher.export"; import { CollectionExport } from "@bitwarden/common/models/export/collection.export"; @@ -23,7 +24,6 @@ import { LoginUriExport } from "@bitwarden/common/models/export/login-uri.export import { LoginExport } from "@bitwarden/common/models/export/login.export"; import { SecureNoteExport } from "@bitwarden/common/models/export/secure-note.export"; import { ErrorResponse } from "@bitwarden/common/models/response/error.response"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; 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"; @@ -52,8 +52,6 @@ import { FolderResponse } from "../vault/models/folder.response"; import { DownloadCommand } from "./download.command"; export class GetCommand extends DownloadCommand { - private activeUserId$ = this.accountService.activeAccount$.pipe(map((a) => a?.id)); - constructor( private cipherService: CipherService, private folderService: FolderService, @@ -114,16 +112,16 @@ export class GetCommand extends DownloadCommand { private async getCipherView(id: string): Promise { let decCipher: CipherView = null; + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); if (Utils.isGuid(id)) { - const cipher = await this.cipherService.get(id); + const cipher = await this.cipherService.get(id, activeUserId); if (cipher != null) { - const activeUserId = await firstValueFrom(this.activeUserId$); decCipher = await cipher.decrypt( await this.cipherService.getKeyForCipherKeyDecryption(cipher, activeUserId), ); } } else if (id.trim() !== "") { - let ciphers = await this.cipherService.getAllDecrypted(); + let ciphers = await this.cipherService.getAllDecrypted(activeUserId); ciphers = this.searchService.searchCiphersBasic(ciphers, id); if (ciphers.length > 1) { return ciphers; @@ -265,8 +263,10 @@ export class GetCommand extends DownloadCommand { const canAccessPremium = await firstValueFrom( this.accountProfileService.hasPremiumFromAnySource$(account.id), ); + if (!canAccessPremium) { - const originalCipher = await this.cipherService.get(cipher.id); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + const originalCipher = await this.cipherService.get(cipher.id, activeUserId); if ( originalCipher == null || originalCipher.organizationId == null || @@ -352,7 +352,8 @@ export class GetCommand extends DownloadCommand { this.accountProfileService.hasPremiumFromAnySource$(account.id), ); if (!canAccessPremium) { - const originalCipher = await this.cipherService.get(cipher.id); + 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."); } @@ -384,7 +385,7 @@ export class GetCommand extends DownloadCommand { private async getFolder(id: string) { let decFolder: FolderView = null; - const activeUserId = await firstValueFrom(this.activeUserId$); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); if (Utils.isGuid(id)) { const folder = await this.folderService.getFromState(id, activeUserId); if (folder != null) { @@ -561,7 +562,7 @@ export class GetCommand extends DownloadCommand { private async getFingerprint(id: string) { let fingerprint: string[] = null; if (id === "me") { - const activeUserId = await firstValueFrom(this.activeUserId$); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); const publicKey = await firstValueFrom(this.keyService.userPublicKey$(activeUserId)); fingerprint = await this.keyService.getFingerprint(activeUserId, publicKey); } else if (Utils.isGuid(id)) { diff --git a/apps/cli/src/commands/list.command.ts b/apps/cli/src/commands/list.command.ts index 5e01af798a4..5d512d81bf5 100644 --- a/apps/cli/src/commands/list.command.ts +++ b/apps/cli/src/commands/list.command.ts @@ -65,11 +65,14 @@ export class ListCommand { private async listCiphers(options: Options) { let ciphers: CipherView[]; + + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + options.trash = options.trash || false; if (options.url != null && options.url.trim() !== "") { - ciphers = await this.cipherService.getAllDecryptedForUrl(options.url); + ciphers = await this.cipherService.getAllDecryptedForUrl(options.url, activeUserId); } else { - ciphers = await this.cipherService.getAllDecrypted(); + ciphers = await this.cipherService.getAllDecrypted(activeUserId); } if ( @@ -138,9 +141,8 @@ export class ListCommand { } private async listFolders(options: Options) { - const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), - ); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + let folders = await this.folderService.getAllDecryptedFromState(activeUserId); if (options.search != null && options.search.trim() !== "") { diff --git a/apps/cli/src/commands/restore.command.ts b/apps/cli/src/commands/restore.command.ts index 96179e7b687..fd2f6f239ef 100644 --- a/apps/cli/src/commands/restore.command.ts +++ b/apps/cli/src/commands/restore.command.ts @@ -1,9 +1,16 @@ +import { firstValueFrom } from "rxjs"; + +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { Response } from "../models/response"; export class RestoreCommand { - constructor(private cipherService: CipherService) {} + constructor( + private cipherService: CipherService, + private accountService: AccountService, + ) {} async run(object: string, id: string): Promise { if (id != null) { @@ -19,7 +26,9 @@ export class RestoreCommand { } private async restoreCipher(id: string) { - const cipher = await this.cipherService.get(id); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + + const cipher = await this.cipherService.get(id, activeUserId); if (cipher == null) { return Response.notFound(); } @@ -28,7 +37,7 @@ export class RestoreCommand { } try { - await this.cipherService.restoreWithServer(id); + await this.cipherService.restoreWithServer(id, activeUserId); return Response.success(); } catch (e) { return Response.error(e); diff --git a/apps/cli/src/models/response.ts b/apps/cli/src/models/response.ts index 76d9509226d..ac0977182f4 100644 --- a/apps/cli/src/models/response.ts +++ b/apps/cli/src/models/response.ts @@ -39,6 +39,10 @@ export class Response { return Response.error("Not found."); } + static noEditPermission(): Response { + return Response.error("You do not have permission to edit this item"); + } + static badRequest(message: string): Response { return Response.error(message); } diff --git a/apps/cli/src/oss-serve-configurator.ts b/apps/cli/src/oss-serve-configurator.ts index be476d19814..dec09447839 100644 --- a/apps/cli/src/oss-serve-configurator.ts +++ b/apps/cli/src/oss-serve-configurator.ts @@ -124,7 +124,10 @@ export class OssServeConfigurator { this.serviceContainer.encryptService, this.serviceContainer.organizationUserApiService, ); - this.restoreCommand = new RestoreCommand(this.serviceContainer.cipherService); + this.restoreCommand = new RestoreCommand( + this.serviceContainer.cipherService, + this.serviceContainer.accountService, + ); this.shareCommand = new ShareCommand( this.serviceContainer.cipherService, this.serviceContainer.accountService, 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 2807509e428..5e31995606f 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 @@ -2,7 +2,7 @@ // @ts-strict-ignore import { throwError } from "rxjs"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { AbstractStorageService } from "@bitwarden/common/platform/abstractions/storage.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; diff --git a/apps/cli/src/service-container/service-container.ts b/apps/cli/src/service-container/service-container.ts index 4eda8cd7abd..f7dad133f94 100644 --- a/apps/cli/src/service-container/service-container.ts +++ b/apps/cli/src/service-container/service-container.ts @@ -61,6 +61,8 @@ import { import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { DefaultBillingAccountProfileStateService } from "@bitwarden/common/billing/services/account/billing-account-profile-state.service"; import { ClientType } from "@bitwarden/common/enums"; +import { EncryptServiceImplementation } from "@bitwarden/common/key-management/crypto/services/encrypt.service.implementation"; +import { FallbackBulkEncryptService } from "@bitwarden/common/key-management/crypto/services/fallback-bulk-encrypt.service"; import { ConfigApiServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config-api.service.abstraction"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { @@ -83,8 +85,6 @@ import { AppIdService } from "@bitwarden/common/platform/services/app-id.service import { ConfigApiService } from "@bitwarden/common/platform/services/config/config-api.service"; import { DefaultConfigService } from "@bitwarden/common/platform/services/config/default-config.service"; import { ContainerService } from "@bitwarden/common/platform/services/container.service"; -import { EncryptServiceImplementation } from "@bitwarden/common/platform/services/cryptography/encrypt.service.implementation"; -import { FallbackBulkEncryptService } from "@bitwarden/common/platform/services/cryptography/fallback-bulk-encrypt.service"; import { DefaultEnvironmentService } from "@bitwarden/common/platform/services/default-environment.service"; import { FileUploadService } from "@bitwarden/common/platform/services/file-upload/file-upload.service"; import { KeyGenerationService } from "@bitwarden/common/platform/services/key-generation.service"; @@ -151,7 +151,7 @@ import { ImportApiServiceAbstraction, ImportService, ImportServiceAbstraction, -} from "@bitwarden/importer/core"; +} from "@bitwarden/importer-core"; import { DefaultKdfConfigService, KdfConfigService, diff --git a/apps/cli/src/tools/import.command.ts b/apps/cli/src/tools/import.command.ts index d68ef4d043a..f414357c941 100644 --- a/apps/cli/src/tools/import.command.ts +++ b/apps/cli/src/tools/import.command.ts @@ -11,7 +11,7 @@ import { import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; -import { ImportServiceAbstraction, ImportType } from "@bitwarden/importer/core"; +import { ImportServiceAbstraction, ImportType } from "@bitwarden/importer-core"; import { Response } from "../models/response"; import { MessageResponse } from "../models/response/message.response"; diff --git a/apps/cli/src/tools/send/commands/get.command.ts b/apps/cli/src/tools/send/commands/get.command.ts index 0e650c8503d..1d651c50bf0 100644 --- a/apps/cli/src/tools/send/commands/get.command.ts +++ b/apps/cli/src/tools/send/commands/get.command.ts @@ -5,7 +5,7 @@ import { firstValueFrom } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { SearchService } from "@bitwarden/common/abstractions/search.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { SendView } from "@bitwarden/common/tools/send/models/view/send.view"; diff --git a/apps/cli/src/tools/send/commands/receive.command.ts b/apps/cli/src/tools/send/commands/receive.command.ts index 41a6681af55..879d03f6dae 100644 --- a/apps/cli/src/tools/send/commands/receive.command.ts +++ b/apps/cli/src/tools/send/commands/receive.command.ts @@ -5,9 +5,9 @@ import * as inquirer from "inquirer"; import { firstValueFrom } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { ErrorResponse } from "@bitwarden/common/models/response/error.response"; import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; 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"; diff --git a/apps/cli/src/vault.program.ts b/apps/cli/src/vault.program.ts index f3eb6eef613..d6ef27b1428 100644 --- a/apps/cli/src/vault.program.ts +++ b/apps/cli/src/vault.program.ts @@ -347,7 +347,10 @@ export class VaultProgram extends BaseProgram { } await this.exitIfLocked(); - const command = new RestoreCommand(this.serviceContainer.cipherService); + const command = new RestoreCommand( + this.serviceContainer.cipherService, + this.serviceContainer.accountService, + ); const response = await command.run(object, id); this.processResponse(response); }); diff --git a/apps/cli/src/vault/create.command.ts b/apps/cli/src/vault/create.command.ts index 73027e80112..713471356c9 100644 --- a/apps/cli/src/vault/create.command.ts +++ b/apps/cli/src/vault/create.command.ts @@ -10,11 +10,12 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { SelectionReadOnlyRequest } from "@bitwarden/common/admin-console/models/request/selection-read-only.request"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { getUserId } from "@bitwarden/common/auth/services/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 { CipherExport } from "@bitwarden/common/models/export/cipher.export"; import { CollectionExport } from "@bitwarden/common/models/export/collection.export"; import { FolderExport } from "@bitwarden/common/models/export/folder.export"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { FolderApiServiceAbstraction } from "@bitwarden/common/vault/abstractions/folder/folder-api.service.abstraction"; @@ -30,8 +31,6 @@ import { CipherResponse } from "./models/cipher.response"; import { FolderResponse } from "./models/folder.response"; export class CreateCommand { - private activeUserId$ = this.accountService.activeAccount$.pipe(map((a) => a?.id)); - constructor( private cipherService: CipherService, private folderService: FolderService, @@ -90,7 +89,7 @@ export class CreateCommand { } private async createCipher(req: CipherExport) { - const activeUserId = await firstValueFrom(this.activeUserId$); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); const cipher = await this.cipherService.encrypt(CipherExport.toView(req), activeUserId); try { const newCipher = await this.cipherService.createWithServer(cipher); @@ -132,14 +131,14 @@ export class CreateCommand { return Response.badRequest("File name not provided."); } + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + const itemId = options.itemId.toLowerCase(); - const cipher = await this.cipherService.get(itemId); + const cipher = await this.cipherService.get(itemId, activeUserId); if (cipher == null) { return Response.notFound(); } - const activeUserId = await firstValueFrom(this.activeUserId$); - const canAccessPremium = await firstValueFrom( this.accountProfileService.hasPremiumFromAnySource$(activeUserId), ); @@ -173,7 +172,7 @@ export class CreateCommand { } private async createFolder(req: FolderExport) { - const activeUserId = await firstValueFrom(this.activeUserId$); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); const userKey = await this.keyService.getUserKeyWithLegacySupport(activeUserId); const folder = await this.folderService.encrypt(FolderExport.toView(req), userKey); try { diff --git a/apps/cli/src/vault/delete.command.ts b/apps/cli/src/vault/delete.command.ts index a285f8f5b34..9e648cd9bb0 100644 --- a/apps/cli/src/vault/delete.command.ts +++ b/apps/cli/src/vault/delete.command.ts @@ -1,7 +1,8 @@ -import { firstValueFrom, map } from "rxjs"; +import { firstValueFrom } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; @@ -44,7 +45,9 @@ export class DeleteCommand { } private async deleteCipher(id: string, options: Options) { - const cipher = await this.cipherService.get(id); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + + const cipher = await this.cipherService.get(id, activeUserId); if (cipher == null) { return Response.notFound(); } @@ -59,9 +62,9 @@ export class DeleteCommand { try { if (options.permanent) { - await this.cipherService.deleteWithServer(id); + await this.cipherService.deleteWithServer(id, activeUserId); } else { - await this.cipherService.softDeleteWithServer(id); + await this.cipherService.softDeleteWithServer(id, activeUserId); } return Response.success(); } catch (e) { @@ -74,8 +77,10 @@ export class DeleteCommand { return Response.badRequest("`itemid` option is required."); } + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + const itemId = options.itemId.toLowerCase(); - const cipher = await this.cipherService.get(itemId); + const cipher = await this.cipherService.get(itemId, activeUserId); if (cipher == null) { return Response.notFound(); } @@ -89,16 +94,19 @@ export class DeleteCommand { return Response.error("Attachment `" + id + "` was not found."); } - const account = await firstValueFrom(this.accountService.activeAccount$); const canAccessPremium = await firstValueFrom( - this.accountProfileService.hasPremiumFromAnySource$(account.id), + this.accountProfileService.hasPremiumFromAnySource$(activeUserId), ); if (cipher.organizationId == null && !canAccessPremium) { return Response.error("Premium status is required to use this feature."); } try { - await this.cipherService.deleteAttachmentWithServer(cipher.id, attachments[0].id); + await this.cipherService.deleteAttachmentWithServer( + cipher.id, + attachments[0].id, + activeUserId, + ); return Response.success(); } catch (e) { return Response.error(e); @@ -106,9 +114,7 @@ export class DeleteCommand { } private async deleteFolder(id: string) { - const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), - ); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); const folder = await this.folderService.getFromState(id, activeUserId); if (folder == null) { return Response.notFound(); diff --git a/apps/cli/tsconfig.json b/apps/cli/tsconfig.json index 3853cd93126..9d6e3066b29 100644 --- a/apps/cli/tsconfig.json +++ b/apps/cli/tsconfig.json @@ -17,7 +17,7 @@ "@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/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"], diff --git a/apps/desktop/desktop_native/.gitignore b/apps/desktop/desktop_native/.gitignore index 1cfa7dafc20..a0a01b28f50 100644 --- a/apps/desktop/desktop_native/.gitignore +++ b/apps/desktop/desktop_native/.gitignore @@ -5,3 +5,4 @@ index.node npm-debug.log* *.node dist +windows_pluginauthenticator_bindings.rs diff --git a/apps/desktop/desktop_native/Cargo.lock b/apps/desktop/desktop_native/Cargo.lock index 08f0b7513e2..1299a65f956 100644 --- a/apps/desktop/desktop_native/Cargo.lock +++ b/apps/desktop/desktop_native/Cargo.lock @@ -410,6 +410,26 @@ dependencies = [ "serde", ] +[[package]] +name = "bindgen" +version = "0.71.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "itertools", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", +] + [[package]] name = "bitflags" version = "2.8.0" @@ -546,13 +566,22 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.10" +version = "1.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13208fcbb66eaeffe09b99fffbe1af420f00a7b35aa99ad683dfc1aa76145229" +checksum = "9157bbaa6b165880c27a4293a474c91cdcf265cc68cc829bf10be0964a391caf" dependencies = [ "shlex", ] +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -593,6 +622,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + [[package]] name = "clap" version = "4.5.27" @@ -1458,6 +1498,15 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.14" @@ -1641,9 +1690,9 @@ dependencies = [ [[package]] name = "napi" -version = "2.16.13" +version = "2.16.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "214f07a80874bb96a8433b3cdfc84980d56c7b02e1a0d7ba4ba0db5cef785e2b" +checksum = "d3437deb8b6ba2448b6a94260c5c6b9e5eeb5a5d6277e44b40b2532d457b0f0d" dependencies = [ "bitflags", "ctor", @@ -2259,6 +2308,16 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "prettyplease" +version = "0.2.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "483f8c21f64f3ea09fe0f30f5d48c3e8eefe5dac9129f0075f76593b4c1da705" +dependencies = [ + "proc-macro2", + "syn", +] + [[package]] name = "proc-macro-crate" version = "3.2.0" @@ -2437,6 +2496,12 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +[[package]] +name = "rustc-hash" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" + [[package]] name = "rustc_version" version = "0.4.1" @@ -2563,18 +2628,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.217" +version = "1.0.209" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" +checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.217" +version = "1.0.209" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" +checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" dependencies = [ "proc-macro2", "quote", @@ -2583,9 +2648,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.138" +version = "1.0.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949" +checksum = "8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329ad" dependencies = [ "itoa", "memchr", @@ -2793,9 +2858,9 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.32.1" +version = "0.33.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c33cd241af0f2e9e3b5c32163b873b29956890b5342e6745b917ce9d490f4af" +checksum = "4fc858248ea01b66f19d8e8a6d55f41deaf91e9d495246fd01368d99935c6c01" dependencies = [ "core-foundation-sys", "libc", @@ -3447,6 +3512,13 @@ dependencies = [ "syn", ] +[[package]] +name = "windows-plugin-authenticator" +version = "0.0.0" +dependencies = [ + "bindgen", +] + [[package]] name = "windows-registry" version = "0.4.0" diff --git a/apps/desktop/desktop_native/Cargo.toml b/apps/desktop/desktop_native/Cargo.toml index 6230a6bfe15..78142d618ed 100644 --- a/apps/desktop/desktop_native/Cargo.toml +++ b/apps/desktop/desktop_native/Cargo.toml @@ -1,3 +1,13 @@ [workspace] resolver = "2" -members = ["napi", "core", "proxy", "macos_provider"] +members = ["napi", "core", "proxy", "macos_provider", "windows-plugin-authenticator"] + +[workspace.dependencies] +anyhow = "=1.0.94" +log = "=0.4.25" +serde = "=1.0.209" +serde_json = "=1.0.127" +tokio = "=1.43.0" +tokio-util = "=0.7.13" +tokio-stream = "=0.1.15" +thiserror = "=1.0.69" diff --git a/apps/desktop/desktop_native/core/Cargo.toml b/apps/desktop/desktop_native/core/Cargo.toml index 86b6f2239ff..03b5a60b8b1 100644 --- a/apps/desktop/desktop_native/core/Cargo.toml +++ b/apps/desktop/desktop_native/core/Cargo.toml @@ -13,13 +13,13 @@ default = [ "dep:security-framework", "dep:security-framework-sys", "dep:zbus", - "dep:zbus_polkit" + "dep:zbus_polkit", ] manual_test = [] [dependencies] aes = "=0.8.4" -anyhow = "=1.0.94" +anyhow.workspace = true arboard = { version = "=3.4.1", default-features = false, features = [ "wayland-data-control", ] } @@ -32,7 +32,7 @@ pin-project = "=1.1.8" dirs = "=6.0.0" futures = "=0.3.31" interprocess = { version = "=2.2.1", features = ["tokio"] } -log = "=0.4.25" +log.workspace = true rand = "=0.8.5" russh-cryptovec = "=0.7.3" scopeguard = "=1.2.0" @@ -45,15 +45,15 @@ ssh-key = { version = "=0.6.7", default-features = false, features = [ "getrandom", ] } bitwarden-russh = { git = "https://github.com/bitwarden/bitwarden-russh.git", rev = "23b50e3bbe6d56ef19ab0e98e8bb1462cb6d77ae" } -tokio = { version = "=1.43.0", features = ["io-util", "sync", "macros", "net"] } -tokio-stream = { version = "=0.1.15", features = ["net"] } -tokio-util = { version = "=0.7.13", features = ["codec"] } -thiserror = "=1.0.69" +tokio = { workspace = true, features = ["io-util", "sync", "macros", "net"] } +tokio-stream = { workspace = true, features = ["net"] } +tokio-util = { workspace = true, features = ["codec"] } +thiserror.workspace = true typenum = "=1.17.0" pkcs8 = { version = "=0.10.2", features = ["alloc", "encryption", "pem"] } rsa = "=0.9.6" ed25519 = { version = "=2.2.3", features = ["pkcs8"] } -sysinfo = { version = "0.32.0", features = ["windows"] } +sysinfo = { version = "=0.33.1", features = ["windows"] } [target.'cfg(windows)'.dependencies] widestring = { version = "=1.1.0", optional = true } diff --git a/apps/desktop/desktop_native/macos_provider/Cargo.toml b/apps/desktop/desktop_native/macos_provider/Cargo.toml index ff7408d6d44..a488ce88a1c 100644 --- a/apps/desktop/desktop_native/macos_provider/Cargo.toml +++ b/apps/desktop/desktop_native/macos_provider/Cargo.toml @@ -16,15 +16,15 @@ bench = false [dependencies] desktop_core = { path = "../core" } futures = "=0.3.31" -log = "0.4.22" -serde = { version = "1.0.205", features = ["derive"] } -serde_json = "1.0.122" -tokio = { version = "1.39.2", features = ["sync"] } -tokio-util = "0.7.11" -uniffi = { version = "0.28.3", features = ["cli"] } +log.workspace = true +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true +tokio = { workspace = true, features = ["sync"] } +tokio-util.workspace = true +uniffi = { version = "=0.28.3", features = ["cli"] } [target.'cfg(target_os = "macos")'.dependencies] -oslog = "0.2.0" +oslog = "=0.2.0" [build-dependencies] -uniffi = { version = "0.28.3", features = ["build"] } +uniffi = { version = "=0.28.3", features = ["build"] } diff --git a/apps/desktop/desktop_native/napi/Cargo.toml b/apps/desktop/desktop_native/napi/Cargo.toml index b23e61662b4..73afee72b55 100644 --- a/apps/desktop/desktop_native/napi/Cargo.toml +++ b/apps/desktop/desktop_native/napi/Cargo.toml @@ -18,13 +18,13 @@ base64 = "=0.22.1" hex = "=0.4.3" anyhow = "=1.0.94" desktop_core = { path = "../core" } -napi = { version = "=2.16.13", features = ["async"] } +napi = { version = "=2.16.15", features = ["async"] } napi-derive = "=2.16.13" -serde = { version = "1.0.209", features = ["derive"] } -serde_json = "1.0.127" -tokio = { version = "=1.43.0" } -tokio-util = "=0.7.13" -tokio-stream = "=0.1.15" +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true +tokio.workspace = true +tokio-util.workspace = true +tokio-stream.workspace = true [target.'cfg(windows)'.dependencies] windows-registry = "=0.4.0" diff --git a/apps/desktop/desktop_native/objc/Cargo.toml b/apps/desktop/desktop_native/objc/Cargo.toml index eae303b9f08..2d6478c77c9 100644 --- a/apps/desktop/desktop_native/objc/Cargo.toml +++ b/apps/desktop/desktop_native/objc/Cargo.toml @@ -9,13 +9,13 @@ publish = false default = [] [dependencies] -anyhow = "=1.0.94" -thiserror = "=1.0.69" -tokio = "1.39.1" +anyhow.workspace = true +thiserror.workspace = true +tokio.workspace = true [target.'cfg(target_os = "macos")'.dependencies] core-foundation = "=0.10.0" [build-dependencies] -cc = "1.2.4" -glob = "0.3.2" +cc = "=1.2.4" +glob = "=0.3.2" diff --git a/apps/desktop/desktop_native/proxy/Cargo.toml b/apps/desktop/desktop_native/proxy/Cargo.toml index a38fa2cf890..27f2856f3a6 100644 --- a/apps/desktop/desktop_native/proxy/Cargo.toml +++ b/apps/desktop/desktop_native/proxy/Cargo.toml @@ -7,13 +7,13 @@ version = "0.0.0" publish = false [dependencies] -anyhow = "=1.0.94" +anyhow.workspace = true desktop_core = { path = "../core" } futures = "=0.3.31" -log = "=0.4.25" +log.workspace = true simplelog = "=0.12.2" -tokio = { version = "=1.43.0", features = ["io-std", "io-util", "macros", "rt"] } -tokio-util = { version = "=0.7.13", features = ["codec"] } +tokio = { workspace = true, features = ["io-std", "io-util", "macros", "rt"] } +tokio-util = { workspace = true, features = ["codec"] } [target.'cfg(target_os = "macos")'.dependencies] embed_plist = "=1.2.2" diff --git a/apps/desktop/desktop_native/windows-plugin-authenticator/Cargo.toml b/apps/desktop/desktop_native/windows-plugin-authenticator/Cargo.toml new file mode 100644 index 00000000000..b8759cfca3f --- /dev/null +++ b/apps/desktop/desktop_native/windows-plugin-authenticator/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "windows-plugin-authenticator" +version = "0.0.0" +edition = "2021" +license = "GPL-3.0" +publish = false + +[target.'cfg(target_os = "windows")'.build-dependencies] +bindgen = "0.71.1" diff --git a/apps/desktop/desktop_native/windows-plugin-authenticator/README.md b/apps/desktop/desktop_native/windows-plugin-authenticator/README.md new file mode 100644 index 00000000000..6dc72ceed46 --- /dev/null +++ b/apps/desktop/desktop_native/windows-plugin-authenticator/README.md @@ -0,0 +1,23 @@ +# windows-plugin-authenticator + +This is an internal crate that's meant to be a safe abstraction layer over the generated Rust bindings for the Windows WebAuthn Plugin Authenticator API's. + +You can find more information about the Windows WebAuthn API's [here](https://github.com/microsoft/webauthn). + +## Building + +To build this crate, set the following environment variables: + +- `LIBCLANG_PATH` -> the path to the `bin` directory of your LLVM install ([more info](https://rust-lang.github.io/rust-bindgen/requirements.html?highlight=libclang_path#installing-clang)) + +### Bash Example + +``` +export LIBCLANG_PATH='C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\Llvm\x64\bin' +``` + +### PowerShell Example + +``` +$env:LIBCLANG_PATH = 'C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\Llvm\x64\bin' +``` diff --git a/apps/desktop/desktop_native/windows-plugin-authenticator/build.rs b/apps/desktop/desktop_native/windows-plugin-authenticator/build.rs new file mode 100644 index 00000000000..7bc311fb12d --- /dev/null +++ b/apps/desktop/desktop_native/windows-plugin-authenticator/build.rs @@ -0,0 +1,22 @@ +fn main() { + #[cfg(target_os = "windows")] + windows(); +} + +#[cfg(target_os = "windows")] +fn windows() { + let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR not set"); + + let bindings = bindgen::Builder::default() + .header("pluginauthenticator.hpp") + .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) + .generate() + .expect("Unable to generate bindings."); + + bindings + .write_to_file(format!( + "{}\\windows_pluginauthenticator_bindings.rs", + out_dir + )) + .expect("Couldn't write bindings."); +} diff --git a/apps/desktop/desktop_native/windows-plugin-authenticator/pluginauthenticator.hpp b/apps/desktop/desktop_native/windows-plugin-authenticator/pluginauthenticator.hpp new file mode 100644 index 00000000000..c800266a3e6 --- /dev/null +++ b/apps/desktop/desktop_native/windows-plugin-authenticator/pluginauthenticator.hpp @@ -0,0 +1,231 @@ +/* + Bitwarden's pluginauthenticator.hpp + + Source: https://github.com/microsoft/webauthn/blob/master/experimental/pluginauthenticator.h + + This is a C++ header file, so the extension has been manually + changed from `.h` to `.hpp`, so bindgen will automatically + generate the correct C++ bindings. + + More Info: https://rust-lang.github.io/rust-bindgen/cpp.html +*/ + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + +/* File created by MIDL compiler version 8.01.0628 */ +/* @@MIDL_FILE_HEADING( ) */ + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 501 +#endif + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCSAL_H_VERSION__ +#define __REQUIRED_RPCSAL_H_VERSION__ 100 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of +#endif /* __RPCNDR_H_VERSION__ */ + +#ifndef COM_NO_WINDOWS_H +#include "windows.h" +#include "ole2.h" +#endif /*COM_NO_WINDOWS_H*/ + +#ifndef __pluginauthenticator_h__ +#define __pluginauthenticator_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#ifndef DECLSPEC_XFGVIRT +#if defined(_CONTROL_FLOW_GUARD_XFG) +#define DECLSPEC_XFGVIRT(base, func) __declspec(xfg_virtual(base, func)) +#else +#define DECLSPEC_XFGVIRT(base, func) +#endif +#endif + +/* Forward Declarations */ + +#ifndef __EXPERIMENTAL_IPluginAuthenticator_FWD_DEFINED__ +#define __EXPERIMENTAL_IPluginAuthenticator_FWD_DEFINED__ +typedef interface EXPERIMENTAL_IPluginAuthenticator EXPERIMENTAL_IPluginAuthenticator; + +#endif /* __EXPERIMENTAL_IPluginAuthenticator_FWD_DEFINED__ */ + +/* header files for imported files */ +#include "oaidl.h" +#include "webauthn.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +/* interface __MIDL_itf_pluginauthenticator_0000_0000 */ +/* [local] */ + +typedef struct _EXPERIMENTAL_WEBAUTHN_PLUGIN_OPERATION_REQUEST + { + HWND hWnd; + GUID transactionId; + DWORD cbRequestSignature; + /* [size_is] */ byte *pbRequestSignature; + DWORD cbEncodedRequest; + /* [size_is] */ byte *pbEncodedRequest; + } EXPERIMENTAL_WEBAUTHN_PLUGIN_OPERATION_REQUEST; + +typedef struct _EXPERIMENTAL_WEBAUTHN_PLUGIN_OPERATION_REQUEST *EXPERIMENTAL_PWEBAUTHN_PLUGIN_OPERATION_REQUEST; + +typedef const EXPERIMENTAL_WEBAUTHN_PLUGIN_OPERATION_REQUEST *EXPERIMENTAL_PCWEBAUTHN_PLUGIN_OPERATION_REQUEST; + +typedef struct _EXPERIMENTAL_WEBAUTHN_PLUGIN_OPERATION_RESPONSE + { + DWORD cbEncodedResponse; + /* [size_is] */ byte *pbEncodedResponse; + } EXPERIMENTAL_WEBAUTHN_PLUGIN_OPERATION_RESPONSE; + +typedef struct _EXPERIMENTAL_WEBAUTHN_PLUGIN_OPERATION_RESPONSE *EXPERIMENTAL_PWEBAUTHN_PLUGIN_OPERATION_RESPONSE; + +typedef const EXPERIMENTAL_WEBAUTHN_PLUGIN_OPERATION_RESPONSE *EXPERIMENTAL_PCWEBAUTHN_PLUGIN_OPERATION_RESPONSE; + +typedef struct _EXPERIMENTAL_WEBAUTHN_PLUGIN_CANCEL_OPERATION_REQUEST + { + GUID transactionId; + DWORD cbRequestSignature; + /* [size_is] */ byte *pbRequestSignature; + } EXPERIMENTAL_WEBAUTHN_PLUGIN_CANCEL_OPERATION_REQUEST; + +typedef struct _EXPERIMENTAL_WEBAUTHN_PLUGIN_CANCEL_OPERATION_REQUEST *EXPERIMENTAL_PWEBAUTHN_PLUGIN_CANCEL_OPERATION_REQUEST; + +typedef const EXPERIMENTAL_WEBAUTHN_PLUGIN_CANCEL_OPERATION_REQUEST *EXPERIMENTAL_PCWEBAUTHN_PLUGIN_CANCEL_OPERATION_REQUEST; + +extern RPC_IF_HANDLE __MIDL_itf_pluginauthenticator_0000_0000_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_pluginauthenticator_0000_0000_v0_0_s_ifspec; + +#ifndef __EXPERIMENTAL_IPluginAuthenticator_INTERFACE_DEFINED__ +#define __EXPERIMENTAL_IPluginAuthenticator_INTERFACE_DEFINED__ + +/* interface EXPERIMENTAL_IPluginAuthenticator */ +/* [unique][version][uuid][object] */ + +EXTERN_C const IID IID_EXPERIMENTAL_IPluginAuthenticator; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("e6466e9a-b2f3-47c5-b88d-89bc14a8d998") + EXPERIMENTAL_IPluginAuthenticator : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE EXPERIMENTAL_PluginMakeCredential( + /* [in] */ __RPC__in EXPERIMENTAL_PCWEBAUTHN_PLUGIN_OPERATION_REQUEST request, + /* [out] */ __RPC__deref_out_opt EXPERIMENTAL_PWEBAUTHN_PLUGIN_OPERATION_RESPONSE *response) = 0; + + virtual HRESULT STDMETHODCALLTYPE EXPERIMENTAL_PluginGetAssertion( + /* [in] */ __RPC__in EXPERIMENTAL_PCWEBAUTHN_PLUGIN_OPERATION_REQUEST request, + /* [out] */ __RPC__deref_out_opt EXPERIMENTAL_PWEBAUTHN_PLUGIN_OPERATION_RESPONSE *response) = 0; + + virtual HRESULT STDMETHODCALLTYPE EXPERIMENTAL_PluginCancelOperation( + /* [in] */ __RPC__in EXPERIMENTAL_PCWEBAUTHN_PLUGIN_CANCEL_OPERATION_REQUEST request) = 0; + + }; + +#else /* C style interface */ + + typedef struct EXPERIMENTAL_IPluginAuthenticatorVtbl + { + BEGIN_INTERFACE + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + __RPC__in EXPERIMENTAL_IPluginAuthenticator * This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( + __RPC__in EXPERIMENTAL_IPluginAuthenticator * This); + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( + __RPC__in EXPERIMENTAL_IPluginAuthenticator * This); + + DECLSPEC_XFGVIRT(EXPERIMENTAL_IPluginAuthenticator, EXPERIMENTAL_PluginMakeCredential) + HRESULT ( STDMETHODCALLTYPE *EXPERIMENTAL_PluginMakeCredential )( + __RPC__in EXPERIMENTAL_IPluginAuthenticator * This, + /* [in] */ __RPC__in EXPERIMENTAL_PCWEBAUTHN_PLUGIN_OPERATION_REQUEST request, + /* [out] */ __RPC__deref_out_opt EXPERIMENTAL_PWEBAUTHN_PLUGIN_OPERATION_RESPONSE *response); + + DECLSPEC_XFGVIRT(EXPERIMENTAL_IPluginAuthenticator, EXPERIMENTAL_PluginGetAssertion) + HRESULT ( STDMETHODCALLTYPE *EXPERIMENTAL_PluginGetAssertion )( + __RPC__in EXPERIMENTAL_IPluginAuthenticator * This, + /* [in] */ __RPC__in EXPERIMENTAL_PCWEBAUTHN_PLUGIN_OPERATION_REQUEST request, + /* [out] */ __RPC__deref_out_opt EXPERIMENTAL_PWEBAUTHN_PLUGIN_OPERATION_RESPONSE *response); + + DECLSPEC_XFGVIRT(EXPERIMENTAL_IPluginAuthenticator, EXPERIMENTAL_PluginCancelOperation) + HRESULT ( STDMETHODCALLTYPE *EXPERIMENTAL_PluginCancelOperation )( + __RPC__in EXPERIMENTAL_IPluginAuthenticator * This, + /* [in] */ __RPC__in EXPERIMENTAL_PCWEBAUTHN_PLUGIN_CANCEL_OPERATION_REQUEST request); + + END_INTERFACE + } EXPERIMENTAL_IPluginAuthenticatorVtbl; + + interface EXPERIMENTAL_IPluginAuthenticator + { + CONST_VTBL struct EXPERIMENTAL_IPluginAuthenticatorVtbl *lpVtbl; + }; + +#ifdef COBJMACROS + + +#define EXPERIMENTAL_IPluginAuthenticator_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define EXPERIMENTAL_IPluginAuthenticator_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define EXPERIMENTAL_IPluginAuthenticator_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define EXPERIMENTAL_IPluginAuthenticator_EXPERIMENTAL_PluginMakeCredential(This,request,response) \ + ( (This)->lpVtbl -> EXPERIMENTAL_PluginMakeCredential(This,request,response) ) + +#define EXPERIMENTAL_IPluginAuthenticator_EXPERIMENTAL_PluginGetAssertion(This,request,response) \ + ( (This)->lpVtbl -> EXPERIMENTAL_PluginGetAssertion(This,request,response) ) + +#define EXPERIMENTAL_IPluginAuthenticator_EXPERIMENTAL_PluginCancelOperation(This,request) \ + ( (This)->lpVtbl -> EXPERIMENTAL_PluginCancelOperation(This,request) ) + +#endif /* COBJMACROS */ + +#endif /* C style interface */ + +#endif /* __EXPERIMENTAL_IPluginAuthenticator_INTERFACE_DEFINED__ */ + +/* Additional Prototypes for ALL interfaces */ + +unsigned long __RPC_USER HWND_UserSize( __RPC__in unsigned long *, unsigned long , __RPC__in HWND * ); +unsigned char * __RPC_USER HWND_UserMarshal( __RPC__in unsigned long *, __RPC__inout_xcount(0) unsigned char *, __RPC__in HWND * ); +unsigned char * __RPC_USER HWND_UserUnmarshal(__RPC__in unsigned long *, __RPC__in_xcount(0) unsigned char *, __RPC__out HWND * ); +void __RPC_USER HWND_UserFree( __RPC__in unsigned long *, __RPC__in HWND * ); + +unsigned long __RPC_USER HWND_UserSize64( __RPC__in unsigned long *, unsigned long , __RPC__in HWND * ); +unsigned char * __RPC_USER HWND_UserMarshal64( __RPC__in unsigned long *, __RPC__inout_xcount(0) unsigned char *, __RPC__in HWND * ); +unsigned char * __RPC_USER HWND_UserUnmarshal64(__RPC__in unsigned long *, __RPC__in_xcount(0) unsigned char *, __RPC__out HWND * ); +void __RPC_USER HWND_UserFree64( __RPC__in unsigned long *, __RPC__in HWND * ); + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/apps/desktop/desktop_native/windows-plugin-authenticator/src/lib.rs b/apps/desktop/desktop_native/windows-plugin-authenticator/src/lib.rs new file mode 100644 index 00000000000..e226000e6fa --- /dev/null +++ b/apps/desktop/desktop_native/windows-plugin-authenticator/src/lib.rs @@ -0,0 +1,11 @@ +#![cfg(target_os = "windows")] + +mod pa; + +pub fn get_version_number() -> u64 { + unsafe { pa::WebAuthNGetApiVersionNumber() }.into() +} + +pub fn add_authenticator() { + unimplemented!(); +} diff --git a/apps/desktop/desktop_native/windows-plugin-authenticator/src/pa.rs b/apps/desktop/desktop_native/windows-plugin-authenticator/src/pa.rs new file mode 100644 index 00000000000..3da5a77a243 --- /dev/null +++ b/apps/desktop/desktop_native/windows-plugin-authenticator/src/pa.rs @@ -0,0 +1,15 @@ +/* + The 'pa' (plugin authenticator) module will contain the generated + bindgen code. + + The attributes below will suppress warnings from the generated code. +*/ + +#![cfg(target_os = "windows")] +#![allow(clippy::all)] +#![allow(warnings)] + +include!(concat!( + env!("OUT_DIR"), + "/windows_pluginauthenticator_bindings.rs" +)); 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 71c55a17d1e..c01d581afe8 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 @@ -3,11 +3,11 @@ import "module-alias/register"; import { v4 as uuidv4 } from "uuid"; +import { EncryptServiceImplementation } from "@bitwarden/common/key-management/crypto/services/encrypt.service.implementation"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { ConsoleLogService } from "@bitwarden/common/platform/services/console-log.service"; -import { EncryptServiceImplementation } from "@bitwarden/common/platform/services/cryptography/encrypt.service.implementation"; import { NodeCryptoFunctionService } from "@bitwarden/node/services/node-crypto-function.service"; // eslint-disable-next-line no-restricted-imports diff --git a/apps/desktop/package.json b/apps/desktop/package.json index 249145eb3ea..992f218f6c6 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.1.4", + "version": "2025.2.2", "keywords": [ "bitwarden", "password", diff --git a/apps/desktop/resources/entitlements.mas.plist b/apps/desktop/resources/entitlements.mas.plist index 0450111bebd..bb06ae10431 100644 --- a/apps/desktop/resources/entitlements.mas.plist +++ b/apps/desktop/resources/entitlements.mas.plist @@ -16,6 +16,8 @@ com.apple.security.files.user-selected.read-write + com.apple.security.device.usb +
diff --git a/apps/desktop/src/vault/app/vault/view.component.ts b/apps/desktop/src/vault/app/vault/view.component.ts index ce9d3af8276..aee1f34437b 100644 --- a/apps/desktop/src/vault/app/vault/view.component.ts +++ b/apps/desktop/src/vault/app/vault/view.component.ts @@ -17,8 +17,8 @@ import { EventCollectionService } from "@bitwarden/common/abstractions/event/eve import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; @@ -159,10 +159,4 @@ export class ViewComponent extends BaseViewComponent implements OnInit, OnDestro this.messagingService.send("premiumRequired"); } } - - upgradeOrganization() { - this.messagingService.send("upgradeOrganization", { - organizationId: this.cipher.organizationId, - }); - } } diff --git a/apps/desktop/tsconfig.json b/apps/desktop/tsconfig.json index 94194a0de7d..0bef5a5564d 100644 --- a/apps/desktop/tsconfig.json +++ b/apps/desktop/tsconfig.json @@ -22,8 +22,8 @@ "@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/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/node/*": ["../../libs/node/src/*"], @@ -48,5 +48,5 @@ "strictTemplates": true, "preserveWhitespaces": true }, - "include": ["src", "../../libs/common/src/platform/services/**/*.worker.ts"] + "include": ["src", "../../libs/common/src/key-management/crypto/services/encrypt.worker.ts"] } diff --git a/apps/web/package.json b/apps/web/package.json index 7047b0fb137..cf2df649773 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,6 +1,6 @@ { "name": "@bitwarden/web-vault", - "version": "2025.1.2", + "version": "2025.2.1", "scripts": { "build:oss": "cross-env NODE_OPTIONS=\"--max-old-space-size=8192\" webpack", "build:bit": "cross-env NODE_OPTIONS=\"--max-old-space-size=8192\" webpack -c ../../bitwarden_license/bit-web/webpack.config.js", 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 8387c53e5e3..ae0972a6828 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 @@ -121,6 +121,22 @@ + + {{ "accountDeprovisioningNotification" | i18n }} + + {{ "learnMore" | i18n }} + + ; enterpriseOrganization$: Observable; + showAccountDeprovisioningBanner$: Observable; + constructor( private route: ActivatedRoute, private organizationService: OrganizationService, @@ -68,19 +73,36 @@ export class OrganizationLayoutComponent implements OnInit { private configService: ConfigService, private policyService: PolicyService, private providerService: ProviderService, + protected bannerService: AccountDeprovisioningBannerService, private accountService: AccountService, ) {} async ngOnInit() { document.body.classList.remove("layout_frontend"); - const userId = await firstValueFrom(getUserId(this.accountService.activeAccount$)); this.organization$ = this.route.params.pipe( map((p) => p.organizationId), - switchMap((id) => this.organizationService.organizations$(userId).pipe(getById(id))), + withLatestFrom(this.accountService.activeAccount$.pipe(getUserId)), + switchMap(([orgId, userId]) => + this.organizationService.organizations$(userId).pipe(getById(orgId)), + ), filter((org) => org != null), ); + 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( @@ -107,10 +129,7 @@ export class OrganizationLayoutComponent implements OnInit { ), ); - this.integrationPageEnabled$ = combineLatest( - this.organization$, - this.configService.getFeatureFlag$(FeatureFlag.PM14505AdminConsoleIntegrationPage), - ).pipe(map(([org, featureFlagEnabled]) => featureFlagEnabled && org.canAccessIntegrations)); + this.integrationPageEnabled$ = this.organization$.pipe(map((org) => org.canAccessIntegrations)); this.domainVerificationNavigationTextKey = (await this.configService.getFeatureFlag( FeatureFlag.AccountDeprovisioning, 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 new file mode 100644 index 00000000000..414828969df --- /dev/null +++ b/apps/web/src/app/admin-console/organizations/layouts/services/account-deprovisioning-banner.service.spec.ts @@ -0,0 +1,75 @@ +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 new file mode 100644 index 00000000000..86a6b7df3e2 --- /dev/null +++ b/apps/web/src/app/admin-console/organizations/layouts/services/account-deprovisioning-banner.service.ts @@ -0,0 +1,40 @@ +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 58efc7348e1..68ba5830c35 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 @@ -1,8 +1,10 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore import { DIALOG_DATA, DialogConfig } from "@angular/cdk/dialog"; -import { Component, Inject, OnInit } from "@angular/core"; +import { Component, Inject, OnDestroy, OnInit } from "@angular/core"; import { FormBuilder } from "@angular/forms"; +import { ActivatedRoute, Router } from "@angular/router"; +import { firstValueFrom, switchMap } from "rxjs"; import { OrganizationUserApiService } from "@bitwarden/admin-console/common"; import { UserNamePipe } from "@bitwarden/angular/pipes/user-name.pipe"; @@ -12,7 +14,6 @@ import { ListResponse } from "@bitwarden/common/models/response/list.response"; import { EventView } from "@bitwarden/common/models/view/event.view"; 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 { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service"; import { DialogService, TableDataSource, ToastService } from "@bitwarden/components"; @@ -34,7 +35,7 @@ export interface EntityEventsDialogParams { templateUrl: "entity-events.component.html", standalone: true, }) -export class EntityEventsComponent implements OnInit { +export class EntityEventsComponent implements OnInit, OnDestroy { loading = true; continuationToken: string; protected dataSource = new TableDataSource(); @@ -59,13 +60,14 @@ export class EntityEventsComponent implements OnInit { private apiService: ApiService, private i18nService: I18nService, private eventService: EventService, - private platformUtilsService: PlatformUtilsService, private userNamePipe: UserNamePipe, private logService: LogService, private organizationUserApiService: OrganizationUserApiService, private formBuilder: FormBuilder, private validationService: ValidationService, private toastService: ToastService, + private router: Router, + private activeRoute: ActivatedRoute, ) {} async ngOnInit() { @@ -77,6 +79,21 @@ export class EntityEventsComponent implements OnInit { await this.load(); } + async ngOnDestroy() { + await firstValueFrom( + this.activeRoute.queryParams.pipe( + switchMap(async (params) => { + await this.router.navigate([], { + queryParams: { + ...params, + viewEvents: null, + }, + }); + }), + ), + ); + } + async load() { try { if (this.showUser) { diff --git a/apps/web/src/app/admin-console/organizations/members/components/bulk/base-bulk-confirm.component.ts b/apps/web/src/app/admin-console/organizations/members/components/bulk/base-bulk-confirm.component.ts index 2396292e9af..05e302f011d 100644 --- a/apps/web/src/app/admin-console/organizations/members/components/bulk/base-bulk-confirm.component.ts +++ b/apps/web/src/app/admin-console/organizations/members/components/bulk/base-bulk-confirm.component.ts @@ -8,8 +8,8 @@ import { } from "@bitwarden/admin-console/common"; import { ProviderUserBulkPublicKeyResponse } from "@bitwarden/common/admin-console/models/response/provider/provider-user-bulk-public-key.response"; import { ProviderUserBulkResponse } from "@bitwarden/common/admin-console/models/response/provider/provider-user-bulk.response"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { ListResponse } from "@bitwarden/common/models/response/list.response"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; 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 af827fa65fd..d3a8b8a2e71 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 @@ -14,8 +14,8 @@ import { import { OrganizationUserStatusType } from "@bitwarden/common/admin-console/enums"; import { ProviderUserBulkPublicKeyResponse } from "@bitwarden/common/admin-console/models/response/provider/provider-user-bulk-public-key.response"; import { ProviderUserBulkResponse } from "@bitwarden/common/admin-console/models/response/provider/provider-user-bulk.response"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { ListResponse } from "@bitwarden/common/models/response/list.response"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { StateProvider } from "@bitwarden/common/platform/state"; diff --git a/apps/web/src/app/admin-console/organizations/members/components/bulk/bulk-delete-dialog.component.html b/apps/web/src/app/admin-console/organizations/members/components/bulk/bulk-delete-dialog.component.html index bb5294ebf02..f666decae81 100644 --- a/apps/web/src/app/admin-console/organizations/members/components/bulk/bulk-delete-dialog.component.html +++ b/apps/web/src/app/admin-console/organizations/members/components/bulk/bulk-delete-dialog.component.html @@ -7,9 +7,9 @@ {{ error }} - -

{{ "deleteManyOrganizationUsersWarningDesc" | i18n }}

-
+

+ {{ "deleteManyOrganizationUsersWarningDesc" | i18n }} +

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 704a94b0dd3..9d7752cde84 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 @@ -2,12 +2,17 @@ // @ts-strict-ignore import { DIALOG_DATA, DialogConfig } from "@angular/cdk/dialog"; 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 { DialogService } from "@bitwarden/components"; +import { DeleteManagedMemberWarningService } from "../../services/delete-managed-member/delete-managed-member-warning.service"; + import { BulkUserDetails } from "./bulk-status.component"; type BulkDeleteDialogParams = { @@ -31,12 +36,20 @@ 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; this.users = dialogParams.users; } async submit() { + if ( + await firstValueFrom(this.configService.getFeatureFlag$(FeatureFlag.AccountDeprovisioning)) + ) { + await this.deleteManagedMemberWarningService.acknowledgeWarning(this.organizationId); + } + try { this.loading = true; this.error = null; 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 d66c43ac50f..4925c210039 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 @@ -3,9 +3,9 @@ *ngIf="{ enabled: accountDeprovisioningEnabled$ | async } as accountDeprovisioning" > -

{{ bulkMemberTitle }}

+ {{ bulkMemberTitle }} -

{{ bulkTitle }}

+ {{ bulkTitle }}
@@ -26,61 +26,44 @@ {{ "nonCompliantMembersError" | i18n }} - - -

{{ "revokeUsersWarning" | i18n }}

-
- - - - - {{ "member" | i18n }} - {{ "details" | i18n }} - - - - - -
-
- -
-
- {{ user.email }} - {{ user.name }} -
-
- - - - - - - - {{ "noMasterPassword" | i18n }} - - - - -
-
- - - - - {{ "user" | i18n }} - {{ "details" | i18n }} - - - - - - - - + +
+
+ +
+ +
+ {{ user.name }} + {{ user.email }} - {{ user.name }} + +
+
+ +
{{ user.email }}
+
+
+
+ + +

{{ "revokeUsersWarning" | i18n }}

+ + + + {{ (accountDeprovisioning.enabled ? "member" : "user") | i18n }} + + {{ "details" | i18n }} + + + + + + + - + - @@ -95,55 +78,21 @@ - + - {{ "member" | i18n }} - {{ "status" | i18n }} + + {{ (accountDeprovisioning.enabled ? "member" : "user") | i18n }} + + {{ "status" | i18n }} - -
-
- -
-
- {{ user.email }} - {{ user.name }} -
-
- - - {{ statuses.get(user.id) }} - - - {{ "bulkFilteredMessage" | i18n }} - - -
-
- - - - - {{ "member" | i18n }} - {{ "status" | i18n }} - - - - - -
-
- -
-
- {{ user.email }} - {{ user.name }} -
-
+ + {{ statuses.get(user.id) }} @@ -157,7 +106,13 @@
- - - {{ "important" | i18n }} - {{ "masterPassImportant" | i18n }} {{ characterMinimumMessage }} - - - - -
- -
- - {{ "reTypeMasterPass" | i18n }} - - - -
- -
- - {{ "masterPassHintLabel" | i18n }} - - {{ "masterPassHintDesc" | i18n }} - -
- -
- -
-
- - {{ "checkForBreaches" | i18n }} -
-
- - - - {{ "acceptPolicies" | i18n }}
- {{ - "termsOfService" | i18n - }}, - {{ - "privacyPolicy" | i18n - }} -
-
- -
- - - - - - -
-

- {{ "alreadyHaveAccount" | i18n }} - {{ "logIn" | i18n }} -

- -
- diff --git a/apps/web/src/app/auth/register-form/register-form.component.ts b/apps/web/src/app/auth/register-form/register-form.component.ts deleted file mode 100644 index e8c9f0291a5..00000000000 --- a/apps/web/src/app/auth/register-form/register-form.component.ts +++ /dev/null @@ -1,115 +0,0 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore -import { Component, Input, OnInit } from "@angular/core"; -import { UntypedFormBuilder } from "@angular/forms"; -import { Router } from "@angular/router"; - -import { RegisterComponent as BaseRegisterComponent } from "@bitwarden/angular/auth/components/register.component"; -import { FormValidationErrorsService } from "@bitwarden/angular/platform/abstractions/form-validation-errors.service"; -import { LoginStrategyServiceAbstraction } from "@bitwarden/auth/common"; -import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { AuditService } from "@bitwarden/common/abstractions/audit.service"; -import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; -import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options"; -import { ReferenceEventRequest } from "@bitwarden/common/models/request/reference-event.request"; -import { RegisterRequest } from "@bitwarden/common/models/request/register.request"; -import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { DialogService, ToastService } from "@bitwarden/components"; -import { KeyService } from "@bitwarden/key-management"; - -import { AcceptOrganizationInviteService } from "../organization-invite/accept-organization.service"; - -@Component({ - selector: "app-register-form", - templateUrl: "./register-form.component.html", -}) -export class RegisterFormComponent extends BaseRegisterComponent implements OnInit { - @Input() queryParamEmail: string; - @Input() queryParamFromOrgInvite: boolean; - @Input() enforcedPolicyOptions: MasterPasswordPolicyOptions; - @Input() referenceDataValue: ReferenceEventRequest; - - showErrorSummary = false; - characterMinimumMessage: string; - - constructor( - formValidationErrorService: FormValidationErrorsService, - formBuilder: UntypedFormBuilder, - loginStrategyService: LoginStrategyServiceAbstraction, - router: Router, - i18nService: I18nService, - keyService: KeyService, - apiService: ApiService, - platformUtilsService: PlatformUtilsService, - private policyService: PolicyService, - environmentService: EnvironmentService, - logService: LogService, - auditService: AuditService, - dialogService: DialogService, - acceptOrgInviteService: AcceptOrganizationInviteService, - toastService: ToastService, - ) { - super( - formValidationErrorService, - formBuilder, - loginStrategyService, - router, - i18nService, - keyService, - apiService, - platformUtilsService, - environmentService, - logService, - auditService, - dialogService, - toastService, - ); - this.modifyRegisterRequest = async (request: RegisterRequest) => { - // Org invites are deep linked. Non-existent accounts are redirected to the register page. - // Org user id and token are included here only for validation and two factor purposes. - const orgInvite = await acceptOrgInviteService.getOrganizationInvite(); - if (orgInvite != null) { - request.organizationUserId = orgInvite.organizationUserId; - request.token = orgInvite.token; - } - // Invite is accepted after login (on deep link redirect). - }; - } - - async ngOnInit() { - await super.ngOnInit(); - this.referenceData = this.referenceDataValue; - if (this.queryParamEmail) { - this.formGroup.get("email")?.setValue(this.queryParamEmail); - } - - if (this.enforcedPolicyOptions != null && this.enforcedPolicyOptions.minLength > 0) { - this.characterMinimumMessage = ""; - } else { - this.characterMinimumMessage = this.i18nService.t("characterMinimum", this.minimumLength); - } - } - - async submit() { - if ( - this.enforcedPolicyOptions != null && - !this.policyService.evaluateMasterPassword( - this.passwordStrengthResult.score, - this.formGroup.value.masterPassword, - this.enforcedPolicyOptions, - ) - ) { - this.toastService.showToast({ - variant: "error", - title: this.i18nService.t("errorOccurred"), - message: this.i18nService.t("masterPasswordPolicyRequirementsNotMet"), - }); - return; - } - - await super.submit(false); - } -} diff --git a/apps/web/src/app/auth/register-form/register-form.module.ts b/apps/web/src/app/auth/register-form/register-form.module.ts deleted file mode 100644 index b63cb18506d..00000000000 --- a/apps/web/src/app/auth/register-form/register-form.module.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { NgModule } from "@angular/core"; - -import { PasswordCalloutComponent } from "@bitwarden/auth/angular"; - -import { SharedModule } from "../../shared"; - -import { RegisterFormComponent } from "./register-form.component"; - -@NgModule({ - imports: [SharedModule, PasswordCalloutComponent], - declarations: [RegisterFormComponent], - exports: [RegisterFormComponent], -}) -export class RegisterFormModule {} 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 9f405c65083..c5edc021614 100644 --- a/apps/web/src/app/auth/settings/account/account.component.html +++ b/apps/web/src/app/auth/settings/account/account.component.html @@ -9,7 +9,7 @@ - + - - - - - - - -
- - -
-
- - - - - - - diff --git a/apps/web/src/app/billing/trial-initiation/trial-initiation.component.spec.ts b/apps/web/src/app/billing/trial-initiation/trial-initiation.component.spec.ts deleted file mode 100644 index c8d4d35fb7d..00000000000 --- a/apps/web/src/app/billing/trial-initiation/trial-initiation.component.spec.ts +++ /dev/null @@ -1,336 +0,0 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore -import { StepperSelectionEvent } from "@angular/cdk/stepper"; -import { TitleCasePipe } from "@angular/common"; -import { NO_ERRORS_SCHEMA } from "@angular/core"; -import { ComponentFixture, fakeAsync, TestBed, tick } from "@angular/core/testing"; -import { FormBuilder, UntypedFormBuilder } from "@angular/forms"; -import { ActivatedRoute, Router } from "@angular/router"; -import { RouterTestingModule } from "@angular/router/testing"; -import { mock, MockProxy } from "jest-mock-extended"; -import { BehaviorSubject, of } from "rxjs"; - -import { I18nPipe } from "@bitwarden/angular/platform/pipes/i18n.pipe"; -import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/policy/policy-api.service.abstraction"; -import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; -import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options"; -import { Policy } from "@bitwarden/common/admin-console/models/domain/policy"; -import { OrganizationBillingServiceAbstraction as OrganizationBillingService } from "@bitwarden/common/billing/abstractions/organization-billing.service"; -import { PlanType } from "@bitwarden/common/billing/enums"; -import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; -import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; - -import { AcceptOrganizationInviteService } from "../../auth/organization-invite/accept-organization.service"; -import { OrganizationInvite } from "../../auth/organization-invite/organization-invite"; -import { RouterService } from "../../core"; -import { SharedModule } from "../../shared"; - -import { TrialInitiationComponent } from "./trial-initiation.component"; -import { VerticalStepperComponent } from "./vertical-stepper/vertical-stepper.component"; - -describe("TrialInitiationComponent", () => { - let component: TrialInitiationComponent; - let fixture: ComponentFixture; - const mockQueryParams = new BehaviorSubject({ org: "enterprise" }); - const testOrgId = "91329456-5b9f-44b3-9279-6bb9ee6a0974"; - const formBuilder: FormBuilder = new FormBuilder(); - let routerSpy: jest.SpyInstance; - - let stateServiceMock: MockProxy; - let policyApiServiceMock: MockProxy; - let policyServiceMock: MockProxy; - let routerServiceMock: MockProxy; - let acceptOrgInviteServiceMock: MockProxy; - let organizationBillingServiceMock: MockProxy; - let configServiceMock: MockProxy; - - beforeEach(() => { - // only define services directly that we want to mock return values in this component - stateServiceMock = mock(); - policyApiServiceMock = mock(); - policyServiceMock = mock(); - routerServiceMock = mock(); - acceptOrgInviteServiceMock = mock(); - organizationBillingServiceMock = mock(); - configServiceMock = mock(); - - // 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 - TestBed.configureTestingModule({ - imports: [ - SharedModule, - RouterTestingModule.withRoutes([ - { path: "trial", component: TrialInitiationComponent }, - { - path: `organizations/${testOrgId}/vault`, - component: BlankComponent, - }, - { - path: `organizations/${testOrgId}/members`, - component: BlankComponent, - }, - ]), - ], - declarations: [TrialInitiationComponent, I18nPipe], - providers: [ - UntypedFormBuilder, - { - provide: ActivatedRoute, - useValue: { - queryParams: mockQueryParams.asObservable(), - }, - }, - { provide: StateService, useValue: stateServiceMock }, - { provide: PolicyService, useValue: policyServiceMock }, - { provide: PolicyApiServiceAbstraction, useValue: policyApiServiceMock }, - { provide: LogService, useValue: mock() }, - { provide: I18nService, useValue: mock() }, - { provide: TitleCasePipe, useValue: mock() }, - { - provide: VerticalStepperComponent, - useClass: VerticalStepperStubComponent, - }, - { - provide: RouterService, - useValue: routerServiceMock, - }, - { - provide: AcceptOrganizationInviteService, - useValue: acceptOrgInviteServiceMock, - }, - { - provide: OrganizationBillingService, - useValue: organizationBillingServiceMock, - }, - { - provide: ConfigService, - useValue: configServiceMock, - }, - ], - schemas: [NO_ERRORS_SCHEMA], // Allows child components to be ignored (such as register component) - }).compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(TrialInitiationComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it("should create", () => { - expect(component).toBeTruthy(); - }); - - // These tests demonstrate mocking service calls - describe("onInit() enforcedPolicyOptions", () => { - it("should not set enforcedPolicyOptions if there isn't an org invite in deep linked url", async () => { - acceptOrgInviteServiceMock.getOrganizationInvite.mockResolvedValueOnce(null); - // Need to recreate component with new service mock - fixture = TestBed.createComponent(TrialInitiationComponent); - component = fixture.componentInstance; - await component.ngOnInit(); - - expect(component.enforcedPolicyOptions).toBe(undefined); - }); - it("should set enforcedPolicyOptions if the deep linked url has an org invite", async () => { - // Set up service method mocks - acceptOrgInviteServiceMock.getOrganizationInvite.mockResolvedValueOnce({ - organizationId: testOrgId, - token: "token", - email: "testEmail", - organizationUserId: "123", - } as OrganizationInvite); - policyApiServiceMock.getPoliciesByToken.mockReturnValueOnce( - Promise.resolve([ - { - id: "345", - organizationId: testOrgId, - type: 1, - data: { - minComplexity: 4, - minLength: 10, - requireLower: null, - requireNumbers: null, - requireSpecial: null, - requireUpper: null, - }, - enabled: true, - }, - ] as Policy[]), - ); - policyServiceMock.masterPasswordPolicyOptions$.mockReturnValue( - of({ - minComplexity: 4, - minLength: 10, - requireLower: null, - requireNumbers: null, - requireSpecial: null, - requireUpper: null, - } as MasterPasswordPolicyOptions), - ); - - // Need to recreate component with new service mocks - fixture = TestBed.createComponent(TrialInitiationComponent); - component = fixture.componentInstance; - await component.ngOnInit(); - expect(component.enforcedPolicyOptions).toMatchObject({ - minComplexity: 4, - minLength: 10, - requireLower: null, - requireNumbers: null, - requireSpecial: null, - requireUpper: null, - }); - }); - }); - - // These tests demonstrate route params - describe("Route params", () => { - it("should set org variable to be enterprise and plan to EnterpriseAnnually if org param is enterprise", fakeAsync(() => { - mockQueryParams.next({ org: "enterprise" }); - tick(); // wait for resolution - fixture = TestBed.createComponent(TrialInitiationComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - expect(component.org).toBe("enterprise"); - expect(component.plan).toBe(PlanType.EnterpriseAnnually); - })); - it("should not set org variable if no org param is provided", fakeAsync(() => { - mockQueryParams.next({}); - tick(); // wait for resolution - fixture = TestBed.createComponent(TrialInitiationComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - expect(component.org).toBe(""); - expect(component.accountCreateOnly).toBe(true); - })); - it("should not set the org if org param is invalid ", fakeAsync(async () => { - mockQueryParams.next({ org: "hahahaha" }); - tick(); // wait for resolution - fixture = TestBed.createComponent(TrialInitiationComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - expect(component.org).toBe(""); - expect(component.accountCreateOnly).toBe(true); - })); - it("should set the layout variable if layout param is valid ", fakeAsync(async () => { - mockQueryParams.next({ layout: "teams1" }); - tick(); // wait for resolution - fixture = TestBed.createComponent(TrialInitiationComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - expect(component.layout).toBe("teams1"); - expect(component.accountCreateOnly).toBe(false); - })); - it("should not set the layout variable and leave as 'default' if layout param is invalid ", fakeAsync(async () => { - mockQueryParams.next({ layout: "asdfasdf" }); - tick(); // wait for resolution - fixture = TestBed.createComponent(TrialInitiationComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - // 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 - component.ngOnInit(); - expect(component.layout).toBe("default"); - expect(component.accountCreateOnly).toBe(true); - })); - }); - - // These tests demonstrate the use of a stub component - describe("createAccount()", () => { - beforeEach(() => { - component.verticalStepper = TestBed.createComponent(VerticalStepperStubComponent) - .componentInstance as VerticalStepperComponent; - }); - - it("should set email and call verticalStepper.next()", fakeAsync(() => { - const verticalStepperNext = jest.spyOn(component.verticalStepper, "next"); - component.createdAccount("test@email.com"); - expect(verticalStepperNext).toHaveBeenCalled(); - expect(component.email).toBe("test@email.com"); - })); - }); - - describe("billingSuccess()", () => { - beforeEach(() => { - component.verticalStepper = TestBed.createComponent(VerticalStepperStubComponent) - .componentInstance as VerticalStepperComponent; - }); - - it("should set orgId and call verticalStepper.next()", () => { - const verticalStepperNext = jest.spyOn(component.verticalStepper, "next"); - component.billingSuccess({ orgId: testOrgId }); - expect(verticalStepperNext).toHaveBeenCalled(); - expect(component.orgId).toBe(testOrgId); - }); - }); - - describe("stepSelectionChange()", () => { - beforeEach(() => { - component.verticalStepper = TestBed.createComponent(VerticalStepperStubComponent) - .componentInstance as VerticalStepperComponent; - }); - - it("on step 2 should show organization copy text", () => { - component.stepSelectionChange({ - selectedIndex: 1, - previouslySelectedIndex: 0, - } as StepperSelectionEvent); - - expect(component.orgInfoSubLabel).toContain("Enter your"); - expect(component.orgInfoSubLabel).toContain(" organization information"); - }); - it("going from step 2 to 3 should set the orgInforSubLabel to be the Org name from orgInfoFormGroup", () => { - component.orgInfoFormGroup = formBuilder.group({ - name: ["Hooli"], - email: [""], - }); - component.stepSelectionChange({ - selectedIndex: 2, - previouslySelectedIndex: 1, - } as StepperSelectionEvent); - - expect(component.orgInfoSubLabel).toContain("Hooli"); - }); - }); - - describe("previousStep()", () => { - beforeEach(() => { - component.verticalStepper = TestBed.createComponent(VerticalStepperStubComponent) - .componentInstance as VerticalStepperComponent; - }); - - it("should call verticalStepper.previous()", fakeAsync(() => { - const verticalStepperPrevious = jest.spyOn(component.verticalStepper, "previous"); - component.previousStep(); - expect(verticalStepperPrevious).toHaveBeenCalled(); - })); - }); - - // These tests demonstrate router navigation - describe("navigation methods", () => { - beforeEach(() => { - component.orgId = testOrgId; - const router = TestBed.inject(Router); - fixture.detectChanges(); - routerSpy = jest.spyOn(router, "navigate"); - }); - describe("navigateToOrgVault", () => { - it("should call verticalStepper.previous()", fakeAsync(() => { - component.navigateToOrgVault(); - expect(routerSpy).toHaveBeenCalledWith(["organizations", testOrgId, "vault"]); - })); - }); - describe("navigateToOrgVault", () => { - it("should call verticalStepper.previous()", fakeAsync(() => { - component.navigateToOrgInvite(); - expect(routerSpy).toHaveBeenCalledWith(["organizations", testOrgId, "members"]); - })); - }); - }); -}); - -export class VerticalStepperStubComponent extends VerticalStepperComponent {} -export class BlankComponent {} // For router tests diff --git a/apps/web/src/app/billing/trial-initiation/trial-initiation.component.ts b/apps/web/src/app/billing/trial-initiation/trial-initiation.component.ts deleted file mode 100644 index 2403c28d267..00000000000 --- a/apps/web/src/app/billing/trial-initiation/trial-initiation.component.ts +++ /dev/null @@ -1,353 +0,0 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore -import { StepperSelectionEvent } from "@angular/cdk/stepper"; -import { TitleCasePipe } from "@angular/common"; -import { Component, OnDestroy, OnInit, ViewChild } from "@angular/core"; -import { UntypedFormBuilder, Validators } from "@angular/forms"; -import { ActivatedRoute, Router } from "@angular/router"; -import { Subject, takeUntil } from "rxjs"; - -import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/policy/policy-api.service.abstraction"; -import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; -import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options"; -import { Policy } from "@bitwarden/common/admin-console/models/domain/policy"; -import { - OrganizationInformation, - PlanInformation, - OrganizationBillingServiceAbstraction as OrganizationBillingService, -} from "@bitwarden/common/billing/abstractions/organization-billing.service"; -import { PlanType, ProductTierType } from "@bitwarden/common/billing/enums"; -import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; -import { ReferenceEventRequest } from "@bitwarden/common/models/request/reference-event.request"; -import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; - -import { AcceptOrganizationInviteService } from "../../auth/organization-invite/accept-organization.service"; -import { OrganizationInvite } from "../../auth/organization-invite/organization-invite"; -import { - OrganizationCreatedEvent, - SubscriptionProduct, - TrialOrganizationType, -} from "../../billing/accounts/trial-initiation/trial-billing-step.component"; - -import { RouterService } from "./../../core/router.service"; -import { VerticalStepperComponent } from "./vertical-stepper/vertical-stepper.component"; - -export enum ValidOrgParams { - families = "families", - enterprise = "enterprise", - teams = "teams", - teamsStarter = "teamsStarter", - individual = "individual", - premium = "premium", - free = "free", -} - -enum ValidLayoutParams { - default = "default", - teams = "teams", - teams1 = "teams1", - teams2 = "teams2", - teams3 = "teams3", - enterprise = "enterprise", - enterprise1 = "enterprise1", - enterprise2 = "enterprise2", - cnetcmpgnent = "cnetcmpgnent", - cnetcmpgnind = "cnetcmpgnind", - cnetcmpgnteams = "cnetcmpgnteams", - abmenterprise = "abmenterprise", - abmteams = "abmteams", - secretsManager = "secretsManager", -} - -@Component({ - selector: "app-trial", - templateUrl: "trial-initiation.component.html", -}) -export class TrialInitiationComponent implements OnInit, OnDestroy { - email = ""; - fromOrgInvite = false; - org = ""; - orgInfoSubLabel = ""; - orgId = ""; - orgLabel = ""; - billingSubLabel = ""; - layout = "default"; - plan: PlanType; - productTier: ProductTierType; - accountCreateOnly = true; - useTrialStepper = false; - loading = false; - policies: Policy[]; - enforcedPolicyOptions: MasterPasswordPolicyOptions; - trialFlowOrgs: string[] = [ - ValidOrgParams.teams, - ValidOrgParams.teamsStarter, - ValidOrgParams.enterprise, - ValidOrgParams.families, - ]; - routeFlowOrgs: string[] = [ - ValidOrgParams.free, - ValidOrgParams.premium, - ValidOrgParams.individual, - ]; - layouts = ValidLayoutParams; - referenceData: ReferenceEventRequest; - @ViewChild("stepper", { static: false }) verticalStepper: VerticalStepperComponent; - - orgInfoFormGroup = this.formBuilder.group({ - name: ["", { validators: [Validators.required, Validators.maxLength(50)], updateOn: "change" }], - email: [""], - }); - - private set referenceDataId(referenceId: string) { - if (referenceId != null) { - this.referenceData.id = referenceId; - } else { - this.referenceData.id = ("; " + document.cookie) - .split("; reference=") - .pop() - .split(";") - .shift(); - } - - if (this.referenceData.id === "") { - this.referenceData.id = null; - } else { - // Matches "_ga_QBRN562QQQ=value1.value2.session" and captures values and session. - const regex = /_ga_QBRN562QQQ=([^.]+)\.([^.]+)\.(\d+)/; - const match = document.cookie.match(regex); - if (match) { - this.referenceData.session = match[3]; - } - } - } - - private destroy$ = new Subject(); - protected enableTrialPayment$ = this.configService.getFeatureFlag$( - FeatureFlag.TrialPaymentOptional, - ); - - constructor( - private route: ActivatedRoute, - protected router: Router, - private formBuilder: UntypedFormBuilder, - private titleCasePipe: TitleCasePipe, - private logService: LogService, - private policyApiService: PolicyApiServiceAbstraction, - private policyService: PolicyService, - private i18nService: I18nService, - private routerService: RouterService, - private acceptOrgInviteService: AcceptOrganizationInviteService, - private organizationBillingService: OrganizationBillingService, - private configService: ConfigService, - ) {} - - async ngOnInit(): Promise { - this.route.queryParams.pipe(takeUntil(this.destroy$)).subscribe((qParams) => { - this.referenceData = new ReferenceEventRequest(); - if (qParams.email != null && qParams.email.indexOf("@") > -1) { - this.email = qParams.email; - this.fromOrgInvite = qParams.fromOrgInvite === "true"; - } - - this.referenceDataId = qParams.reference; - - if (Object.values(ValidLayoutParams).includes(qParams.layout)) { - this.layout = qParams.layout; - this.accountCreateOnly = false; - } - - if (this.trialFlowOrgs.includes(qParams.org)) { - this.org = qParams.org; - this.orgLabel = this.titleCasePipe.transform(this.orgDisplayName); - this.useTrialStepper = true; - this.referenceData.flow = qParams.org; - - if (this.org === ValidOrgParams.families) { - this.plan = PlanType.FamiliesAnnually; - this.productTier = ProductTierType.Families; - } else if (this.org === ValidOrgParams.teamsStarter) { - this.plan = PlanType.TeamsStarter; - this.productTier = ProductTierType.TeamsStarter; - } else if (this.org === ValidOrgParams.teams) { - this.plan = PlanType.TeamsAnnually; - this.productTier = ProductTierType.Teams; - } else if (this.org === ValidOrgParams.enterprise) { - this.plan = PlanType.EnterpriseAnnually; - this.productTier = ProductTierType.Enterprise; - } - } else if (this.routeFlowOrgs.includes(qParams.org)) { - this.referenceData.flow = qParams.org; - const route = this.router.createUrlTree(["create-organization"], { - queryParams: { plan: qParams.org }, - }); - this.routerService.setPreviousUrl(route.toString()); - } - - // Are they coming from an email for sponsoring a families organization - // After logging in redirect them to setup the families sponsorship - this.setupFamilySponsorship(qParams.sponsorshipToken); - - this.referenceData.initiationPath = this.accountCreateOnly - ? "Registration form" - : "Password Manager trial from marketing website"; - }); - - // If there's a deep linked org invite, use it to get the password policies - const orgInvite = await this.acceptOrgInviteService.getOrganizationInvite(); - if (orgInvite != null) { - await this.initPasswordPolicies(orgInvite); - } - - this.orgInfoFormGroup.controls.name.valueChanges - .pipe(takeUntil(this.destroy$)) - .subscribe(() => { - this.orgInfoFormGroup.controls.name.markAsTouched(); - }); - } - - ngOnDestroy(): void { - this.destroy$.next(); - this.destroy$.complete(); - } - - stepSelectionChange(event: StepperSelectionEvent) { - // Set org info sub label - if (event.selectedIndex === 1 && this.orgInfoFormGroup.controls.name.value === "") { - this.orgInfoSubLabel = - "Enter your " + - this.titleCasePipe.transform(this.orgDisplayName) + - " organization information"; - } else if (event.previouslySelectedIndex === 1) { - this.orgInfoSubLabel = this.orgInfoFormGroup.controls.name.value; - } - - //set billing sub label - if (event.selectedIndex === 2) { - this.billingSubLabel = this.i18nService.t("billingTrialSubLabel"); - } - } - - async createOrganizationOnTrial() { - this.loading = true; - const organization: OrganizationInformation = { - name: this.orgInfoFormGroup.get("name").value, - billingEmail: this.orgInfoFormGroup.get("email").value, - initiationPath: "Password Manager trial from marketing website", - }; - - const plan: PlanInformation = { - type: this.plan, - passwordManagerSeats: 1, - }; - - const response = await this.organizationBillingService.purchaseSubscriptionNoPaymentMethod({ - organization, - plan, - }); - - this.orgId = response?.id; - this.billingSubLabel = `${this.i18nService.t("annual")} ($0/${this.i18nService.t("yr")})`; - this.loading = false; - this.verticalStepper.next(); - } - - createdAccount(email: string) { - this.email = email; - this.orgInfoFormGroup.get("email")?.setValue(email); - this.verticalStepper.next(); - } - - billingSuccess(event: any) { - this.orgId = event?.orgId; - this.billingSubLabel = event?.subLabelText; - this.verticalStepper.next(); - } - - createdOrganization(event: OrganizationCreatedEvent) { - this.orgId = event.organizationId; - this.billingSubLabel = event.planDescription; - this.verticalStepper.next(); - } - - navigateToOrgVault() { - // 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(["organizations", this.orgId, "vault"]); - } - - navigateToOrgInvite() { - // 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(["organizations", this.orgId, "members"]); - } - - previousStep() { - this.verticalStepper.previous(); - } - - get orgDisplayName() { - if (this.org === "teamsStarter") { - return "Teams Starter"; - } - - return this.org; - } - - get freeTrialText() { - const translationKey = - this.layout === this.layouts.secretsManager - ? "startYour7DayFreeTrialOfBitwardenSecretsManagerFor" - : "startYour7DayFreeTrialOfBitwardenFor"; - - return this.i18nService.t(translationKey, this.org); - } - - get trialOrganizationType(): TrialOrganizationType { - switch (this.productTier) { - case ProductTierType.Free: - return null; - default: - return this.productTier; - } - } - - private setupFamilySponsorship(sponsorshipToken: string) { - if (sponsorshipToken != null) { - const route = this.router.createUrlTree(["setup/families-for-enterprise"], { - queryParams: { plan: sponsorshipToken }, - }); - this.routerService.setPreviousUrl(route.toString()); - } - } - - private async initPasswordPolicies(invite: OrganizationInvite): Promise { - if (invite == null) { - return; - } - - try { - this.policies = await this.policyApiService.getPoliciesByToken( - invite.organizationId, - invite.token, - invite.email, - invite.organizationUserId, - ); - } catch (e) { - this.logService.error(e); - } - - if (this.policies != null) { - this.policyService - .masterPasswordPolicyOptions$(this.policies) - .pipe(takeUntil(this.destroy$)) - .subscribe((enforcedPasswordPolicyOptions) => { - this.enforcedPolicyOptions = enforcedPasswordPolicyOptions; - }); - } - } - - protected readonly SubscriptionProduct = SubscriptionProduct; -} diff --git a/apps/web/src/app/billing/trial-initiation/trial-initiation.module.ts b/apps/web/src/app/billing/trial-initiation/trial-initiation.module.ts index 7b81f57e33b..3e6bfdc4e6c 100644 --- a/apps/web/src/app/billing/trial-initiation/trial-initiation.module.ts +++ b/apps/web/src/app/billing/trial-initiation/trial-initiation.module.ts @@ -6,8 +6,6 @@ import { InputPasswordComponent } from "@bitwarden/auth/angular"; import { FormFieldModule } from "@bitwarden/components"; import { OrganizationCreateModule } from "../../admin-console/organizations/create/organization-create.module"; -import { RegisterFormModule } from "../../auth/register-form/register-form.module"; -import { TaxInfoComponent } from "../../billing"; import { TrialBillingStepComponent } from "../../billing/accounts/trial-initiation/trial-billing-step.component"; import { SecretsManagerTrialFreeStepperComponent } from "../../billing/trial-initiation/secrets-manager/secrets-manager-trial-free-stepper.component"; import { SecretsManagerTrialPaidStepperComponent } from "../../billing/trial-initiation/secrets-manager/secrets-manager-trial-paid-stepper.component"; @@ -39,7 +37,6 @@ import { TeamsContentComponent } from "./content/teams-content.component"; import { Teams1ContentComponent } from "./content/teams1-content.component"; import { Teams2ContentComponent } from "./content/teams2-content.component"; import { Teams3ContentComponent } from "./content/teams3-content.component"; -import { TrialInitiationComponent } from "./trial-initiation.component"; import { VerticalStepperModule } from "./vertical-stepper/vertical-stepper.module"; @NgModule({ @@ -48,15 +45,12 @@ import { VerticalStepperModule } from "./vertical-stepper/vertical-stepper.modul CdkStepperModule, VerticalStepperModule, FormFieldModule, - RegisterFormModule, OrganizationCreateModule, EnvironmentSelectorModule, - TaxInfoComponent, TrialBillingStepComponent, InputPasswordComponent, ], declarations: [ - TrialInitiationComponent, CompleteTrialInitiationComponent, EnterpriseContentComponent, TeamsContentComponent, @@ -87,7 +81,7 @@ import { VerticalStepperModule } from "./vertical-stepper/vertical-stepper.modul SecretsManagerTrialFreeStepperComponent, SecretsManagerTrialPaidStepperComponent, ], - exports: [TrialInitiationComponent, CompleteTrialInitiationComponent], + exports: [CompleteTrialInitiationComponent], providers: [TitleCasePipe], }) export class TrialInitiationModule {} diff --git a/apps/web/src/app/components/environment-selector/environment-selector.component.html b/apps/web/src/app/components/environment-selector/environment-selector.component.html index 91675bd4945..0c93865c900 100644 --- a/apps/web/src/app/components/environment-selector/environment-selector.component.html +++ b/apps/web/src/app/components/environment-selector/environment-selector.component.html @@ -15,11 +15,11 @@ {{ region.domain }} - diff --git a/apps/web/src/app/core/core.module.ts b/apps/web/src/app/core/core.module.ts index 7b567460dab..be42a9ba34e 100644 --- a/apps/web/src/app/core/core.module.ts +++ b/apps/web/src/app/core/core.module.ts @@ -52,10 +52,10 @@ import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction"; import { ClientType } from "@bitwarden/common/enums"; import { ProcessReloadServiceAbstraction } from "@bitwarden/common/key-management/abstractions/process-reload.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { EnvironmentService, Urls, diff --git a/apps/web/src/app/core/init.service.ts b/apps/web/src/app/core/init.service.ts index 4efec67e767..3623d9b0d2f 100644 --- a/apps/web/src/app/core/init.service.ts +++ b/apps/web/src/app/core/init.service.ts @@ -7,7 +7,7 @@ import { WINDOW } from "@bitwarden/angular/services/injection-tokens"; import { EventUploadService as EventUploadServiceAbstraction } from "@bitwarden/common/abstractions/event/event-upload.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { TwoFactorService as TwoFactorServiceAbstraction } from "@bitwarden/common/auth/abstractions/two-factor.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/platform/abstractions/i18n.service"; import { SdkLoadService } from "@bitwarden/common/platform/abstractions/sdk/sdk-load.service"; import { StateService as StateServiceAbstraction } from "@bitwarden/common/platform/abstractions/state.service"; diff --git a/apps/web/src/app/key-management/key-rotation/user-key-rotation.service.spec.ts b/apps/web/src/app/key-management/key-rotation/user-key-rotation.service.spec.ts index 4f2ae8f77e0..0101bc5aa97 100644 --- a/apps/web/src/app/key-management/key-rotation/user-key-rotation.service.spec.ts +++ b/apps/web/src/app/key-management/key-rotation/user-key-rotation.service.spec.ts @@ -7,8 +7,8 @@ import { OrganizationUserResetPasswordWithIdRequest } from "@bitwarden/admin-con import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { WebauthnRotateCredentialRequest } from "@bitwarden/common/auth/models/request/webauthn-rotate-credential.request"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { SendWithIdRequest } from "@bitwarden/common/tools/send/models/request/send-with-id.request"; diff --git a/apps/web/src/app/key-management/key-rotation/user-key-rotation.service.ts b/apps/web/src/app/key-management/key-rotation/user-key-rotation.service.ts index ae47798420e..1acbc2012c5 100644 --- a/apps/web/src/app/key-management/key-rotation/user-key-rotation.service.ts +++ b/apps/web/src/app/key-management/key-rotation/user-key-rotation.service.ts @@ -8,7 +8,7 @@ import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractio import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { VerificationType } from "@bitwarden/common/auth/enums/verification-type"; import { MasterPasswordVerification } from "@bitwarden/common/auth/types/verification"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { EncryptedString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SendService } from "@bitwarden/common/tools/send/services/send.service.abstraction"; diff --git a/apps/web/src/app/layouts/header/web-header.component.html b/apps/web/src/app/layouts/header/web-header.component.html index 7cba19b29ad..28d786f2d64 100644 --- a/apps/web/src/app/layouts/header/web-header.component.html +++ b/apps/web/src/app/layouts/header/web-header.component.html @@ -12,12 +12,14 @@

- - {{ title || (routeData.titleId | i18n) }} - +
+ + {{ title || (routeData.titleId | i18n) }} +
+

@@ -70,7 +78,11 @@ - + diff --git a/bitwarden_license/bit-web/src/app/tools/access-intelligence/critical-applications.component.ts b/bitwarden_license/bit-web/src/app/tools/access-intelligence/critical-applications.component.ts index 4d820a3cc66..f1fa38dd28f 100644 --- a/bitwarden_license/bit-web/src/app/tools/access-intelligence/critical-applications.component.ts +++ b/bitwarden_license/bit-web/src/app/tools/access-intelligence/critical-applications.component.ts @@ -131,17 +131,17 @@ export class CriticalApplicationsComponent implements OnInit { ?.atRiskMemberDetails ?? [], applicationName, }; - this.dataService.setDrawerForAppAtRiskMembers(data); + this.dataService.setDrawerForAppAtRiskMembers(data, applicationName); }; - showOrgAtRiskMembers = async () => { + showOrgAtRiskMembers = async (invokerId: string) => { const data = this.reportService.generateAtRiskMemberList(this.dataSource.data); - this.dataService.setDrawerForOrgAtRiskMembers(data); + this.dataService.setDrawerForOrgAtRiskMembers(data, invokerId); }; - showOrgAtRiskApps = async () => { + showOrgAtRiskApps = async (invokerId: string) => { const data = this.reportService.generateAtRiskApplicationList(this.dataSource.data); - this.dataService.setDrawerForOrgAtRiskApps(data); + this.dataService.setDrawerForOrgAtRiskApps(data, invokerId); }; trackByFunction(_: number, item: ApplicationHealthReportDetailWithCriticalFlag) { diff --git a/bitwarden_license/bit-web/src/app/tools/access-intelligence/risk-insights.component.html b/bitwarden_license/bit-web/src/app/tools/access-intelligence/risk-insights.component.html index a368f5c0c18..12082e888b0 100644 --- a/bitwarden_license/bit-web/src/app/tools/access-intelligence/risk-insights.component.html +++ b/bitwarden_license/bit-web/src/app/tools/access-intelligence/risk-insights.component.html @@ -56,7 +56,11 @@ - + ; + +export abstract class AdminTaskService { + /** + * Retrieves all tasks for a given organization. + * @param organizationId - The ID of the organization to retrieve tasks for. + * @param status - Optional. The status of the tasks to retrieve. + */ + abstract getAllTasks( + organizationId: OrganizationId, + status?: SecurityTaskStatus | undefined, + ): Promise; + + /** + * Creates multiple tasks for a given organization and sends out notifications to applicable users. + * @param organizationId - The ID of the organization to create tasks for. + * @param tasks - The tasks to create. + */ + abstract bulkCreateTasks( + organizationId: OrganizationId, + tasks: CreateTasksRequest[], + ): Promise; +} diff --git a/bitwarden_license/bit-web/src/app/vault/services/default-admin-task.service.spec.ts b/bitwarden_license/bit-web/src/app/vault/services/default-admin-task.service.spec.ts new file mode 100644 index 00000000000..49a4c16e159 --- /dev/null +++ b/bitwarden_license/bit-web/src/app/vault/services/default-admin-task.service.spec.ts @@ -0,0 +1,65 @@ +import { MockProxy, mock } from "jest-mock-extended"; + +import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { CipherId, OrganizationId } from "@bitwarden/common/types/guid"; +import { SecurityTaskStatus, SecurityTaskType } from "@bitwarden/vault"; + +import { CreateTasksRequest } from "./abstractions/admin-task.abstraction"; +import { DefaultAdminTaskService } from "./default-admin-task.service"; + +describe("DefaultAdminTaskService", () => { + let defaultAdminTaskService: DefaultAdminTaskService; + let apiService: MockProxy; + + beforeEach(() => { + apiService = mock(); + defaultAdminTaskService = new DefaultAdminTaskService(apiService); + }); + + describe("getAllTasks", () => { + it("should call the api service with the correct parameters with status", async () => { + const organizationId = "orgId" as OrganizationId; + const status = SecurityTaskStatus.Pending; + const expectedUrl = `/tasks/organization?organizationId=${organizationId}&status=0`; + + await defaultAdminTaskService.getAllTasks(organizationId, status); + + expect(apiService.send).toHaveBeenCalledWith("GET", expectedUrl, null, true, true); + }); + + it("should call the api service with the correct parameters without status", async () => { + const organizationId = "orgId" as OrganizationId; + const expectedUrl = `/tasks/organization?organizationId=${organizationId}`; + + await defaultAdminTaskService.getAllTasks(organizationId); + + expect(apiService.send).toHaveBeenCalledWith("GET", expectedUrl, null, true, true); + }); + }); + + describe("bulkCreateTasks", () => { + it("should call the api service with the correct parameters", async () => { + const organizationId = "orgId" as OrganizationId; + const tasks: CreateTasksRequest[] = [ + { + cipherId: "cipherId-1" as CipherId, + type: SecurityTaskType.UpdateAtRiskCredential, + }, + { + cipherId: "cipherId-2" as CipherId, + type: SecurityTaskType.UpdateAtRiskCredential, + }, + ]; + + await defaultAdminTaskService.bulkCreateTasks(organizationId, tasks); + + expect(apiService.send).toHaveBeenCalledWith( + "POST", + `/tasks/${organizationId}/bulk-create`, + { tasks }, + true, + true, + ); + }); + }); +}); diff --git a/bitwarden_license/bit-web/src/app/vault/services/default-admin-task.service.ts b/bitwarden_license/bit-web/src/app/vault/services/default-admin-task.service.ts new file mode 100644 index 00000000000..520fb744486 --- /dev/null +++ b/bitwarden_license/bit-web/src/app/vault/services/default-admin-task.service.ts @@ -0,0 +1,54 @@ +import { Injectable } from "@angular/core"; + +import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { ListResponse } from "@bitwarden/common/models/response/list.response"; +import { OrganizationId } from "@bitwarden/common/types/guid"; +import { + SecurityTask, + SecurityTaskData, + SecurityTaskResponse, + SecurityTaskStatus, +} from "@bitwarden/vault"; + +import { AdminTaskService, CreateTasksRequest } from "./abstractions/admin-task.abstraction"; + +@Injectable() +export class DefaultAdminTaskService implements AdminTaskService { + constructor(private apiService: ApiService) {} + + async getAllTasks( + organizationId: OrganizationId, + status?: SecurityTaskStatus | undefined, + ): Promise { + const queryParams = new URLSearchParams(); + + queryParams.append("organizationId", organizationId); + if (status !== undefined) { + queryParams.append("status", status.toString()); + } + + const r = await this.apiService.send( + "GET", + `/tasks/organization?${queryParams.toString()}`, + null, + true, + true, + ); + const response = new ListResponse(r, SecurityTaskResponse); + + return response.data.map((d) => new SecurityTask(new SecurityTaskData(d))); + } + + async bulkCreateTasks( + organizationId: OrganizationId, + tasks: CreateTasksRequest[], + ): Promise { + await this.apiService.send( + "POST", + `/tasks/${organizationId}/bulk-create`, + { tasks }, + true, + true, + ); + } +} diff --git a/bitwarden_license/bit-web/tsconfig.build.json b/bitwarden_license/bit-web/tsconfig.build.json index 9bebbeb5061..6313ce27863 100644 --- a/bitwarden_license/bit-web/tsconfig.build.json +++ b/bitwarden_license/bit-web/tsconfig.build.json @@ -9,6 +9,6 @@ ], "include": [ "../../apps/web/src/connectors/*.ts", - "../../libs/common/src/platform/services/**/*.worker.ts" + "../../libs/common/src/key-management/crypto/services/encrypt.worker.ts" ] } diff --git a/bitwarden_license/bit-web/tsconfig.json b/bitwarden_license/bit-web/tsconfig.json index a2f9c4608c1..82e0b7f57fa 100644 --- a/bitwarden_license/bit-web/tsconfig.json +++ b/bitwarden_license/bit-web/tsconfig.json @@ -21,8 +21,8 @@ "../../libs/tools/export/vault-export/vault-export-core/src" ], "@bitwarden/vault-export-ui": ["../../libs/tools/export/vault-export/vault-export-ui/src"], - "@bitwarden/importer/core": ["../../libs/importer/src"], - "@bitwarden/importer/ui": ["../../libs/importer/src/components"], + "@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"], @@ -46,7 +46,7 @@ "../../apps/web/src/connectors/*.ts", "../../apps/web/src/**/*.stories.ts", "../../apps/web/src/**/*.spec.ts", - "../../libs/common/src/platform/services/**/*.worker.ts", + "../../libs/common/src/key-management/crypto/services/encrypt.worker.ts", "src/**/*.stories.ts", "src/**/*.spec.ts" diff --git a/eslint.config.mjs b/eslint.config.mjs index 514d1ccf0be..2d7c91521f9 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -11,6 +11,8 @@ import rxjs from "eslint-plugin-rxjs"; import angularRxjs from "eslint-plugin-rxjs-angular"; import storybook from "eslint-plugin-storybook"; +import platformPlugins from "./libs/eslint/platform/index.mjs"; + export default tseslint.config( ...storybook.configs["flat/recommended"], { @@ -28,6 +30,7 @@ export default tseslint.config( plugins: { rxjs: rxjs, "rxjs-angular": angularRxjs, + "@bitwarden/platform": platformPlugins, }, languageOptions: { parserOptions: { @@ -66,7 +69,7 @@ export default tseslint.config( "@angular-eslint/no-outputs-metadata-property": 0, "@angular-eslint/use-lifecycle-interface": "error", "@angular-eslint/use-pipe-transform-interface": 0, - + "@bitwarden/platform/required-using": "error", "@typescript-eslint/explicit-member-accessibility": ["error", { accessibility: "no-public" }], "@typescript-eslint/no-explicit-any": "off", // TODO: This should be re-enabled "@typescript-eslint/no-floating-promises": "error", diff --git a/jest.config.js b/jest.config.js index ccde758dbc9..e8815f92ffb 100644 --- a/jest.config.js +++ b/jest.config.js @@ -30,6 +30,7 @@ module.exports = { "/libs/billing/jest.config.js", "/libs/common/jest.config.js", "/libs/components/jest.config.js", + "/libs/eslint/jest.config.js", "/libs/tools/export/vault-export/vault-export-core/jest.config.js", "/libs/tools/generator/core/jest.config.js", "/libs/tools/generator/components/jest.config.js", diff --git a/libs/admin-console/src/common/collections/services/default-collection-admin.service.ts b/libs/admin-console/src/common/collections/services/default-collection-admin.service.ts index 6aafbaf4678..890353d9039 100644 --- a/libs/admin-console/src/common/collections/services/default-collection-admin.service.ts +++ b/libs/admin-console/src/common/collections/services/default-collection-admin.service.ts @@ -2,7 +2,7 @@ // @ts-strict-ignore import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { SelectionReadOnlyRequest } from "@bitwarden/common/admin-console/models/request/selection-read-only.request"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { KeyService } from "@bitwarden/key-management"; diff --git a/libs/admin-console/src/common/collections/services/default-collection.service.spec.ts b/libs/admin-console/src/common/collections/services/default-collection.service.spec.ts index a230a20b2e3..7fe81ade4d2 100644 --- a/libs/admin-console/src/common/collections/services/default-collection.service.spec.ts +++ b/libs/admin-console/src/common/collections/services/default-collection.service.spec.ts @@ -1,7 +1,7 @@ import { mock } from "jest-mock-extended"; import { firstValueFrom, of } from "rxjs"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; diff --git a/libs/admin-console/src/common/collections/services/default-collection.service.ts b/libs/admin-console/src/common/collections/services/default-collection.service.ts index 4070c92f27c..da50a25886e 100644 --- a/libs/admin-console/src/common/collections/services/default-collection.service.ts +++ b/libs/admin-console/src/common/collections/services/default-collection.service.ts @@ -3,7 +3,7 @@ import { combineLatest, firstValueFrom, map, Observable, of, switchMap } from "rxjs"; import { Jsonify } from "type-fest"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { diff --git a/libs/admin-console/src/common/collections/services/default-vnext-collection.service.spec.ts b/libs/admin-console/src/common/collections/services/default-vnext-collection.service.spec.ts index 048a4733948..9700fcb695a 100644 --- a/libs/admin-console/src/common/collections/services/default-vnext-collection.service.spec.ts +++ b/libs/admin-console/src/common/collections/services/default-vnext-collection.service.spec.ts @@ -1,7 +1,7 @@ import { mock, MockProxy } from "jest-mock-extended"; import { first, firstValueFrom, of, ReplaySubject, takeWhile } from "rxjs"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; diff --git a/libs/admin-console/src/common/collections/services/default-vnext-collection.service.ts b/libs/admin-console/src/common/collections/services/default-vnext-collection.service.ts index 2d5a083592b..0ef8ae99ab3 100644 --- a/libs/admin-console/src/common/collections/services/default-vnext-collection.service.ts +++ b/libs/admin-console/src/common/collections/services/default-vnext-collection.service.ts @@ -2,7 +2,7 @@ // @ts-strict-ignore import { combineLatest, filter, firstValueFrom, map } from "rxjs"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { StateProvider, DerivedState } from "@bitwarden/common/platform/state"; diff --git a/libs/angular/src/admin-console/components/collections.component.ts b/libs/angular/src/admin-console/components/collections.component.ts index 52a22ac2946..5f39966468f 100644 --- a/libs/angular/src/admin-console/components/collections.component.ts +++ b/libs/angular/src/admin-console/components/collections.component.ts @@ -7,9 +7,11 @@ import { CollectionService, CollectionView } from "@bitwarden/admin-console/comm import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { Cipher } from "@bitwarden/common/vault/models/domain/cipher"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; @@ -45,11 +47,9 @@ export class CollectionsComponent implements OnInit { } async load() { - this.cipherDomain = await this.loadCipher(); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + this.cipherDomain = await this.loadCipher(activeUserId); this.collectionIds = this.loadCipherCollections(); - const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), - ); this.cipher = await this.cipherDomain.decrypt( await this.cipherService.getKeyForCipherKeyDecryption(this.cipherDomain, activeUserId), ); @@ -95,7 +95,8 @@ export class CollectionsComponent implements OnInit { } this.cipherDomain.collectionIds = selectedCollectionIds; try { - this.formPromise = this.saveCollections(); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + this.formPromise = this.saveCollections(activeUserId); await this.formPromise; this.onSavedCollections.emit(); this.toastService.showToast({ @@ -114,8 +115,8 @@ export class CollectionsComponent implements OnInit { } } - protected loadCipher() { - return this.cipherService.get(this.cipherId); + protected loadCipher(userId: UserId) { + return this.cipherService.get(this.cipherId, userId); } protected loadCipherCollections() { @@ -129,7 +130,7 @@ export class CollectionsComponent implements OnInit { ); } - protected saveCollections() { - return this.cipherService.saveCollectionsWithServer(this.cipherDomain); + protected saveCollections(userId: UserId) { + return this.cipherService.saveCollectionsWithServer(this.cipherDomain, userId); } } diff --git a/libs/angular/src/auth/components/base-login-decryption-options-v1.component.ts b/libs/angular/src/auth/components/base-login-decryption-options-v1.component.ts index ca3906cead3..32396c878d9 100644 --- a/libs/angular/src/auth/components/base-login-decryption-options-v1.component.ts +++ b/libs/angular/src/auth/components/base-login-decryption-options-v1.component.ts @@ -195,7 +195,7 @@ export class BaseLoginDecryptionOptionsComponentV1 implements OnInit, OnDestroy async loadNewUserData() { const autoEnrollStatus$ = defer(() => - this.ssoLoginService.getActiveUserOrganizationSsoIdentifier(), + this.ssoLoginService.getActiveUserOrganizationSsoIdentifier(this.activeAccountId), ).pipe( switchMap((organizationIdentifier) => { if (organizationIdentifier == undefined) { diff --git a/libs/angular/src/auth/components/environment-selector.component.html b/libs/angular/src/auth/components/environment-selector.component.html index 786afe40371..19f49f73dd2 100644 --- a/libs/angular/src/auth/components/environment-selector.component.html +++ b/libs/angular/src/auth/components/environment-selector.component.html @@ -3,7 +3,7 @@ selectedRegion: selectedRegion$ | async, } as data" > -
+
{{ "accessing" | i18n }}:
diff --git a/libs/angular/src/auth/components/two-factor-auth/two-factor-auth.component.ts b/libs/angular/src/auth/components/two-factor-auth/two-factor-auth.component.ts index 6aca189a79e..3e59e4a29b9 100644 --- a/libs/angular/src/auth/components/two-factor-auth/two-factor-auth.component.ts +++ b/libs/angular/src/auth/components/two-factor-auth/two-factor-auth.component.ts @@ -214,7 +214,7 @@ export class TwoFactorAuthComponent extends CaptchaProtectedComponent implements } } - async selectOtherTwofactorMethod() { + async selectOtherTwoFactorMethod() { const dialogRef = TwoFactorOptionsComponent.open(this.dialogService); const response: TwoFactorOptionsDialogResultType = await lastValueFrom(dialogRef.closed); if (response.result === TwoFactorOptionsDialogResult.Provider) { @@ -262,7 +262,8 @@ export class TwoFactorAuthComponent extends CaptchaProtectedComponent implements // Save off the OrgSsoIdentifier for use in the TDE flows // - TDE login decryption options component // - Browser SSO on extension open - await this.ssoLoginService.setActiveUserOrganizationSsoIdentifier(this.orgIdentifier); + const userId = (await firstValueFrom(this.accountService.activeAccount$))?.id; + await this.ssoLoginService.setActiveUserOrganizationSsoIdentifier(this.orgIdentifier, userId); this.loginEmailService.clearValues(); // note: this flow affects both TDE & standard users diff --git a/libs/angular/src/auth/components/two-factor.component.ts b/libs/angular/src/auth/components/two-factor.component.ts index fd5cae506ec..0a3c3cc4a2e 100644 --- a/libs/angular/src/auth/components/two-factor.component.ts +++ b/libs/angular/src/auth/components/two-factor.component.ts @@ -102,6 +102,7 @@ export class TwoFactorComponent extends CaptchaProtectedComponent implements OnI protected toastService: ToastService, ) { super(environmentService, i18nService, platformUtilsService, toastService); + this.webAuthnSupported = this.platformUtilsService.supportsWebAuthn(win); // Add subscription to authenticationSessionTimeout$ and navigate to twoFactorTimeoutRoute if expired @@ -287,7 +288,8 @@ export class TwoFactorComponent extends CaptchaProtectedComponent implements OnI // Save off the OrgSsoIdentifier for use in the TDE flows // - TDE login decryption options component // - Browser SSO on extension open - await this.ssoLoginService.setActiveUserOrganizationSsoIdentifier(this.orgIdentifier); + const userId = (await firstValueFrom(this.accountService.activeAccount$))?.id; + await this.ssoLoginService.setActiveUserOrganizationSsoIdentifier(this.orgIdentifier, userId); this.loginEmailService.clearValues(); // note: this flow affects both TDE & standard users diff --git a/libs/angular/src/components/share.component.ts b/libs/angular/src/components/share.component.ts index 534a1337eda..e785441b8e4 100644 --- a/libs/angular/src/components/share.component.ts +++ b/libs/angular/src/components/share.component.ts @@ -8,6 +8,7 @@ import { OrganizationService } from "@bitwarden/common/admin-console/abstraction import { OrganizationUserStatusType } from "@bitwarden/common/admin-console/enums"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; @@ -73,10 +74,8 @@ export class ShareComponent implements OnInit, OnDestroy { } }); - const cipherDomain = await this.cipherService.get(this.cipherId); - const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), - ); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + const cipherDomain = await this.cipherService.get(this.cipherId, activeUserId); this.cipher = await cipherDomain.decrypt( await this.cipherService.getKeyForCipherKeyDecryption(cipherDomain, activeUserId), ); @@ -104,10 +103,8 @@ export class ShareComponent implements OnInit, OnDestroy { return; } - const cipherDomain = await this.cipherService.get(this.cipherId); - const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), - ); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + const cipherDomain = await this.cipherService.get(this.cipherId, activeUserId); const cipherView = await cipherDomain.decrypt( await this.cipherService.getKeyForCipherKeyDecryption(cipherDomain, activeUserId), ); diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index f3dbdacce4b..d6db49c109d 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -147,13 +147,15 @@ import { BillingApiService } from "@bitwarden/common/billing/services/billing-ap import { OrganizationBillingApiService } from "@bitwarden/common/billing/services/organization/organization-billing-api.service"; import { OrganizationBillingService } from "@bitwarden/common/billing/services/organization-billing.service"; import { TaxService } from "@bitwarden/common/billing/services/tax.service"; +import { BulkEncryptService } from "@bitwarden/common/key-management/crypto/abstractions/bulk-encrypt.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; +import { BulkEncryptServiceImplementation } from "@bitwarden/common/key-management/crypto/services/bulk-encrypt.service.implementation"; +import { MultithreadEncryptServiceImplementation } from "@bitwarden/common/key-management/crypto/services/multithread-encrypt.service.implementation"; import { AppIdService as AppIdServiceAbstraction } from "@bitwarden/common/platform/abstractions/app-id.service"; import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service"; -import { BulkEncryptService } from "@bitwarden/common/platform/abstractions/bulk-encrypt.service"; import { ConfigApiServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config-api.service.abstraction"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { CryptoFunctionService as CryptoFunctionServiceAbstraction } from "@bitwarden/common/platform/abstractions/crypto-function.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { EnvironmentService, RegionConfig, @@ -194,8 +196,6 @@ import { AppIdService } from "@bitwarden/common/platform/services/app-id.service import { ConfigApiService } from "@bitwarden/common/platform/services/config/config-api.service"; import { DefaultConfigService } from "@bitwarden/common/platform/services/config/default-config.service"; import { ConsoleLogService } from "@bitwarden/common/platform/services/console-log.service"; -import { BulkEncryptServiceImplementation } from "@bitwarden/common/platform/services/cryptography/bulk-encrypt.service.implementation"; -import { MultithreadEncryptServiceImplementation } from "@bitwarden/common/platform/services/cryptography/multithread-encrypt.service.implementation"; import { DefaultBroadcasterService } from "@bitwarden/common/platform/services/default-broadcaster.service"; import { DefaultEnvironmentService } from "@bitwarden/common/platform/services/default-environment.service"; import { DefaultServerSettingsService } from "@bitwarden/common/platform/services/default-server-settings.service"; @@ -282,12 +282,6 @@ import { PasswordGenerationServiceAbstraction, UsernameGenerationServiceAbstraction, } from "@bitwarden/generator-legacy"; -import { - ImportApiService, - ImportApiServiceAbstraction, - ImportService, - ImportServiceAbstraction, -} from "@bitwarden/importer/core"; import { KeyService, DefaultKeyService, @@ -302,7 +296,12 @@ import { DefaultUserAsymmetricKeysRegenerationApiService, } from "@bitwarden/key-management"; import { SafeInjectionToken } from "@bitwarden/ui-common"; -import { PasswordRepromptService } from "@bitwarden/vault"; +import { + DefaultTaskService, + NewDeviceVerificationNoticeService, + PasswordRepromptService, + TaskService, +} from "@bitwarden/vault"; import { VaultExportService, VaultExportServiceAbstraction, @@ -312,9 +311,6 @@ import { IndividualVaultExportServiceAbstraction, } from "@bitwarden/vault-export-core"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { NewDeviceVerificationNoticeService } from "../../../vault/src/services/new-device-verification-notice.service"; import { FormValidationErrorsService as FormValidationErrorsServiceAbstraction } from "../platform/abstractions/form-validation-errors.service"; import { ViewCacheService } from "../platform/abstractions/view-cache.service"; import { FormValidationErrorsService } from "../platform/services/form-validation-errors.service"; @@ -805,7 +801,7 @@ const safeProviders: SafeProvider[] = [ safeProvider({ provide: SsoLoginServiceAbstraction, useClass: SsoLoginService, - deps: [StateProvider], + deps: [StateProvider, LogService], }), safeProvider({ provide: STATE_FACTORY, @@ -826,26 +822,6 @@ const safeProviders: SafeProvider[] = [ MigrationRunner, ], }), - safeProvider({ - provide: ImportApiServiceAbstraction, - useClass: ImportApiService, - deps: [ApiServiceAbstraction], - }), - safeProvider({ - provide: ImportServiceAbstraction, - useClass: ImportService, - deps: [ - CipherServiceAbstraction, - FolderServiceAbstraction, - ImportApiServiceAbstraction, - I18nServiceAbstraction, - CollectionService, - KeyService, - EncryptService, - PinServiceAbstraction, - AccountServiceAbstraction, - ], - }), safeProvider({ provide: IndividualVaultExportServiceAbstraction, useClass: IndividualVaultExportService, @@ -1492,6 +1468,11 @@ const safeProviders: SafeProvider[] = [ useClass: PasswordLoginStrategyData, deps: [], }), + safeProvider({ + provide: TaskService, + useClass: DefaultTaskService, + deps: [StateProvider, ApiServiceAbstraction, OrganizationServiceAbstraction, ConfigService], + }), ]; @NgModule({ diff --git a/libs/angular/src/tools/generator/components/generator.component.ts b/libs/angular/src/tools/generator/components/generator.component.ts deleted file mode 100644 index 1f3c635e499..00000000000 --- a/libs/angular/src/tools/generator/components/generator.component.ts +++ /dev/null @@ -1,389 +0,0 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore -import { Directive, EventEmitter, Input, NgZone, OnDestroy, OnInit, Output } from "@angular/core"; -import { ActivatedRoute } from "@angular/router"; -import { BehaviorSubject, combineLatest, firstValueFrom, Subject } from "rxjs"; -import { debounceTime, first, map, skipWhile, takeUntil } from "rxjs/operators"; - -import { PasswordGeneratorPolicyOptions } from "@bitwarden/common/admin-console/models/domain/password-generator-policy-options"; -import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { ToastService } from "@bitwarden/components"; -import { - GeneratorType, - DefaultPasswordBoundaries as DefaultBoundaries, -} from "@bitwarden/generator-core"; -import { - PasswordGenerationServiceAbstraction, - UsernameGenerationServiceAbstraction, - UsernameGeneratorOptions, - PasswordGeneratorOptions, -} from "@bitwarden/generator-legacy"; - -export class EmailForwarderOptions { - name: string; - value: string; - validForSelfHosted: boolean; -} - -@Directive() -export class GeneratorComponent implements OnInit, OnDestroy { - @Input() comingFromAddEdit = false; - @Input() type: GeneratorType | ""; - @Output() onSelected = new EventEmitter(); - - usernameGeneratingPromise: Promise; - typeOptions: any[]; - usernameTypeOptions: any[]; - subaddressOptions: any[]; - catchallOptions: any[]; - forwardOptions: EmailForwarderOptions[]; - usernameOptions: UsernameGeneratorOptions = { website: null }; - passwordOptions: PasswordGeneratorOptions = {}; - username = "-"; - password = "-"; - showOptions = false; - avoidAmbiguous = false; - enforcedPasswordPolicyOptions: PasswordGeneratorPolicyOptions; - usernameWebsite: string = null; - - get passTypeOptions() { - return this._passTypeOptions.filter((o) => !o.disabled); - } - private _passTypeOptions: { name: string; value: GeneratorType; disabled: boolean }[]; - - private destroy$ = new Subject(); - private isInitialized$ = new BehaviorSubject(false); - - // update screen reader minimum password length with 500ms debounce - // so that the user isn't flooded with status updates - private _passwordOptionsMinLengthForReader = new BehaviorSubject( - DefaultBoundaries.length.min, - ); - protected passwordOptionsMinLengthForReader$ = this._passwordOptionsMinLengthForReader.pipe( - map((val) => val || DefaultBoundaries.length.min), - debounceTime(500), - ); - - private _password = new BehaviorSubject("-"); - - constructor( - protected passwordGenerationService: PasswordGenerationServiceAbstraction, - protected usernameGenerationService: UsernameGenerationServiceAbstraction, - protected platformUtilsService: PlatformUtilsService, - protected accountService: AccountService, - protected i18nService: I18nService, - protected logService: LogService, - protected route: ActivatedRoute, - protected ngZone: NgZone, - private win: Window, - protected toastService: ToastService, - ) { - this.typeOptions = [ - { name: i18nService.t("password"), value: "password" }, - { name: i18nService.t("username"), value: "username" }, - ]; - this._passTypeOptions = [ - { name: i18nService.t("password"), value: "password", disabled: false }, - { name: i18nService.t("passphrase"), value: "passphrase", disabled: false }, - ]; - this.usernameTypeOptions = [ - { - name: i18nService.t("plusAddressedEmail"), - value: "subaddress", - desc: i18nService.t("plusAddressedEmailDesc"), - }, - { - name: i18nService.t("catchallEmail"), - value: "catchall", - desc: i18nService.t("catchallEmailDesc"), - }, - { - name: i18nService.t("forwardedEmail"), - value: "forwarded", - desc: i18nService.t("forwardedEmailDesc"), - }, - { name: i18nService.t("randomWord"), value: "word" }, - ]; - this.subaddressOptions = [{ name: i18nService.t("random"), value: "random" }]; - this.catchallOptions = [{ name: i18nService.t("random"), value: "random" }]; - - this.forwardOptions = [ - { name: "", value: "", validForSelfHosted: false }, - { name: "addy.io", value: "anonaddy", validForSelfHosted: true }, - { name: "DuckDuckGo", value: "duckduckgo", validForSelfHosted: false }, - { name: "Fastmail", value: "fastmail", validForSelfHosted: true }, - { name: "Firefox Relay", value: "firefoxrelay", validForSelfHosted: false }, - { name: "SimpleLogin", value: "simplelogin", validForSelfHosted: true }, - { name: "Forward Email", value: "forwardemail", validForSelfHosted: true }, - ].sort((a, b) => a.name.localeCompare(b.name)); - - this._password.pipe(debounceTime(250)).subscribe((password) => { - ngZone.run(() => { - this.password = password; - }); - this.passwordGenerationService.addHistory(this.password).catch((e) => { - this.logService.error(e); - }); - }); - } - - cascadeOptions(navigationType: GeneratorType = undefined, accountEmail: string) { - this.avoidAmbiguous = !this.passwordOptions.ambiguous; - - if (!this.type) { - if (navigationType) { - this.type = navigationType; - } else { - this.type = this.passwordOptions.type === "username" ? "username" : "password"; - } - } - - this.passwordOptions.type = - this.passwordOptions.type === "passphrase" ? "passphrase" : "password"; - - const overrideType = this.enforcedPasswordPolicyOptions.overridePasswordType ?? ""; - const isDisabled = overrideType.length - ? (value: string, policyValue: string) => value !== policyValue - : (_value: string, _policyValue: string) => false; - for (const option of this._passTypeOptions) { - option.disabled = isDisabled(option.value, overrideType); - } - - if (this.usernameOptions.type == null) { - this.usernameOptions.type = "word"; - } - if ( - this.usernameOptions.subaddressEmail == null || - this.usernameOptions.subaddressEmail === "" - ) { - this.usernameOptions.subaddressEmail = accountEmail; - } - if (this.usernameWebsite == null) { - this.usernameOptions.subaddressType = this.usernameOptions.catchallType = "random"; - } else { - this.usernameOptions.website = this.usernameWebsite; - } - } - - async ngOnInit() { - combineLatest([ - this.route.queryParams.pipe(first()), - this.accountService.activeAccount$.pipe(first()), - this.passwordGenerationService.getOptions$(), - this.usernameGenerationService.getOptions$(), - ]) - .pipe( - map(([qParams, account, [passwordOptions, passwordPolicy], usernameOptions]) => ({ - navigationType: qParams.type as GeneratorType, - accountEmail: account.email, - passwordOptions, - passwordPolicy, - usernameOptions, - })), - takeUntil(this.destroy$), - ) - .subscribe((options) => { - this.passwordOptions = options.passwordOptions; - this.enforcedPasswordPolicyOptions = options.passwordPolicy; - this.usernameOptions = options.usernameOptions; - - this.cascadeOptions(options.navigationType, options.accountEmail); - this._passwordOptionsMinLengthForReader.next(this.passwordOptions.minLength); - - if (this.regenerateWithoutButtonPress()) { - this.regenerate().catch((e) => { - this.logService.error(e); - }); - } - - this.isInitialized$.next(true); - }); - - // once initialization is complete, `ngOnInit` should return. - // - // FIXME(#6944): if a sync is in progress, wait to complete until after - // the sync completes. - await firstValueFrom( - this.isInitialized$.pipe( - skipWhile((initialized) => !initialized), - takeUntil(this.destroy$), - ), - ); - - if (this.usernameWebsite !== null) { - const websiteOption = { name: this.i18nService.t("websiteName"), value: "website-name" }; - this.subaddressOptions.push(websiteOption); - this.catchallOptions.push(websiteOption); - } - } - - ngOnDestroy() { - this.destroy$.next(); - this.destroy$.complete(); - this.isInitialized$.complete(); - this._passwordOptionsMinLengthForReader.complete(); - } - - async typeChanged() { - await this.savePasswordOptions(); - } - - async regenerate() { - if (this.type === "password") { - await this.regeneratePassword(); - } else if (this.type === "username") { - await this.regenerateUsername(); - } - } - - async sliderChanged() { - // 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.savePasswordOptions(); - await this.passwordGenerationService.addHistory(this.password); - } - - async onPasswordOptionsMinNumberInput($event: Event) { - // `savePasswordOptions()` replaces the null - this.passwordOptions.number = null; - - await this.savePasswordOptions(); - - // fixes UI desync that occurs when minNumber has a fixed value - // that is reset through normalization - ($event.target as HTMLInputElement).value = `${this.passwordOptions.minNumber}`; - } - - async setPasswordOptionsNumber($event: boolean) { - this.passwordOptions.number = $event; - // `savePasswordOptions()` replaces the null - this.passwordOptions.minNumber = null; - - await this.savePasswordOptions(); - } - - async onPasswordOptionsMinSpecialInput($event: Event) { - // `savePasswordOptions()` replaces the null - this.passwordOptions.special = null; - - await this.savePasswordOptions(); - - // fixes UI desync that occurs when minSpecial has a fixed value - // that is reset through normalization - ($event.target as HTMLInputElement).value = `${this.passwordOptions.minSpecial}`; - } - - async setPasswordOptionsSpecial($event: boolean) { - this.passwordOptions.special = $event; - // `savePasswordOptions()` replaces the null - this.passwordOptions.minSpecial = null; - - await this.savePasswordOptions(); - } - - async sliderInput() { - await this.normalizePasswordOptions(); - } - - async savePasswordOptions() { - // map navigation state into generator type - const restoreType = this.passwordOptions.type; - if (this.type === "username") { - this.passwordOptions.type = this.type; - } - - // save options - await this.normalizePasswordOptions(); - await this.passwordGenerationService.saveOptions(this.passwordOptions); - - // restore the original format - this.passwordOptions.type = restoreType; - } - - async saveUsernameOptions() { - await this.usernameGenerationService.saveOptions(this.usernameOptions); - if (this.usernameOptions.type === "forwarded") { - this.username = "-"; - } - } - - async regeneratePassword() { - this._password.next( - await this.passwordGenerationService.generatePassword(this.passwordOptions), - ); - } - - regenerateUsername() { - return this.generateUsername(); - } - - async generateUsername() { - try { - this.usernameGeneratingPromise = this.usernameGenerationService.generateUsername( - this.usernameOptions, - ); - this.username = await this.usernameGeneratingPromise; - if (this.username === "" || this.username === null) { - this.username = "-"; - } - } catch (e) { - this.logService.error(e); - } - } - - copy() { - const password = this.type === "password"; - const copyOptions = this.win != null ? { window: this.win } : null; - this.platformUtilsService.copyToClipboard( - password ? this.password : this.username, - copyOptions, - ); - this.toastService.showToast({ - variant: "info", - title: null, - message: this.i18nService.t( - "valueCopied", - this.i18nService.t(password ? "password" : "username"), - ), - }); - } - - select() { - this.onSelected.emit(this.type === "password" ? this.password : this.username); - } - - toggleOptions() { - this.showOptions = !this.showOptions; - } - - regenerateWithoutButtonPress() { - return this.type !== "username" || this.usernameOptions.type !== "forwarded"; - } - - private async normalizePasswordOptions() { - // Application level normalize options dependent on class variables - this.passwordOptions.ambiguous = !this.avoidAmbiguous; - - if ( - !this.passwordOptions.uppercase && - !this.passwordOptions.lowercase && - !this.passwordOptions.number && - !this.passwordOptions.special - ) { - this.passwordOptions.lowercase = true; - if (this.win != null) { - const lowercase = this.win.document.querySelector("#lowercase") as HTMLInputElement; - if (lowercase) { - lowercase.checked = true; - } - } - } - - await this.passwordGenerationService.enforcePasswordGeneratorPoliciesOnOptions( - this.passwordOptions, - ); - } -} diff --git a/libs/angular/src/tools/generator/components/password-generator-history.component.ts b/libs/angular/src/tools/generator/components/password-generator-history.component.ts deleted file mode 100644 index 2933163fce2..00000000000 --- a/libs/angular/src/tools/generator/components/password-generator-history.component.ts +++ /dev/null @@ -1,40 +0,0 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore -import { Directive, OnInit } from "@angular/core"; - -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { ToastService } from "@bitwarden/components"; -import { GeneratedPasswordHistory } from "@bitwarden/generator-history"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; - -@Directive() -export class PasswordGeneratorHistoryComponent implements OnInit { - history: GeneratedPasswordHistory[] = []; - - constructor( - protected passwordGenerationService: PasswordGenerationServiceAbstraction, - protected platformUtilsService: PlatformUtilsService, - protected i18nService: I18nService, - private win: Window, - protected toastService: ToastService, - ) {} - - async ngOnInit() { - this.history = await this.passwordGenerationService.getHistory(); - } - - clear = async () => { - this.history = await this.passwordGenerationService.clear(); - }; - - copy(password: string) { - const copyOptions = this.win != null ? { window: this.win } : null; - this.platformUtilsService.copyToClipboard(password, copyOptions); - this.toastService.showToast({ - variant: "info", - title: null, - message: this.i18nService.t("valueCopied", this.i18nService.t("password")), - }); - } -} diff --git a/libs/angular/src/tools/generator/generator-swap.ts b/libs/angular/src/tools/generator/generator-swap.ts deleted file mode 100644 index 16fafc67116..00000000000 --- a/libs/angular/src/tools/generator/generator-swap.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Type, inject } from "@angular/core"; -import { Route, Routes } from "@angular/router"; - -import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; -import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; - -import { componentRouteSwap } from "../../utils/component-route-swap"; - -/** - * Helper function to swap between two components based on the GeneratorToolsModernization feature flag. - * @param defaultComponent - The current non-refreshed component to render. - * @param refreshedComponent - The new refreshed component to render. - * @param options - The shared route options to apply to the default component, and to the alt component if altOptions is not provided. - * @param altOptions - The alt route options to apply to the alt component. - */ -export function generatorSwap( - defaultComponent: Type, - refreshedComponent: Type, - options: Route, - altOptions?: Route, -): Routes { - return componentRouteSwap( - defaultComponent, - refreshedComponent, - async () => { - const configService = inject(ConfigService); - return configService.getFeatureFlag(FeatureFlag.GeneratorToolsModernization); - }, - options, - altOptions, - ); -} diff --git a/libs/angular/src/utils/extension-refresh-redirect.spec.ts b/libs/angular/src/utils/extension-refresh-redirect.spec.ts deleted file mode 100644 index 3291a4496ff..00000000000 --- a/libs/angular/src/utils/extension-refresh-redirect.spec.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { TestBed } from "@angular/core/testing"; -import { Navigation, Router, UrlTree } from "@angular/router"; -import { mock, MockProxy } from "jest-mock-extended"; - -import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; -import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; - -import { extensionRefreshRedirect } from "./extension-refresh-redirect"; - -describe("extensionRefreshRedirect", () => { - let configService: MockProxy; - let router: MockProxy; - - beforeEach(() => { - configService = mock(); - router = mock(); - - TestBed.configureTestingModule({ - providers: [ - { provide: ConfigService, useValue: configService }, - { provide: Router, useValue: router }, - ], - }); - }); - - it("returns true when ExtensionRefresh flag is disabled", async () => { - configService.getFeatureFlag.mockResolvedValue(false); - - const result = await TestBed.runInInjectionContext(() => - extensionRefreshRedirect("/redirect")(), - ); - - expect(result).toBe(true); - expect(configService.getFeatureFlag).toHaveBeenCalledWith(FeatureFlag.ExtensionRefresh); - expect(router.parseUrl).not.toHaveBeenCalled(); - }); - - it("returns UrlTree when ExtensionRefresh flag is enabled and preserves query params", async () => { - configService.getFeatureFlag.mockResolvedValue(true); - - const urlTree = new UrlTree(); - urlTree.queryParams = { test: "test" }; - - const navigation: Navigation = { - extras: {}, - id: 0, - initialUrl: new UrlTree(), - extractedUrl: urlTree, - trigger: "imperative", - previousNavigation: undefined, - }; - - router.getCurrentNavigation.mockReturnValue(navigation); - - await TestBed.runInInjectionContext(() => extensionRefreshRedirect("/redirect")()); - - expect(configService.getFeatureFlag).toHaveBeenCalledWith(FeatureFlag.ExtensionRefresh); - expect(router.createUrlTree).toHaveBeenCalledWith(["/redirect"], { - queryParams: urlTree.queryParams, - }); - }); -}); diff --git a/libs/angular/src/utils/extension-refresh-redirect.ts b/libs/angular/src/utils/extension-refresh-redirect.ts deleted file mode 100644 index 2baa3a3ec89..00000000000 --- a/libs/angular/src/utils/extension-refresh-redirect.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { inject } from "@angular/core"; -import { UrlTree, Router } from "@angular/router"; - -import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; -import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; - -/** - * Helper function to redirect to a new URL based on the ExtensionRefresh feature flag. - * @param redirectUrl - The URL to redirect to if the ExtensionRefresh flag is enabled. - */ -export function extensionRefreshRedirect(redirectUrl: string): () => Promise { - return async () => { - const configService = inject(ConfigService); - const router = inject(Router); - - const shouldRedirect = await configService.getFeatureFlag(FeatureFlag.ExtensionRefresh); - if (shouldRedirect) { - const currentNavigation = router.getCurrentNavigation(); - const queryParams = currentNavigation?.extractedUrl?.queryParams || {}; - - // Preserve query params when redirecting as it is likely that the refreshed component - // will be consuming the same query params. - return router.createUrlTree([redirectUrl], { queryParams }); - } else { - return true; - } - }; -} diff --git a/libs/angular/src/utils/extension-refresh-swap.ts b/libs/angular/src/utils/extension-refresh-swap.ts deleted file mode 100644 index 6512be032d2..00000000000 --- a/libs/angular/src/utils/extension-refresh-swap.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Type, inject } from "@angular/core"; -import { Route, Routes } from "@angular/router"; - -import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; -import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; - -import { componentRouteSwap } from "./component-route-swap"; - -/** - * Helper function to swap between two components based on the ExtensionRefresh feature flag. - * @param defaultComponent - The current non-refreshed component to render. - * @param refreshedComponent - The new refreshed component to render. - * @param options - The shared route options to apply to the default component, and to the alt component if altOptions is not provided. - * @param altOptions - The alt route options to apply to the alt component. - */ -export function extensionRefreshSwap( - defaultComponent: Type, - refreshedComponent: Type, - options: Route, - altOptions?: Route, -): Routes { - return componentRouteSwap( - defaultComponent, - refreshedComponent, - async () => { - const configService = inject(ConfigService); - return configService.getFeatureFlag(FeatureFlag.ExtensionRefresh); - }, - options, - altOptions, - ); -} diff --git a/libs/angular/src/vault/components/add-edit.component.ts b/libs/angular/src/vault/components/add-edit.component.ts index 26f645d89ef..923f667e680 100644 --- a/libs/angular/src/vault/components/add-edit.component.ts +++ b/libs/angular/src/vault/components/add-edit.component.ts @@ -12,6 +12,7 @@ import { PolicyService } from "@bitwarden/common/admin-console/abstractions/poli import { OrganizationUserStatusType, PolicyType } from "@bitwarden/common/admin-console/enums"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { normalizeExpiryYearFormat } from "@bitwarden/common/autofill/utils"; import { EventType } from "@bitwarden/common/enums"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; @@ -101,8 +102,6 @@ export class AddEditComponent implements OnInit, OnDestroy { private personalOwnershipPolicyAppliesToActiveUser: boolean; private previousCipherId: string; - private activeUserId$ = this.accountService.activeAccount$.pipe(map((a) => a?.id)); - get fido2CredentialCreationDateValue(): string { const dateCreated = this.i18nService.t("dateCreated"); const creationDate = this.datePipe.transform( @@ -125,7 +124,7 @@ export class AddEditComponent implements OnInit, OnDestroy { protected policyService: PolicyService, protected logService: LogService, protected passwordRepromptService: PasswordRepromptService, - protected organizationService: OrganizationService, + private organizationService: OrganizationService, protected dialogService: DialogService, protected win: Window, protected datePipe: DatePipe, @@ -263,12 +262,13 @@ export class AddEditComponent implements OnInit, OnDestroy { this.title = this.i18nService.t("addItem"); } - const loadedAddEditCipherInfo = await this.loadAddEditCipherInfo(); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + + const loadedAddEditCipherInfo = await this.loadAddEditCipherInfo(activeUserId); - const activeUserId = await firstValueFrom(this.activeUserId$); if (this.cipher == null) { if (this.editMode) { - const cipher = await this.loadCipher(); + const cipher = await this.loadCipher(activeUserId); this.cipher = await cipher.decrypt( await this.cipherService.getKeyForCipherKeyDecryption(cipher, activeUserId), ); @@ -420,9 +420,7 @@ export class AddEditComponent implements OnInit, OnDestroy { this.cipher.id = null; } - const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), - ); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); const cipher = await this.encryptCipher(activeUserId); try { this.formPromise = this.saveCipher(cipher); @@ -516,7 +514,8 @@ export class AddEditComponent implements OnInit, OnDestroy { } try { - this.deletePromise = this.deleteCipher(); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + this.deletePromise = this.deleteCipher(activeUserId); await this.deletePromise; this.toastService.showToast({ variant: "success", @@ -542,7 +541,8 @@ export class AddEditComponent implements OnInit, OnDestroy { } try { - this.restorePromise = this.restoreCipher(); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + this.restorePromise = this.restoreCipher(activeUserId); await this.restorePromise; this.toastService.showToast({ variant: "success", @@ -725,8 +725,8 @@ export class AddEditComponent implements OnInit, OnDestroy { return allCollections.filter((c) => !c.readOnly); } - protected loadCipher() { - return this.cipherService.get(this.cipherId); + protected loadCipher(userId: UserId) { + return this.cipherService.get(this.cipherId, userId); } protected encryptCipher(userId: UserId) { @@ -746,14 +746,14 @@ export class AddEditComponent implements OnInit, OnDestroy { : this.cipherService.updateWithServer(cipher, orgAdmin); } - protected deleteCipher() { + protected deleteCipher(userId: UserId) { return this.cipher.isDeleted - ? this.cipherService.deleteWithServer(this.cipher.id, this.asAdmin) - : this.cipherService.softDeleteWithServer(this.cipher.id, this.asAdmin); + ? this.cipherService.deleteWithServer(this.cipher.id, userId, this.asAdmin) + : this.cipherService.softDeleteWithServer(this.cipher.id, userId, this.asAdmin); } - protected restoreCipher() { - return this.cipherService.restoreWithServer(this.cipher.id, this.asAdmin); + protected restoreCipher(userId: UserId) { + return this.cipherService.restoreWithServer(this.cipher.id, userId, this.asAdmin); } /** @@ -773,8 +773,10 @@ export class AddEditComponent implements OnInit, OnDestroy { return this.ownershipOptions[0].value; } - async loadAddEditCipherInfo(): Promise { - const addEditCipherInfo: any = await firstValueFrom(this.cipherService.addEditCipherInfo$); + async loadAddEditCipherInfo(userId: UserId): Promise { + const addEditCipherInfo: any = await firstValueFrom( + this.cipherService.addEditCipherInfo$(userId), + ); const loadedSavedInfo = addEditCipherInfo != null; if (loadedSavedInfo) { @@ -787,7 +789,7 @@ export class AddEditComponent implements OnInit, OnDestroy { } } - await this.cipherService.setAddEditCipherInfo(null); + await this.cipherService.setAddEditCipherInfo(null, userId); return loadedSavedInfo; } diff --git a/libs/angular/src/vault/components/attachments.component.ts b/libs/angular/src/vault/components/attachments.component.ts index ec3dc43b447..b1bfcde852a 100644 --- a/libs/angular/src/vault/components/attachments.component.ts +++ b/libs/angular/src/vault/components/attachments.component.ts @@ -1,13 +1,14 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore import { Directive, EventEmitter, Input, OnInit, Output } from "@angular/core"; -import { firstValueFrom, map } from "rxjs"; +import { firstValueFrom } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { getUserId } from "@bitwarden/common/auth/services/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 { ErrorResponse } from "@bitwarden/common/models/response/error.response"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; @@ -84,9 +85,7 @@ export class AttachmentsComponent implements OnInit { } try { - const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), - ); + const activeUserId = await firstValueFrom(getUserId(this.accountService.activeAccount$)); this.formPromise = this.saveCipherAttachment(files[0], activeUserId); this.cipherDomain = await this.formPromise; this.cipher = await this.cipherDomain.decrypt( @@ -125,12 +124,11 @@ export class AttachmentsComponent implements OnInit { } try { - this.deletePromises[attachment.id] = this.deleteCipherAttachment(attachment.id); + const activeUserId = await firstValueFrom(getUserId(this.accountService.activeAccount$)); + + this.deletePromises[attachment.id] = this.deleteCipherAttachment(attachment.id, activeUserId); const updatedCipher = await this.deletePromises[attachment.id]; - const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), - ); const cipher = new Cipher(updatedCipher); this.cipher = await cipher.decrypt( await this.cipherService.getKeyForCipherKeyDecryption(cipher, activeUserId), @@ -228,10 +226,8 @@ export class AttachmentsComponent implements OnInit { } protected async init() { - this.cipherDomain = await this.loadCipher(); - const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), - ); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + this.cipherDomain = await this.loadCipher(activeUserId); this.cipher = await this.cipherDomain.decrypt( await this.cipherService.getKeyForCipherKeyDecryption(this.cipherDomain, activeUserId), ); @@ -287,7 +283,7 @@ export class AttachmentsComponent implements OnInit { : await this.keyService.getOrgKey(this.cipher.organizationId); const decBuf = await this.encryptService.decryptToBytes(encBuf, key); const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), + this.accountService.activeAccount$.pipe(getUserId), ); this.cipherDomain = await this.cipherService.saveAttachmentRawWithServer( this.cipherDomain, @@ -301,7 +297,10 @@ export class AttachmentsComponent implements OnInit { ); // 3. Delete old - this.deletePromises[attachment.id] = this.deleteCipherAttachment(attachment.id); + this.deletePromises[attachment.id] = this.deleteCipherAttachment( + attachment.id, + activeUserId, + ); await this.deletePromises[attachment.id]; const foundAttachment = this.cipher.attachments.filter((a2) => a2.id === attachment.id); if (foundAttachment.length > 0) { @@ -335,16 +334,16 @@ export class AttachmentsComponent implements OnInit { } } - protected loadCipher() { - return this.cipherService.get(this.cipherId); + protected loadCipher(userId: UserId) { + return this.cipherService.get(this.cipherId, userId); } protected saveCipherAttachment(file: File, userId: UserId) { return this.cipherService.saveAttachmentWithServer(this.cipherDomain, file, userId); } - protected deleteCipherAttachment(attachmentId: string) { - return this.cipherService.deleteAttachmentWithServer(this.cipher.id, attachmentId); + protected deleteCipherAttachment(attachmentId: string, userId: UserId) { + return this.cipherService.deleteAttachmentWithServer(this.cipher.id, attachmentId, userId); } protected async reupload(attachment: AttachmentView) { diff --git a/libs/angular/src/vault/components/password-history.component.ts b/libs/angular/src/vault/components/password-history.component.ts index 0b385688d0b..4df9f4bd24d 100644 --- a/libs/angular/src/vault/components/password-history.component.ts +++ b/libs/angular/src/vault/components/password-history.component.ts @@ -1,9 +1,10 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore import { Directive, OnInit } from "@angular/core"; -import { firstValueFrom, map } from "rxjs"; +import { firstValueFrom } from "rxjs"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; @@ -39,10 +40,8 @@ export class PasswordHistoryComponent implements OnInit { } protected async init() { - const cipher = await this.cipherService.get(this.cipherId); - const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), - ); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + const cipher = await this.cipherService.get(this.cipherId, activeUserId); const decCipher = await cipher.decrypt( await this.cipherService.getKeyForCipherKeyDecryption(cipher, activeUserId), ); diff --git a/libs/angular/src/vault/components/vault-items.component.ts b/libs/angular/src/vault/components/vault-items.component.ts index f093aeb1330..fb76ff500eb 100644 --- a/libs/angular/src/vault/components/vault-items.component.ts +++ b/libs/angular/src/vault/components/vault-items.component.ts @@ -2,10 +2,13 @@ // @ts-strict-ignore import { Directive, EventEmitter, Input, OnDestroy, OnInit, Output } from "@angular/core"; import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; -import { BehaviorSubject, Subject, firstValueFrom, from, switchMap, takeUntil } from "rxjs"; +import { BehaviorSubject, Subject, firstValueFrom, from, map, switchMap, takeUntil } from "rxjs"; import { SearchService } from "@bitwarden/common/abstractions/search.service"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { getUserId } from "@bitwarden/common/auth/services/account.service"; +import { UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; @@ -41,11 +44,20 @@ export class VaultItemsComponent implements OnInit, OnDestroy { constructor( protected searchService: SearchService, protected cipherService: CipherService, + protected accountService: AccountService, ) { - this.cipherService.cipherViews$.pipe(takeUntilDestroyed()).subscribe((ciphers) => { - void this.doSearch(ciphers); - this.loaded = true; - }); + this.accountService.activeAccount$ + .pipe( + getUserId, + switchMap((userId) => + this.cipherService.cipherViews$(userId).pipe(map((ciphers) => ({ userId, ciphers }))), + ), + takeUntilDestroyed(), + ) + .subscribe(({ userId, ciphers }) => { + void this.doSearch(ciphers, userId); + this.loaded = true; + }); } ngOnInit(): void { @@ -122,10 +134,16 @@ export class VaultItemsComponent implements OnInit, OnDestroy { protected deletedFilter: (cipher: CipherView) => boolean = (c) => c.isDeleted === this.deleted; - protected async doSearch(indexedCiphers?: CipherView[]) { - indexedCiphers = indexedCiphers ?? (await firstValueFrom(this.cipherService.cipherViews$)); + protected async doSearch(indexedCiphers?: CipherView[], userId?: UserId) { + // Get userId from activeAccount if not provided from parent stream + if (!userId) { + userId = await firstValueFrom(getUserId(this.accountService.activeAccount$)); + } - const failedCiphers = await firstValueFrom(this.cipherService.failedToDecryptCiphers$); + indexedCiphers = + indexedCiphers ?? (await firstValueFrom(this.cipherService.cipherViews$(userId))); + + const failedCiphers = await firstValueFrom(this.cipherService.failedToDecryptCiphers$(userId)); if (failedCiphers != null && failedCiphers.length > 0) { indexedCiphers = [...failedCiphers, ...indexedCiphers]; } diff --git a/libs/angular/src/vault/components/view.component.ts b/libs/angular/src/vault/components/view.component.ts index abbedf13078..637596256b0 100644 --- a/libs/angular/src/vault/components/view.component.ts +++ b/libs/angular/src/vault/components/view.component.ts @@ -11,29 +11,30 @@ import { OnInit, Output, } from "@angular/core"; -import { filter, firstValueFrom, map, Observable } from "rxjs"; +import { filter, firstValueFrom, map, Observable, Subject, takeUntil } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { AuditService } from "@bitwarden/common/abstractions/audit.service"; import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; +import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { EventType } from "@bitwarden/common/enums"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { ErrorResponse } from "@bitwarden/common/models/response/error.response"; import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { EncArrayBuffer } from "@bitwarden/common/platform/models/domain/enc-array-buffer"; -import { CollectionId } from "@bitwarden/common/types/guid"; +import { CollectionId, UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; import { TotpService } from "@bitwarden/common/vault/abstractions/totp.service"; -import { FieldType, CipherType } from "@bitwarden/common/vault/enums"; +import { CipherType, FieldType } from "@bitwarden/common/vault/enums"; import { CipherRepromptType } from "@bitwarden/common/vault/enums/cipher-reprompt-type"; import { Launchable } from "@bitwarden/common/vault/interfaces/launchable"; import { AttachmentView } from "@bitwarden/common/vault/models/view/attachment.view"; @@ -65,7 +66,6 @@ export class ViewComponent implements OnDestroy, OnInit { showPrivateKey: boolean; canAccessPremium: boolean; showPremiumRequiredTotp: boolean; - showUpgradeRequiredTotp: boolean; totpCode: string; totpCodeFormatted: string; totpDash: number; @@ -80,7 +80,7 @@ export class ViewComponent implements OnDestroy, OnInit { private previousCipherId: string; private passwordReprompted = false; - private activeUserId$ = this.accountService.activeAccount$.pipe(map((a) => a?.id)); + private destroyed$ = new Subject(); get fido2CredentialCreationDateValue(): string { const dateCreated = this.i18nService.t("dateCreated"); @@ -144,38 +144,39 @@ export class ViewComponent implements OnDestroy, OnInit { async load() { this.cleanUp(); - const activeUserId = await firstValueFrom(this.activeUserId$); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); // Grab individual cipher from `cipherViews$` for the most up-to-date information - this.cipher = await firstValueFrom( - this.cipherService.cipherViews$.pipe( - map((ciphers) => ciphers.find((c) => c.id === this.cipherId)), + this.cipherService + .cipherViews$(activeUserId) + .pipe( + map((ciphers) => ciphers?.find((c) => c.id === this.cipherId)), filter((cipher) => !!cipher), - ), - ); + takeUntil(this.destroyed$), + ) + .subscribe((cipher) => { + this.cipher = cipher; + }); this.canAccessPremium = await firstValueFrom( this.billingAccountProfileStateService.hasPremiumFromAnySource$(activeUserId), ); this.showPremiumRequiredTotp = - this.cipher.login.totp && !this.canAccessPremium && !this.cipher.organizationId; + this.cipher.login.totp && !this.canAccessPremium && !this.cipher.organizationUseTotp; this.canDeleteCipher$ = this.cipherAuthorizationService.canDeleteCipher$(this.cipher, [ this.collectionId as CollectionId, ]); - this.showUpgradeRequiredTotp = - this.cipher.login.totp && this.cipher.organizationId && !this.cipher.organizationUseTotp; - if (this.cipher.folderId) { this.folder = await ( await firstValueFrom(this.folderService.folderViews$(activeUserId)) ).find((f) => f.id == this.cipher.folderId); } - const canGenerateTotp = this.cipher.organizationId - ? this.cipher.organizationUseTotp - : this.canAccessPremium; - - if (this.cipher.type === CipherType.Login && this.cipher.login.totp && canGenerateTotp) { + if ( + this.cipher.type === CipherType.Login && + this.cipher.login.totp && + (this.cipher.organizationUseTotp || this.canAccessPremium) + ) { await this.totpUpdateCode(); const interval = this.totpService.getTimeInterval(this.cipher.login.totp); await this.totpTick(interval); @@ -250,7 +251,8 @@ export class ViewComponent implements OnDestroy, OnInit { } try { - await this.deleteCipher(); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + await this.deleteCipher(activeUserId); this.toastService.showToast({ variant: "success", title: null, @@ -272,7 +274,8 @@ export class ViewComponent implements OnDestroy, OnInit { } try { - await this.restoreCipher(); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + await this.restoreCipher(activeUserId); this.toastService.showToast({ variant: "success", title: null, @@ -380,7 +383,8 @@ export class ViewComponent implements OnDestroy, OnInit { } if (cipherId) { - await this.cipherService.updateLastLaunchedDate(cipherId); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + await this.cipherService.updateLastLaunchedDate(cipherId, activeUserId); } this.platformUtilsService.launchUri(uri.launchUri); @@ -498,14 +502,14 @@ export class ViewComponent implements OnDestroy, OnInit { a.downloading = false; } - protected deleteCipher() { + protected deleteCipher(userId: UserId) { return this.cipher.isDeleted - ? this.cipherService.deleteWithServer(this.cipher.id) - : this.cipherService.softDeleteWithServer(this.cipher.id); + ? this.cipherService.deleteWithServer(this.cipher.id, userId) + : this.cipherService.softDeleteWithServer(this.cipher.id, userId); } - protected restoreCipher() { - return this.cipherService.restoreWithServer(this.cipher.id); + protected restoreCipher(userId: UserId) { + return this.cipherService.restoreWithServer(this.cipher.id, userId); } protected async promptPassword() { @@ -524,6 +528,7 @@ export class ViewComponent implements OnDestroy, OnInit { this.showCardNumber = false; this.showCardCode = false; this.passwordReprompted = false; + this.destroyed$.next(); if (this.totpInterval) { clearInterval(this.totpInterval); } diff --git a/libs/angular/src/vault/guards/new-device-verification-notice.guard.spec.ts b/libs/angular/src/vault/guards/new-device-verification-notice.guard.spec.ts index ba19cf808ee..938d5b32527 100644 --- a/libs/angular/src/vault/guards/new-device-verification-notice.guard.spec.ts +++ b/libs/angular/src/vault/guards/new-device-verification-notice.guard.spec.ts @@ -2,16 +2,13 @@ import { TestBed } from "@angular/core/testing"; import { ActivatedRouteSnapshot, Router, RouterStateSnapshot } from "@angular/router"; import { BehaviorSubject } from "rxjs"; -import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; -import { PolicyType } from "@bitwarden/common/admin-console/enums"; import { Account, AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { NewDeviceVerificationNoticeService } from "@bitwarden/vault"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { NewDeviceVerificationNoticeService } from "../../../../vault/src/services/new-device-verification-notice.service"; import { VaultProfileService } from "../services/vault-profile.service"; import { NewDeviceVerificationNoticeGuard } from "./new-device-verification-notice.guard"; @@ -36,19 +33,23 @@ describe("NewDeviceVerificationNoticeGuard", () => { return Promise.resolve(false); }); - const isSelfHost = jest.fn().mockResolvedValue(false); + const isSelfHost = jest.fn().mockReturnValue(false); const getProfileTwoFactorEnabled = jest.fn().mockResolvedValue(false); - const policyAppliesToActiveUser$ = jest.fn().mockReturnValue(new BehaviorSubject(false)); const noticeState$ = jest.fn().mockReturnValue(new BehaviorSubject(null)); const getProfileCreationDate = jest.fn().mockResolvedValue(eightDaysAgo); + const hasMasterPasswordAndMasterKeyHash = jest.fn().mockResolvedValue(true); + const getUserSSOBound = jest.fn().mockResolvedValue(false); + const getUserSSOBoundAdminOwner = jest.fn().mockResolvedValue(false); beforeEach(() => { getFeatureFlag.mockClear(); isSelfHost.mockClear(); getProfileCreationDate.mockClear(); getProfileTwoFactorEnabled.mockClear(); - policyAppliesToActiveUser$.mockClear(); createUrlTree.mockClear(); + hasMasterPasswordAndMasterKeyHash.mockClear(); + getUserSSOBound.mockClear(); + getUserSSOBoundAdminOwner.mockClear(); TestBed.configureTestingModule({ providers: [ @@ -57,10 +58,15 @@ describe("NewDeviceVerificationNoticeGuard", () => { { provide: NewDeviceVerificationNoticeService, useValue: { noticeState$ } }, { provide: AccountService, useValue: { activeAccount$ } }, { provide: PlatformUtilsService, useValue: { isSelfHost } }, - { provide: PolicyService, useValue: { policyAppliesToActiveUser$ } }, + { provide: UserVerificationService, useValue: { hasMasterPasswordAndMasterKeyHash } }, { provide: VaultProfileService, - useValue: { getProfileCreationDate, getProfileTwoFactorEnabled }, + useValue: { + getProfileCreationDate, + getProfileTwoFactorEnabled, + getUserSSOBound, + getUserSSOBoundAdminOwner, + }, }, ], }); @@ -92,7 +98,7 @@ describe("NewDeviceVerificationNoticeGuard", () => { expect(isSelfHost).not.toHaveBeenCalled(); expect(getProfileTwoFactorEnabled).not.toHaveBeenCalled(); expect(getProfileCreationDate).not.toHaveBeenCalled(); - expect(policyAppliesToActiveUser$).not.toHaveBeenCalled(); + expect(hasMasterPasswordAndMasterKeyHash).not.toHaveBeenCalled(); }); }); @@ -123,13 +129,6 @@ describe("NewDeviceVerificationNoticeGuard", () => { expect(await newDeviceGuard()).toBe(true); }); - it("returns `true` SSO is required", async () => { - policyAppliesToActiveUser$.mockReturnValueOnce(new BehaviorSubject(true)); - - expect(await newDeviceGuard()).toBe(true); - expect(policyAppliesToActiveUser$).toHaveBeenCalledWith(PolicyType.RequireSso); - }); - it("returns `true` when the profile was created less than a week ago", async () => { const sixDaysAgo = new Date(); sixDaysAgo.setDate(sixDaysAgo.getDate() - 6); @@ -139,6 +138,63 @@ describe("NewDeviceVerificationNoticeGuard", () => { expect(await newDeviceGuard()).toBe(true); }); + it("returns `true` when the profile service throws an error", async () => { + getProfileCreationDate.mockRejectedValueOnce(new Error("test")); + + expect(await newDeviceGuard()).toBe(true); + }); + + describe("SSO bound", () => { + beforeEach(() => { + getFeatureFlag.mockImplementation((key) => { + if (key === FeatureFlag.NewDeviceVerificationPermanentDismiss) { + return Promise.resolve(true); + } + + return Promise.resolve(false); + }); + }); + + afterAll(() => { + getFeatureFlag.mockReturnValue(false); + }); + + it('returns "true" when the user is SSO bound and not an admin or owner', async () => { + getUserSSOBound.mockResolvedValueOnce(true); + getUserSSOBoundAdminOwner.mockResolvedValueOnce(false); + + expect(await newDeviceGuard()).toBe(true); + }); + + it('returns "true" when the user is an admin or owner of an SSO bound organization and has not logged in with their master password', async () => { + getUserSSOBound.mockResolvedValueOnce(true); + getUserSSOBoundAdminOwner.mockResolvedValueOnce(true); + hasMasterPasswordAndMasterKeyHash.mockResolvedValueOnce(false); + + expect(await newDeviceGuard()).toBe(true); + }); + + it("shows notice when the user is an admin or owner of an SSO bound organization and logged in with their master password", async () => { + getUserSSOBound.mockResolvedValueOnce(true); + getUserSSOBoundAdminOwner.mockResolvedValueOnce(true); + hasMasterPasswordAndMasterKeyHash.mockResolvedValueOnce(true); + + await newDeviceGuard(); + + expect(createUrlTree).toHaveBeenCalledWith(["/new-device-notice"]); + }); + + it("shows notice when the user that is not in an SSO bound organization", async () => { + getUserSSOBound.mockResolvedValueOnce(false); + getUserSSOBoundAdminOwner.mockResolvedValueOnce(false); + hasMasterPasswordAndMasterKeyHash.mockResolvedValueOnce(true); + + await newDeviceGuard(); + + expect(createUrlTree).toHaveBeenCalledWith(["/new-device-notice"]); + }); + }); + describe("temp flag", () => { beforeEach(() => { getFeatureFlag.mockImplementation((key) => { diff --git a/libs/angular/src/vault/guards/new-device-verification-notice.guard.ts b/libs/angular/src/vault/guards/new-device-verification-notice.guard.ts index 8b406877a12..8d4a7742bc5 100644 --- a/libs/angular/src/vault/guards/new-device-verification-notice.guard.ts +++ b/libs/angular/src/vault/guards/new-device-verification-notice.guard.ts @@ -1,17 +1,14 @@ import { inject } from "@angular/core"; import { ActivatedRouteSnapshot, CanActivateFn, Router } from "@angular/router"; -import { Observable, firstValueFrom } from "rxjs"; +import { firstValueFrom, Observable } from "rxjs"; -import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; -import { PolicyType } from "@bitwarden/common/admin-console/enums"; import { Account, AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { NewDeviceVerificationNoticeService } from "@bitwarden/vault"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { NewDeviceVerificationNoticeService } from "../../../../vault/src/services/new-device-verification-notice.service"; import { VaultProfileService } from "../services/vault-profile.service"; export const NewDeviceVerificationNoticeGuard: CanActivateFn = async ( @@ -22,8 +19,8 @@ export const NewDeviceVerificationNoticeGuard: CanActivateFn = async ( const newDeviceVerificationNoticeService = inject(NewDeviceVerificationNoticeService); const accountService = inject(AccountService); const platformUtilsService = inject(PlatformUtilsService); - const policyService = inject(PolicyService); const vaultProfileService = inject(VaultProfileService); + const userVerificationService = inject(UserVerificationService); if (route.queryParams["fromNewDeviceVerification"]) { return true; @@ -47,17 +44,28 @@ export const NewDeviceVerificationNoticeGuard: CanActivateFn = async ( return router.createUrlTree(["/login"]); } - const has2FAEnabled = await hasATwoFactorProviderEnabled(vaultProfileService, currentAcct.id); - const isSelfHosted = await platformUtilsService.isSelfHost(); - const requiresSSO = await isSSORequired(policyService); - const isProfileLessThanWeekOld = await profileIsLessThanWeekOld( - vaultProfileService, - currentAcct.id, - ); + try { + const isSelfHosted = platformUtilsService.isSelfHost(); + const userIsSSOUser = await ssoAppliesToUser( + userVerificationService, + vaultProfileService, + currentAcct.id, + ); + const has2FAEnabled = await hasATwoFactorProviderEnabled(vaultProfileService, currentAcct.id); + const isProfileLessThanWeekOld = await profileIsLessThanWeekOld( + vaultProfileService, + currentAcct.id, + ); - // When any of the following are true, the device verification notice is - // not applicable for the user. - if (has2FAEnabled || isSelfHosted || requiresSSO || isProfileLessThanWeekOld) { + // When any of the following are true, the device verification notice is + // not applicable for the user. When the user has *not* logged in with their + // master password, assume they logged in with SSO. + if (has2FAEnabled || isSelfHosted || userIsSSOUser || isProfileLessThanWeekOld) { + return true; + } + } catch { + // Skip showing the notice if there was a problem determining applicability + // The most likely problem to occur is the user not having a network connection return true; } @@ -101,9 +109,39 @@ async function profileIsLessThanWeekOld( return !isMoreThan7DaysAgo(creationDate); } -/** Returns true when the user is required to login via SSO */ -async function isSSORequired(policyService: PolicyService) { - return firstValueFrom(policyService.policyAppliesToActiveUser$(PolicyType.RequireSso)); +/** + * Returns true when either: + * - The user is SSO bound to an organization and is not an Admin or Owner + * - The user is an Admin or Owner of an organization with SSO bound and has not logged in with their master password + * + * NOTE: There are edge cases where this does not satisfy the original requirement of showing the notice to + * users who are subject to the SSO required policy. When Owners and Admins log in with their MP they will see the notice + * when they log in with SSO they will not. This is a concession made because the original logic references policies would not work for TDE users. + * When this guard is run for those users a sync hasn't occurred and thus the policies are not available. + */ +async function ssoAppliesToUser( + userVerificationService: UserVerificationService, + vaultProfileService: VaultProfileService, + userId: string, +) { + const userSSOBound = await vaultProfileService.getUserSSOBound(userId); + const userSSOBoundAdminOwner = await vaultProfileService.getUserSSOBoundAdminOwner(userId); + const userLoggedInWithMP = await userLoggedInWithMasterPassword(userVerificationService, userId); + + const nonOwnerAdminSsoUser = userSSOBound && !userSSOBoundAdminOwner; + const ssoAdminOwnerLoggedInWithMP = userSSOBoundAdminOwner && !userLoggedInWithMP; + + return nonOwnerAdminSsoUser || ssoAdminOwnerLoggedInWithMP; +} + +/** + * Returns true when the user logged in with their master password. + */ +async function userLoggedInWithMasterPassword( + userVerificationService: UserVerificationService, + userId: string, +) { + return userVerificationService.hasMasterPasswordAndMasterKeyHash(userId); } /** Returns the true when the date given is older than 7 days */ diff --git a/libs/angular/src/vault/services/vault-profile.service.spec.ts b/libs/angular/src/vault/services/vault-profile.service.spec.ts index 7761503253a..ade34da39a6 100644 --- a/libs/angular/src/vault/services/vault-profile.service.spec.ts +++ b/libs/angular/src/vault/services/vault-profile.service.spec.ts @@ -1,6 +1,7 @@ import { TestBed } from "@angular/core/testing"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { OrganizationUserType } from "@bitwarden/common/admin-console/enums"; import { VaultProfileService } from "./vault-profile.service"; @@ -13,6 +14,12 @@ describe("VaultProfileService", () => { creationDate: hardcodedDateString, twoFactorEnabled: true, id: "new-user-id", + organizations: [ + { + ssoBound: true, + type: OrganizationUserType.Admin, + }, + ], }); beforeEach(() => { @@ -91,4 +98,64 @@ describe("VaultProfileService", () => { expect(getProfile).not.toHaveBeenCalled(); }); }); + + describe("getUserSSOBound", () => { + it("calls `getProfile` when stored ssoBound property is not stored", async () => { + expect(service["userIsSsoBound"]).toBeNull(); + + const userIsSsoBound = await service.getUserSSOBound(userId); + + expect(userIsSsoBound).toBe(true); + expect(getProfile).toHaveBeenCalled(); + }); + + it("calls `getProfile` when stored profile id does not match", async () => { + service["userIsSsoBound"] = false; + service["userId"] = "old-user-id"; + + const userIsSsoBound = await service.getUserSSOBound(userId); + + expect(userIsSsoBound).toBe(true); + expect(getProfile).toHaveBeenCalled(); + }); + + it("does not call `getProfile` when ssoBound property is already stored", async () => { + service["userIsSsoBound"] = false; + + const userIsSsoBound = await service.getUserSSOBound(userId); + + expect(userIsSsoBound).toBe(false); + expect(getProfile).not.toHaveBeenCalled(); + }); + }); + + describe("getUserSSOBoundAdminOwner", () => { + it("calls `getProfile` when stored userIsSsoBoundAdminOwner property is not stored", async () => { + expect(service["userIsSsoBoundAdminOwner"]).toBeNull(); + + const userIsSsoBoundAdminOwner = await service.getUserSSOBoundAdminOwner(userId); + + expect(userIsSsoBoundAdminOwner).toBe(true); + expect(getProfile).toHaveBeenCalled(); + }); + + it("calls `getProfile` when stored profile id does not match", async () => { + service["userIsSsoBoundAdminOwner"] = false; + service["userId"] = "old-user-id"; + + const userIsSsoBoundAdminOwner = await service.getUserSSOBoundAdminOwner(userId); + + expect(userIsSsoBoundAdminOwner).toBe(true); + expect(getProfile).toHaveBeenCalled(); + }); + + it("does not call `getProfile` when userIsSsoBoundAdminOwner property is already stored", async () => { + service["userIsSsoBoundAdminOwner"] = false; + + const userIsSsoBoundAdminOwner = await service.getUserSSOBoundAdminOwner(userId); + + expect(userIsSsoBoundAdminOwner).toBe(false); + expect(getProfile).not.toHaveBeenCalled(); + }); + }); }); diff --git a/libs/angular/src/vault/services/vault-profile.service.ts b/libs/angular/src/vault/services/vault-profile.service.ts index b368a973781..21f4ecc2285 100644 --- a/libs/angular/src/vault/services/vault-profile.service.ts +++ b/libs/angular/src/vault/services/vault-profile.service.ts @@ -1,6 +1,7 @@ import { Injectable, inject } from "@angular/core"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { OrganizationUserType } from "@bitwarden/common/admin-console/enums"; import { ProfileResponse } from "@bitwarden/common/models/response/profile.response"; @Injectable({ @@ -24,6 +25,12 @@ export class VaultProfileService { /** True when 2FA is enabled on the profile. */ private profile2FAEnabled: boolean | null = null; + /** True when ssoBound is true for any of the users organizations */ + private userIsSsoBound: boolean | null = null; + + /** True when the user is an admin or owner of the ssoBound organization */ + private userIsSsoBoundAdminOwner: boolean | null = null; + /** * Returns the creation date of the profile. * Note: `Date`s are mutable in JS, creating a new @@ -52,12 +59,43 @@ export class VaultProfileService { return profile.twoFactorEnabled; } + /** + * Returns whether the user logs in with SSO for any organization. + */ + async getUserSSOBound(userId: string): Promise { + if (this.userIsSsoBound !== null && userId === this.userId) { + return Promise.resolve(this.userIsSsoBound); + } + + await this.fetchAndCacheProfile(); + + return !!this.userIsSsoBound; + } + + /** + * Returns true when the user is an Admin or Owner of an organization with `ssoBound` true. + */ + async getUserSSOBoundAdminOwner(userId: string): Promise { + if (this.userIsSsoBoundAdminOwner !== null && userId === this.userId) { + return Promise.resolve(this.userIsSsoBoundAdminOwner); + } + + await this.fetchAndCacheProfile(); + + return !!this.userIsSsoBoundAdminOwner; + } + private async fetchAndCacheProfile(): Promise { const profile = await this.apiService.getProfile(); this.userId = profile.id; this.profileCreatedDate = profile.creationDate; this.profile2FAEnabled = profile.twoFactorEnabled; + const ssoBoundOrg = profile.organizations.find((org) => org.ssoBound); + this.userIsSsoBound = !!ssoBoundOrg; + this.userIsSsoBoundAdminOwner = + ssoBoundOrg?.type === OrganizationUserType.Admin || + ssoBoundOrg?.type === OrganizationUserType.Owner; return profile; } diff --git a/libs/angular/src/vault/vault-filter/services/vault-filter.service.ts b/libs/angular/src/vault/vault-filter/services/vault-filter.service.ts index 96fb74ba96b..d175942c475 100644 --- a/libs/angular/src/vault/vault-filter/services/vault-filter.service.ts +++ b/libs/angular/src/vault/vault-filter/services/vault-filter.service.ts @@ -11,19 +11,17 @@ import { Organization } from "@bitwarden/common/admin-console/models/domain/orga import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { ActiveUserState, StateProvider } from "@bitwarden/common/platform/state"; +import { UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; import { TreeNode } from "@bitwarden/common/vault/models/domain/tree-node"; import { FolderView } from "@bitwarden/common/vault/models/view/folder.view"; import { ServiceUtils } from "@bitwarden/common/vault/service-utils"; +import { COLLAPSED_GROUPINGS } from "@bitwarden/common/vault/services/key-state/collapsed-groupings.state"; import { DeprecatedVaultFilterService as DeprecatedVaultFilterServiceAbstraction } from "../../abstractions/deprecated-vault-filter.service"; import { DynamicTreeNode } from "../models/dynamic-tree-node.model"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { COLLAPSED_GROUPINGS } from "./../../../../../common/src/vault/services/key-state/collapsed-groupings.state"; - const NestingDelimiter = "/"; @Injectable() @@ -33,8 +31,6 @@ export class VaultFilterService implements DeprecatedVaultFilterServiceAbstracti private readonly collapsedGroupings$: Observable> = this.collapsedGroupingsState.state$.pipe(map((c) => new Set(c))); - private activeUserId$ = this.accountService.activeAccount$.pipe(map((a) => a?.id)); - constructor( protected organizationService: OrganizationService, protected folderService: FolderService, @@ -66,7 +62,7 @@ export class VaultFilterService implements DeprecatedVaultFilterServiceAbstracti } buildNestedFolders(organizationId?: string): Observable> { - const transformation = async (storedFolders: FolderView[]) => { + const transformation = async (storedFolders: FolderView[], userId: UserId) => { let folders: FolderView[]; // If no org or "My Vault" is selected, show all folders @@ -74,7 +70,7 @@ export class VaultFilterService implements DeprecatedVaultFilterServiceAbstracti folders = storedFolders; } else { // Otherwise, show only folders that have ciphers from the selected org and the "no folder" folder - const ciphers = await this.cipherService.getAllDecrypted(); + const ciphers = await this.cipherService.getAllDecrypted(userId); const orgCiphers = ciphers.filter((c) => c.organizationId == organizationId); folders = storedFolders.filter( (f) => orgCiphers.some((oc) => oc.folderId == f.id) || f.id == null, @@ -88,9 +84,13 @@ export class VaultFilterService implements DeprecatedVaultFilterServiceAbstracti }); }; - return this.activeUserId$.pipe( - switchMap((userId) => this.folderService.folderViews$(userId)), - mergeMap((folders) => from(transformation(folders))), + return this.accountService.activeAccount$.pipe( + getUserId, + switchMap((userId) => + this.folderService + .folderViews$(userId) + .pipe(mergeMap((folders) => from(transformation(folders, userId)))), + ), ); } @@ -134,7 +134,7 @@ export class VaultFilterService implements DeprecatedVaultFilterServiceAbstracti } async getFolderNested(id: string): Promise> { - const activeUserId = await firstValueFrom(this.activeUserId$); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); const folders = await this.getAllFoldersNested( await firstValueFrom(this.folderService.folderViews$(activeUserId)), ); diff --git a/libs/angular/tsconfig.json b/libs/angular/tsconfig.json index b638410a6a8..c603e5cf170 100644 --- a/libs/angular/tsconfig.json +++ b/libs/angular/tsconfig.json @@ -13,7 +13,6 @@ "@bitwarden/generator-history": ["../tools/generator/extensions/history/src"], "@bitwarden/generator-legacy": ["../tools/generator/extensions/legacy/src"], "@bitwarden/generator-navigation": ["../tools/generator/extensions/navigation/src"], - "@bitwarden/importer/core": ["../importer/src"], "@bitwarden/key-management": ["../key-management/src"], "@bitwarden/platform": ["../platform/src"], "@bitwarden/ui-common": ["../ui/common/src"], diff --git a/libs/auth/src/angular/anon-layout/anon-layout-wrapper.mdx b/libs/auth/src/angular/anon-layout/anon-layout-wrapper.mdx index a218eaa1492..8fe332b8caf 100644 --- a/libs/auth/src/angular/anon-layout/anon-layout-wrapper.mdx +++ b/libs/auth/src/angular/anon-layout/anon-layout-wrapper.mdx @@ -6,10 +6,6 @@ import * as stories from "./anon-layout-wrapper.stories"; # Anon Layout Wrapper -NOTE: These stories will treat "Light & Dark" mode as "Light" mode. This is done to avoid a bug with -the way that we render the same component twice in the same iframe and how that interacts with the -`router-outlet`. - ## Anon Layout Wrapper Component The auth owned `AnonLayoutWrapperComponent` orchestrates routing configuration data and feeds it diff --git a/libs/auth/src/angular/login-approval/login-approval.component.html b/libs/auth/src/angular/login-approval/login-approval.component.html index c0cb9b9caf4..2115bdbff11 100644 --- a/libs/auth/src/angular/login-approval/login-approval.component.html +++ b/libs/auth/src/angular/login-approval/login-approval.component.html @@ -1,5 +1,5 @@ - {{ "areYouTryingtoLogin" | i18n }} + {{ "areYouTryingToAccessYourAccount" | i18n }}
@@ -8,7 +8,7 @@ -

{{ "logInAttemptBy" | i18n: email }}

+

{{ "accessAttemptBy" | i18n: email }}

{{ "fingerprintPhraseHeader" | i18n }}

{{ fingerprintPhrase }}

@@ -35,7 +35,7 @@ [bitAction]="approveLogin" [disabled]="loading" > - {{ "confirmLogIn" | i18n }} + {{ "confirmAccess" | i18n }} diff --git a/libs/auth/src/angular/login-approval/login-approval.component.ts b/libs/auth/src/angular/login-approval/login-approval.component.ts index 3b44f545abb..54d90306e5c 100644 --- a/libs/auth/src/angular/login-approval/login-approval.component.ts +++ b/libs/auth/src/angular/login-approval/login-approval.component.ts @@ -85,7 +85,7 @@ export class LoginApprovalComponent implements OnInit, OnDestroy { } const publicKey = Utils.fromB64ToArray(this.authRequestResponse.publicKey); - this.email = await await firstValueFrom( + this.email = await firstValueFrom( this.accountService.activeAccount$.pipe(map((a) => a?.email)), ); this.fingerprintPhrase = await this.authRequestService.getFingerprintPhrase( diff --git a/libs/auth/src/angular/login-decryption-options/login-decryption-options.component.html b/libs/auth/src/angular/login-decryption-options/login-decryption-options.component.html index b3d218389bf..bf37380dc39 100644 --- a/libs/auth/src/angular/login-decryption-options/login-decryption-options.component.html +++ b/libs/auth/src/angular/login-decryption-options/login-decryption-options.component.html @@ -1,5 +1,5 @@ -
+
- this.ssoLoginService.getActiveUserOrganizationSsoIdentifier(), + this.ssoLoginService.getActiveUserOrganizationSsoIdentifier(this.activeAccountId), ).pipe( switchMap((organizationIdentifier) => { if (organizationIdentifier == undefined) { diff --git a/libs/auth/src/angular/login-via-auth-request/login-via-auth-request.component.html b/libs/auth/src/angular/login-via-auth-request/login-via-auth-request.component.html index a1d0f200c15..ba26ba77cb0 100644 --- a/libs/auth/src/angular/login-via-auth-request/login-via-auth-request.component.html +++ b/libs/auth/src/angular/login-via-auth-request/login-via-auth-request.component.html @@ -1,6 +1,20 @@
-

{{ "makeSureYourAccountIsUnlockedAndTheFingerprintEtc" | i18n }}

+

+ {{ "notificationSentDevicePart1" | i18n }} + {{ "notificationSentDeviceAnchor" | i18n }}. {{ "notificationSentDevicePart2" | i18n }} +

+

+ {{ "notificationSentDeviceComplete" | i18n }} +

{{ "fingerprintPhraseHeader" | i18n }}
{{ fingerprintPhrase }} diff --git a/libs/auth/src/angular/login-via-auth-request/login-via-auth-request.component.ts b/libs/auth/src/angular/login-via-auth-request/login-via-auth-request.component.ts index b9a5ee4fe73..00e2d621c47 100644 --- a/libs/auth/src/angular/login-via-auth-request/login-via-auth-request.component.ts +++ b/libs/auth/src/angular/login-via-auth-request/login-via-auth-request.component.ts @@ -29,6 +29,7 @@ import { ClientType, HttpStatusCode } from "@bitwarden/common/enums"; import { ErrorResponse } from "@bitwarden/common/models/response/error.response"; import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service"; import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; +import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; 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"; @@ -71,6 +72,8 @@ export class LoginViaAuthRequestComponent implements OnInit, OnDestroy { protected showResendNotification = false; protected Flow = Flow; protected flow = Flow.StandardAuthRequest; + protected webVaultUrl: string; + protected deviceManagementUrl: string; constructor( private accountService: AccountService, @@ -81,6 +84,7 @@ export class LoginViaAuthRequestComponent implements OnInit, OnDestroy { private authService: AuthService, private cryptoFunctionService: CryptoFunctionService, private deviceTrustService: DeviceTrustServiceAbstraction, + private environmentService: EnvironmentService, private i18nService: I18nService, private logService: LogService, private loginEmailService: LoginEmailServiceAbstraction, @@ -109,6 +113,12 @@ export class LoginViaAuthRequestComponent implements OnInit, OnDestroy { this.logService.error("Failed to use approved auth request: " + e.message); }); }); + + // Get the web vault URL from the environment service + this.environmentService.environment$.pipe(takeUntilDestroyed()).subscribe((env) => { + this.webVaultUrl = env.getWebVaultUrl(); + this.deviceManagementUrl = `${this.webVaultUrl}/#/settings/security/device-management`; + }); } async ngOnInit(): Promise { diff --git a/libs/auth/src/angular/set-password-jit/default-set-password-jit.service.spec.ts b/libs/auth/src/angular/set-password-jit/default-set-password-jit.service.spec.ts index 7a2b334eb42..726110663fc 100644 --- a/libs/auth/src/angular/set-password-jit/default-set-password-jit.service.spec.ts +++ b/libs/auth/src/angular/set-password-jit/default-set-password-jit.service.spec.ts @@ -11,8 +11,8 @@ import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-conso import { OrganizationKeysResponse } from "@bitwarden/common/admin-console/models/response/organization-keys.response"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; import { SetPasswordRequest } from "@bitwarden/common/auth/models/request/set-password.request"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { KeysRequest } from "@bitwarden/common/models/request/keys.request"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; diff --git a/libs/auth/src/angular/set-password-jit/default-set-password-jit.service.ts b/libs/auth/src/angular/set-password-jit/default-set-password-jit.service.ts index 84c580662be..6c9ce8f9267 100644 --- a/libs/auth/src/angular/set-password-jit/default-set-password-jit.service.ts +++ b/libs/auth/src/angular/set-password-jit/default-set-password-jit.service.ts @@ -12,8 +12,8 @@ import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-conso import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason"; import { SetPasswordRequest } from "@bitwarden/common/auth/models/request/set-password.request"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { KeysRequest } from "@bitwarden/common/models/request/keys.request"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; diff --git a/libs/auth/src/angular/sso/sso.component.ts b/libs/auth/src/angular/sso/sso.component.ts index 4583332cb88..b3f0d7d6a66 100644 --- a/libs/auth/src/angular/sso/sso.component.ts +++ b/libs/auth/src/angular/sso/sso.component.ts @@ -367,7 +367,7 @@ export class SsoComponent implements OnInit { codeVerifier, redirectUri, orgSsoIdentifier, - email, + email ?? undefined, ); this.formPromise = this.loginStrategyService.logIn(credentials); const authResult = await this.formPromise; @@ -384,7 +384,10 @@ export class SsoComponent implements OnInit { // - TDE login decryption options component // - Browser SSO on extension open // Note: you cannot set this in state before 2FA b/c there won't be an account in state. - await this.ssoLoginService.setActiveUserOrganizationSsoIdentifier(orgSsoIdentifier); + + // Grabbing the active user id right before making the state set to ensure it exists. + const userId = (await firstValueFrom(this.accountService.activeAccount$))?.id; + await this.ssoLoginService.setActiveUserOrganizationSsoIdentifier(orgSsoIdentifier, userId); // Users enrolled in admin acct recovery can be forced to set a new password after // having the admin set a temp password for them (affects TDE & standard users) diff --git a/libs/auth/src/angular/user-verification/user-verification-form-input.component.html b/libs/auth/src/angular/user-verification/user-verification-form-input.component.html index f532a3b23fd..56bce040d2f 100644 --- a/libs/auth/src/angular/user-verification/user-verification-form-input.component.html +++ b/libs/auth/src/angular/user-verification/user-verification-form-input.component.html @@ -120,7 +120,7 @@
{{ "enterVerificationCodeSentToEmail" | i18n }} -

+

diff --git a/libs/auth/src/common/login-strategies/auth-request-login.strategy.spec.ts b/libs/auth/src/common/login-strategies/auth-request-login.strategy.spec.ts index cec4481cd8d..7c56e2a58c8 100644 --- a/libs/auth/src/common/login-strategies/auth-request-login.strategy.spec.ts +++ b/libs/auth/src/common/login-strategies/auth-request-login.strategy.spec.ts @@ -9,8 +9,8 @@ import { IdentityTokenResponse } from "@bitwarden/common/auth/models/response/id import { FakeMasterPasswordService } from "@bitwarden/common/auth/services/master-password/fake-master-password.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { VaultTimeoutAction } from "@bitwarden/common/enums/vault-timeout-action.enum"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; diff --git a/libs/auth/src/common/login-strategies/login.strategy.spec.ts b/libs/auth/src/common/login-strategies/login.strategy.spec.ts index a8208a1e0ad..fbd6b79f19d 100644 --- a/libs/auth/src/common/login-strategies/login.strategy.spec.ts +++ b/libs/auth/src/common/login-strategies/login.strategy.spec.ts @@ -21,8 +21,8 @@ import { IUserDecryptionOptionsServerResponse } from "@bitwarden/common/auth/mod import { FakeMasterPasswordService } from "@bitwarden/common/auth/services/master-password/fake-master-password.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { VaultTimeoutAction } from "@bitwarden/common/enums/vault-timeout-action.enum"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; diff --git a/libs/auth/src/common/login-strategies/login.strategy.ts b/libs/auth/src/common/login-strategies/login.strategy.ts index 6b1dcfb155c..b4eef1a0276 100644 --- a/libs/auth/src/common/login-strategies/login.strategy.ts +++ b/libs/auth/src/common/login-strategies/login.strategy.ts @@ -22,9 +22,9 @@ import { IdentityTwoFactorResponse } from "@bitwarden/common/auth/models/respons import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { ClientType } from "@bitwarden/common/enums"; import { VaultTimeoutAction } from "@bitwarden/common/enums/vault-timeout-action.enum"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { KeysRequest } from "@bitwarden/common/models/request/keys.request"; import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; diff --git a/libs/auth/src/common/login-strategies/password-login.strategy.spec.ts b/libs/auth/src/common/login-strategies/password-login.strategy.spec.ts index d572710a2fd..1b0613d4da3 100644 --- a/libs/auth/src/common/login-strategies/password-login.strategy.spec.ts +++ b/libs/auth/src/common/login-strategies/password-login.strategy.spec.ts @@ -13,8 +13,8 @@ import { MasterPasswordPolicyResponse } from "@bitwarden/common/auth/models/resp import { FakeMasterPasswordService } from "@bitwarden/common/auth/services/master-password/fake-master-password.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { VaultTimeoutAction } from "@bitwarden/common/enums/vault-timeout-action.enum"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; diff --git a/libs/auth/src/common/login-strategies/sso-login.strategy.spec.ts b/libs/auth/src/common/login-strategies/sso-login.strategy.spec.ts index ec3ec43134f..96b08e98e37 100644 --- a/libs/auth/src/common/login-strategies/sso-login.strategy.spec.ts +++ b/libs/auth/src/common/login-strategies/sso-login.strategy.spec.ts @@ -13,9 +13,9 @@ import { IUserDecryptionOptionsServerResponse } from "@bitwarden/common/auth/mod import { FakeMasterPasswordService } from "@bitwarden/common/auth/services/master-password/fake-master-password.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { VaultTimeoutAction } from "@bitwarden/common/enums/vault-timeout-action.enum"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { ErrorResponse } from "@bitwarden/common/models/response/error.response"; import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; diff --git a/libs/auth/src/common/login-strategies/user-api-login.strategy.spec.ts b/libs/auth/src/common/login-strategies/user-api-login.strategy.spec.ts index 2bb41faa0e1..dd3e7f0134d 100644 --- a/libs/auth/src/common/login-strategies/user-api-login.strategy.spec.ts +++ b/libs/auth/src/common/login-strategies/user-api-login.strategy.spec.ts @@ -8,8 +8,8 @@ import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor import { FakeMasterPasswordService } from "@bitwarden/common/auth/services/master-password/fake-master-password.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { VaultTimeoutAction } from "@bitwarden/common/enums/vault-timeout-action.enum"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { Environment, EnvironmentService, diff --git a/libs/auth/src/common/login-strategies/webauthn-login.strategy.spec.ts b/libs/auth/src/common/login-strategies/webauthn-login.strategy.spec.ts index 9dacce2cf00..fd8817a8c21 100644 --- a/libs/auth/src/common/login-strategies/webauthn-login.strategy.spec.ts +++ b/libs/auth/src/common/login-strategies/webauthn-login.strategy.spec.ts @@ -11,8 +11,8 @@ import { FakeMasterPasswordService } from "@bitwarden/common/auth/services/maste import { WebAuthnLoginAssertionResponseRequest } from "@bitwarden/common/auth/services/webauthn-login/request/webauthn-login-assertion-response.request"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { VaultTimeoutAction } from "@bitwarden/common/enums/vault-timeout-action.enum"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; diff --git a/libs/auth/src/common/services/auth-request/auth-request.service.spec.ts b/libs/auth/src/common/services/auth-request/auth-request.service.spec.ts index 86b2a1dd3b6..2ea6d427641 100644 --- a/libs/auth/src/common/services/auth-request/auth-request.service.spec.ts +++ b/libs/auth/src/common/services/auth-request/auth-request.service.spec.ts @@ -3,9 +3,9 @@ import { mock } from "jest-mock-extended"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { AuthRequestResponse } from "@bitwarden/common/auth/models/response/auth-request.response"; import { FakeMasterPasswordService } from "@bitwarden/common/auth/services/master-password/fake-master-password.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { AuthRequestPushNotification } from "@bitwarden/common/models/response/notification.response"; import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; diff --git a/libs/auth/src/common/services/auth-request/auth-request.service.ts b/libs/auth/src/common/services/auth-request/auth-request.service.ts index 4bc0397b43a..5bc200ae1e8 100644 --- a/libs/auth/src/common/services/auth-request/auth-request.service.ts +++ b/libs/auth/src/common/services/auth-request/auth-request.service.ts @@ -9,9 +9,9 @@ import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth import { AdminAuthRequestStorable } from "@bitwarden/common/auth/models/domain/admin-auth-req-storable"; import { PasswordlessAuthRequest } from "@bitwarden/common/auth/models/request/passwordless-auth.request"; import { AuthRequestResponse } from "@bitwarden/common/auth/models/response/auth-request.response"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { AuthRequestPushNotification } from "@bitwarden/common/models/response/notification.response"; import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; diff --git a/libs/auth/src/common/services/login-strategies/login-strategy.service.spec.ts b/libs/auth/src/common/services/login-strategies/login-strategy.service.spec.ts index 3b03e8754bc..117e5c1f864 100644 --- a/libs/auth/src/common/services/login-strategies/login-strategy.service.spec.ts +++ b/libs/auth/src/common/services/login-strategies/login-strategy.service.spec.ts @@ -17,8 +17,8 @@ import { PreloginResponse } from "@bitwarden/common/auth/models/response/prelogi import { FakeMasterPasswordService } from "@bitwarden/common/auth/services/master-password/fake-master-password.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { VaultTimeoutAction } from "@bitwarden/common/enums/vault-timeout-action.enum"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.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"; diff --git a/libs/auth/src/common/services/login-strategies/login-strategy.service.ts b/libs/auth/src/common/services/login-strategies/login-strategy.service.ts index e3a20fcfe72..849b8e5eba1 100644 --- a/libs/auth/src/common/services/login-strategies/login-strategy.service.ts +++ b/libs/auth/src/common/services/login-strategies/login-strategy.service.ts @@ -22,10 +22,10 @@ import { AuthenticationType } from "@bitwarden/common/auth/enums/authentication- import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result"; import { TokenTwoFactorRequest } from "@bitwarden/common/auth/models/request/identity-token/token-two-factor.request"; 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 { PreloginRequest } from "@bitwarden/common/models/request/prelogin.request"; import { ErrorResponse } from "@bitwarden/common/models/response/error.response"; import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.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"; diff --git a/libs/auth/src/common/services/pin/pin.service.implementation.ts b/libs/auth/src/common/services/pin/pin.service.implementation.ts index 01fc77e4a03..9b86440b364 100644 --- a/libs/auth/src/common/services/pin/pin.service.implementation.ts +++ b/libs/auth/src/common/services/pin/pin.service.implementation.ts @@ -4,8 +4,8 @@ import { firstValueFrom, map } from "rxjs"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { MasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { KeyGenerationService } from "@bitwarden/common/platform/abstractions/key-generation.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; diff --git a/libs/auth/src/common/services/pin/pin.service.spec.ts b/libs/auth/src/common/services/pin/pin.service.spec.ts index d254be4e875..1d6443535bc 100644 --- a/libs/auth/src/common/services/pin/pin.service.spec.ts +++ b/libs/auth/src/common/services/pin/pin.service.spec.ts @@ -1,8 +1,8 @@ import { mock } from "jest-mock-extended"; import { FakeMasterPasswordService } from "@bitwarden/common/auth/services/master-password/fake-master-password.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { KeyGenerationService } from "@bitwarden/common/platform/abstractions/key-generation.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; diff --git a/libs/common/spec/fake-account-service.ts b/libs/common/spec/fake-account-service.ts index d45448ce698..ba48181faa2 100644 --- a/libs/common/spec/fake-account-service.ts +++ b/libs/common/spec/fake-account-service.ts @@ -1,7 +1,7 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore import { mock } from "jest-mock-extended"; -import { ReplaySubject, combineLatest, map } from "rxjs"; +import { ReplaySubject, combineLatest, map, Observable } from "rxjs"; import { Account, AccountInfo, AccountService } from "../src/auth/abstractions/account.service"; import { UserId } from "../src/types/guid"; @@ -55,7 +55,7 @@ export class FakeAccountService implements AccountService { }), ); } - get nextUpAccount$() { + get nextUpAccount$(): Observable { return combineLatest([this.accounts$, this.activeAccount$, this.sortedUserIds$]).pipe( map(([accounts, activeAccount, sortedUserIds]) => { const nextId = sortedUserIds.find((id) => id !== activeAccount?.id && accounts[id] != null); diff --git a/libs/common/spec/fake-state-provider.ts b/libs/common/spec/fake-state-provider.ts index b5105bb24ba..9f72ccada55 100644 --- a/libs/common/spec/fake-state-provider.ts +++ b/libs/common/spec/fake-state-provider.ts @@ -225,9 +225,9 @@ export class FakeStateProvider implements StateProvider { async setUserState( userKeyDefinition: UserKeyDefinition, - value: T, + value: T | null, userId?: UserId, - ): Promise<[UserId, T]> { + ): Promise<[UserId, T | null]> { await this.mock.setUserState(userKeyDefinition, value, userId); if (userId) { return [userId, await this.getUser(userId, userKeyDefinition).update(() => value)]; diff --git a/libs/common/spec/fake-state.ts b/libs/common/spec/fake-state.ts index e4b42e357b6..00b12de2eb1 100644 --- a/libs/common/spec/fake-state.ts +++ b/libs/common/spec/fake-state.ts @@ -131,9 +131,9 @@ export class FakeSingleUserState implements SingleUserState { } async update( - configureState: (state: T, dependency: TCombine) => T, + configureState: (state: T | null, dependency: TCombine) => T | null, options?: StateUpdateOptions, - ): Promise { + ): Promise { options = populateOptionsWithDefault(options); const current = await firstValueFrom(this.state$.pipe(timeout(options.msTimeout))); const combinedDependencies = @@ -206,9 +206,9 @@ export class FakeActiveUserState implements ActiveUserState { } async update( - configureState: (state: T, dependency: TCombine) => T, + configureState: (state: T | null, dependency: TCombine) => T | null, options?: StateUpdateOptions, - ): Promise<[UserId, T]> { + ): Promise<[UserId, T | null]> { options = populateOptionsWithDefault(options); const current = await firstValueFrom(this.state$.pipe(timeout(options.msTimeout))); const combinedDependencies = diff --git a/libs/common/src/admin-console/abstractions/provider/provider-api.service.abstraction.ts b/libs/common/src/admin-console/abstractions/provider/provider-api.service.abstraction.ts index f348e7487de..ffe79f0ad3b 100644 --- a/libs/common/src/admin-console/abstractions/provider/provider-api.service.abstraction.ts +++ b/libs/common/src/admin-console/abstractions/provider/provider-api.service.abstraction.ts @@ -1,5 +1,7 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore +import { AddableOrganizationResponse } from "@bitwarden/common/admin-console/models/response/addable-organization.response"; + import { ProviderSetupRequest } from "../../models/request/provider/provider-setup.request"; import { ProviderUpdateRequest } from "../../models/request/provider/provider-update.request"; import { ProviderVerifyRecoverDeleteRequest } from "../../models/request/provider/provider-verify-recover-delete.request"; @@ -14,4 +16,12 @@ export class ProviderApiServiceAbstraction { request: ProviderVerifyRecoverDeleteRequest, ) => Promise; deleteProvider: (id: string) => Promise; + getProviderAddableOrganizations: (providerId: string) => Promise; + addOrganizationToProvider: ( + providerId: string, + request: { + key: string; + organizationId: string; + }, + ) => Promise; } diff --git a/libs/common/src/admin-console/models/domain/encrypted-organization-key.ts b/libs/common/src/admin-console/models/domain/encrypted-organization-key.ts index 1f8c4e8c42d..5f8fe3349b6 100644 --- a/libs/common/src/admin-console/models/domain/encrypted-organization-key.ts +++ b/libs/common/src/admin-console/models/domain/encrypted-organization-key.ts @@ -1,4 +1,4 @@ -import { EncryptService } from "../../../platform/abstractions/encrypt.service"; +import { EncryptService } from "../../../key-management/crypto/abstractions/encrypt.service"; import { EncString } from "../../../platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-crypto-key"; import { OrgKey, UserPrivateKey } from "../../../types/key"; diff --git a/libs/common/src/admin-console/models/response/addable-organization.response.ts b/libs/common/src/admin-console/models/response/addable-organization.response.ts new file mode 100644 index 00000000000..74ae5f45690 --- /dev/null +++ b/libs/common/src/admin-console/models/response/addable-organization.response.ts @@ -0,0 +1,18 @@ +import { BaseResponse } from "@bitwarden/common/models/response/base.response"; + +export class AddableOrganizationResponse extends BaseResponse { + id: string; + plan: string; + name: string; + seats: number; + disabled: boolean; + + constructor(response: any) { + super(response); + this.id = this.getResponseProperty("id"); + this.plan = this.getResponseProperty("plan"); + this.name = this.getResponseProperty("name"); + this.seats = this.getResponseProperty("seats"); + this.disabled = this.getResponseProperty("disabled"); + } +} diff --git a/libs/common/src/admin-console/services/provider/provider-api.service.ts b/libs/common/src/admin-console/services/provider/provider-api.service.ts index 2ee921393ff..dc82ec011f4 100644 --- a/libs/common/src/admin-console/services/provider/provider-api.service.ts +++ b/libs/common/src/admin-console/services/provider/provider-api.service.ts @@ -1,3 +1,5 @@ +import { AddableOrganizationResponse } from "@bitwarden/common/admin-console/models/response/addable-organization.response"; + import { ApiService } from "../../../abstractions/api.service"; import { ProviderApiServiceAbstraction } from "../../abstractions/provider/provider-api.service.abstraction"; import { ProviderSetupRequest } from "../../models/request/provider/provider-setup.request"; @@ -44,4 +46,34 @@ export class ProviderApiService implements ProviderApiServiceAbstraction { async deleteProvider(id: string): Promise { await this.apiService.send("DELETE", "/providers/" + id, null, true, false); } + + async getProviderAddableOrganizations( + providerId: string, + ): Promise { + const response = await this.apiService.send( + "GET", + "/providers/" + providerId + "/clients/addable", + null, + true, + true, + ); + + return response.map((data: any) => new AddableOrganizationResponse(data)); + } + + addOrganizationToProvider( + providerId: string, + request: { + key: string; + organizationId: string; + }, + ): Promise { + return this.apiService.send( + "POST", + "/providers/" + providerId + "/clients/existing", + request, + true, + false, + ); + } } diff --git a/libs/common/src/auth/abstractions/sso-login.service.abstraction.ts b/libs/common/src/auth/abstractions/sso-login.service.abstraction.ts index 3f3731e0e1b..b30739d94a8 100644 --- a/libs/common/src/auth/abstractions/sso-login.service.abstraction.ts +++ b/libs/common/src/auth/abstractions/sso-login.service.abstraction.ts @@ -1,5 +1,5 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore +import { UserId } from "@bitwarden/common/types/guid"; + export abstract class SsoLoginServiceAbstraction { /** * Gets the code verifier used for SSO. @@ -11,7 +11,7 @@ export abstract class SsoLoginServiceAbstraction { * @see https://datatracker.ietf.org/doc/html/rfc7636 * @returns The code verifier used for SSO. */ - getCodeVerifier: () => Promise; + abstract getCodeVerifier: () => Promise; /** * Sets the code verifier used for SSO. * @@ -21,7 +21,7 @@ export abstract class SsoLoginServiceAbstraction { * and verify it matches the one sent in the request for the `authorization_code`. * @see https://datatracker.ietf.org/doc/html/rfc7636 */ - setCodeVerifier: (codeVerifier: string) => Promise; + abstract setCodeVerifier: (codeVerifier: string) => Promise; /** * Gets the value of the SSO state. * @@ -31,7 +31,7 @@ export abstract class SsoLoginServiceAbstraction { * @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1 * @returns The SSO state. */ - getSsoState: () => Promise; + abstract getSsoState: () => Promise; /** * Sets the value of the SSO state. * @@ -40,7 +40,7 @@ export abstract class SsoLoginServiceAbstraction { * returns the `state` in the callback and the client verifies that the value returned matches the value sent. * @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1 */ - setSsoState: (ssoState: string) => Promise; + abstract setSsoState: (ssoState: string) => Promise; /** * Gets the value of the user's organization sso identifier. * @@ -48,20 +48,20 @@ export abstract class SsoLoginServiceAbstraction { * Do not use this value outside of the SSO login flow. * @returns The user's organization identifier. */ - getOrganizationSsoIdentifier: () => Promise; + abstract getOrganizationSsoIdentifier: () => Promise; /** * Sets the value of the user's organization sso identifier. * * This should only be used during the SSO flow to identify the organization that the user is attempting to log in to. * Do not use this value outside of the SSO login flow. */ - setOrganizationSsoIdentifier: (organizationIdentifier: string) => Promise; + abstract setOrganizationSsoIdentifier: (organizationIdentifier: string) => Promise; /** * Gets the user's email. * Note: This should only be used during the SSO flow to identify the user that is attempting to log in. * @returns The user's email. */ - getSsoEmail: () => Promise; + abstract getSsoEmail: () => Promise; /** * Sets the user's email. * Note: This should only be used during the SSO flow to identify the user that is attempting to log in. @@ -69,17 +69,21 @@ export abstract class SsoLoginServiceAbstraction { * @returns A promise that resolves when the email has been set. * */ - setSsoEmail: (email: string) => Promise; + abstract setSsoEmail: (email: string) => Promise; /** * Gets the value of the active user's organization sso identifier. * * This should only be used post successful SSO login once the user is initialized. + * @param userId The user id for retrieving the org identifier state. */ - getActiveUserOrganizationSsoIdentifier: () => Promise; + abstract getActiveUserOrganizationSsoIdentifier: (userId: UserId) => Promise; /** * Sets the value of the active user's organization sso identifier. * * This should only be used post successful SSO login once the user is initialized. */ - setActiveUserOrganizationSsoIdentifier: (organizationIdentifier: string) => Promise; + abstract setActiveUserOrganizationSsoIdentifier: ( + organizationIdentifier: string, + userId: UserId | undefined, + ) => Promise; } diff --git a/libs/common/src/auth/services/auth.service.spec.ts b/libs/common/src/auth/services/auth.service.spec.ts index 4b7b8a2b262..fc236c91a21 100644 --- a/libs/common/src/auth/services/auth.service.spec.ts +++ b/libs/common/src/auth/services/auth.service.spec.ts @@ -1,9 +1,8 @@ import { MockProxy, mock } from "jest-mock-extended"; import { firstValueFrom, of } from "rxjs"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { KeyService } from "../../../../key-management/src/abstractions/key.service"; +import { KeyService } from "@bitwarden/key-management"; + import { FakeAccountService, makeStaticByteArray, diff --git a/libs/common/src/auth/services/auth.service.ts b/libs/common/src/auth/services/auth.service.ts index d855a1be34f..da70baf3999 100644 --- a/libs/common/src/auth/services/auth.service.ts +++ b/libs/common/src/auth/services/auth.service.ts @@ -11,9 +11,8 @@ import { switchMap, } from "rxjs"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { KeyService } from "../../../../key-management/src/abstractions/key.service"; +import { KeyService } from "@bitwarden/key-management"; + import { ApiService } from "../../abstractions/api.service"; import { StateService } from "../../platform/abstractions/state.service"; import { MessageSender } from "../../platform/messaging"; diff --git a/libs/common/src/auth/services/device-trust.service.implementation.ts b/libs/common/src/auth/services/device-trust.service.implementation.ts index 15c12b7a39a..fe43df53c48 100644 --- a/libs/common/src/auth/services/device-trust.service.implementation.ts +++ b/libs/common/src/auth/services/device-trust.service.implementation.ts @@ -3,14 +3,12 @@ import { firstValueFrom, map, Observable } from "rxjs"; import { UserDecryptionOptionsServiceAbstraction } from "@bitwarden/auth/common"; +import { KeyService } from "@bitwarden/key-management"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { KeyService } from "../../../../key-management/src/abstractions/key.service"; +import { EncryptService } from "../../key-management/crypto/abstractions/encrypt.service"; import { AppIdService } from "../../platform/abstractions/app-id.service"; import { ConfigService } from "../../platform/abstractions/config/config.service"; import { CryptoFunctionService } from "../../platform/abstractions/crypto-function.service"; -import { EncryptService } from "../../platform/abstractions/encrypt.service"; import { I18nService } from "../../platform/abstractions/i18n.service"; import { KeyGenerationService } from "../../platform/abstractions/key-generation.service"; import { LogService } from "../../platform/abstractions/log.service"; diff --git a/libs/common/src/auth/services/device-trust.service.spec.ts b/libs/common/src/auth/services/device-trust.service.spec.ts index 9f344e203c9..e689c93395d 100644 --- a/libs/common/src/auth/services/device-trust.service.spec.ts +++ b/libs/common/src/auth/services/device-trust.service.spec.ts @@ -4,21 +4,19 @@ import { matches, mock } from "jest-mock-extended"; import { BehaviorSubject, firstValueFrom, of } from "rxjs"; import { UserDecryptionOptionsServiceAbstraction } from "@bitwarden/auth/common"; +import { KeyService } from "@bitwarden/key-management"; // FIXME: remove `src` and fix import // eslint-disable-next-line no-restricted-imports import { UserDecryptionOptions } from "../../../../auth/src/common/models/domain/user-decryption-options"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { KeyService } from "../../../../key-management/src/abstractions/key.service"; import { FakeAccountService, mockAccountServiceWith } from "../../../spec/fake-account-service"; import { FakeActiveUserState } from "../../../spec/fake-state"; import { FakeStateProvider } from "../../../spec/fake-state-provider"; import { DeviceType } from "../../enums"; +import { EncryptService } from "../../key-management/crypto/abstractions/encrypt.service"; import { AppIdService } from "../../platform/abstractions/app-id.service"; import { ConfigService } from "../../platform/abstractions/config/config.service"; import { CryptoFunctionService } from "../../platform/abstractions/crypto-function.service"; -import { EncryptService } from "../../platform/abstractions/encrypt.service"; import { I18nService } from "../../platform/abstractions/i18n.service"; import { KeyGenerationService } from "../../platform/abstractions/key-generation.service"; import { LogService } from "../../platform/abstractions/log.service"; diff --git a/libs/common/src/auth/services/key-connector.service.spec.ts b/libs/common/src/auth/services/key-connector.service.spec.ts index 165dcee1ea8..ec03c7ece55 100644 --- a/libs/common/src/auth/services/key-connector.service.spec.ts +++ b/libs/common/src/auth/services/key-connector.service.spec.ts @@ -2,10 +2,8 @@ import { mock } from "jest-mock-extended"; import { of } from "rxjs"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; +import { KeyService } from "@bitwarden/key-management"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { KeyService } from "../../../../key-management/src/abstractions/key.service"; import { FakeAccountService, FakeStateProvider, mockAccountServiceWith } from "../../../spec"; import { ApiService } from "../../abstractions/api.service"; import { OrganizationData } from "../../admin-console/models/data/organization.data"; diff --git a/libs/common/src/auth/services/master-password/master-password.service.ts b/libs/common/src/auth/services/master-password/master-password.service.ts index 14e7522a836..9b5ce588bd3 100644 --- a/libs/common/src/auth/services/master-password/master-password.service.ts +++ b/libs/common/src/auth/services/master-password/master-password.service.ts @@ -2,7 +2,7 @@ // @ts-strict-ignore import { firstValueFrom, map, Observable } from "rxjs"; -import { EncryptService } from "../../../platform/abstractions/encrypt.service"; +import { EncryptService } from "../../../key-management/crypto/abstractions/encrypt.service"; import { KeyGenerationService } from "../../../platform/abstractions/key-generation.service"; import { LogService } from "../../../platform/abstractions/log.service"; import { StateService } from "../../../platform/abstractions/state.service"; diff --git a/libs/common/src/auth/services/password-reset-enrollment.service.implementation.spec.ts b/libs/common/src/auth/services/password-reset-enrollment.service.implementation.spec.ts index ddd24ae7907..8516400fe09 100644 --- a/libs/common/src/auth/services/password-reset-enrollment.service.implementation.spec.ts +++ b/libs/common/src/auth/services/password-reset-enrollment.service.implementation.spec.ts @@ -2,13 +2,11 @@ import { mock, MockProxy } from "jest-mock-extended"; import { BehaviorSubject } from "rxjs"; import { OrganizationUserApiService } from "@bitwarden/admin-console/common"; +import { KeyService } from "@bitwarden/key-management"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { KeyService } from "../../../../key-management/src/abstractions/key.service"; import { OrganizationApiServiceAbstraction } from "../../admin-console/abstractions/organization/organization-api.service.abstraction"; import { OrganizationAutoEnrollStatusResponse } from "../../admin-console/models/response/organization-auto-enroll-status.response"; -import { EncryptService } from "../../platform/abstractions/encrypt.service"; +import { EncryptService } from "../../key-management/crypto/abstractions/encrypt.service"; import { I18nService } from "../../platform/abstractions/i18n.service"; import { UserId } from "../../types/guid"; import { Account, AccountInfo, AccountService } from "../abstractions/account.service"; diff --git a/libs/common/src/auth/services/password-reset-enrollment.service.implementation.ts b/libs/common/src/auth/services/password-reset-enrollment.service.implementation.ts index 22d5384e6ac..824521d8a2e 100644 --- a/libs/common/src/auth/services/password-reset-enrollment.service.implementation.ts +++ b/libs/common/src/auth/services/password-reset-enrollment.service.implementation.ts @@ -6,12 +6,10 @@ import { OrganizationUserApiService, OrganizationUserResetPasswordEnrollmentRequest, } from "@bitwarden/admin-console/common"; +import { KeyService } from "@bitwarden/key-management"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { KeyService } from "../../../../key-management/src/abstractions/key.service"; import { OrganizationApiServiceAbstraction } from "../../admin-console/abstractions/organization/organization-api.service.abstraction"; -import { EncryptService } from "../../platform/abstractions/encrypt.service"; +import { EncryptService } from "../../key-management/crypto/abstractions/encrypt.service"; import { I18nService } from "../../platform/abstractions/i18n.service"; import { Utils } from "../../platform/misc/utils"; import { UserKey } from "../../types/key"; diff --git a/libs/common/src/auth/services/sso-login.service.spec.ts b/libs/common/src/auth/services/sso-login.service.spec.ts new file mode 100644 index 00000000000..6764755e6ca --- /dev/null +++ b/libs/common/src/auth/services/sso-login.service.spec.ts @@ -0,0 +1,94 @@ +import { mock, MockProxy } from "jest-mock-extended"; + +import { + CODE_VERIFIER, + GLOBAL_ORGANIZATION_SSO_IDENTIFIER, + SSO_EMAIL, + SSO_STATE, + SsoLoginService, + USER_ORGANIZATION_SSO_IDENTIFIER, +} from "@bitwarden/common/auth/services/sso-login.service"; +import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; +import { Utils } from "@bitwarden/common/platform/misc/utils"; +import { UserId } from "@bitwarden/common/types/guid"; + +import { FakeAccountService, FakeStateProvider, mockAccountServiceWith } from "../../../spec"; + +describe("SSOLoginService ", () => { + let sut: SsoLoginService; + + let accountService: FakeAccountService; + let mockSingleUserStateProvider: FakeStateProvider; + let mockLogService: MockProxy; + let userId: UserId; + + beforeEach(() => { + jest.clearAllMocks(); + + userId = Utils.newGuid() as UserId; + accountService = mockAccountServiceWith(userId); + mockSingleUserStateProvider = new FakeStateProvider(accountService); + mockLogService = mock(); + + sut = new SsoLoginService(mockSingleUserStateProvider, mockLogService); + }); + + it("instantiates", () => { + expect(sut).not.toBeFalsy(); + }); + + it("gets and sets code verifier", async () => { + const codeVerifier = "test-code-verifier"; + await sut.setCodeVerifier(codeVerifier); + mockSingleUserStateProvider.getGlobal(CODE_VERIFIER); + + const result = await sut.getCodeVerifier(); + expect(result).toBe(codeVerifier); + }); + + it("gets and sets SSO state", async () => { + const ssoState = "test-sso-state"; + await sut.setSsoState(ssoState); + mockSingleUserStateProvider.getGlobal(SSO_STATE); + + const result = await sut.getSsoState(); + expect(result).toBe(ssoState); + }); + + it("gets and sets organization SSO identifier", async () => { + const orgIdentifier = "test-org-identifier"; + await sut.setOrganizationSsoIdentifier(orgIdentifier); + mockSingleUserStateProvider.getGlobal(GLOBAL_ORGANIZATION_SSO_IDENTIFIER); + + const result = await sut.getOrganizationSsoIdentifier(); + expect(result).toBe(orgIdentifier); + }); + + it("gets and sets SSO email", async () => { + const email = "test@example.com"; + await sut.setSsoEmail(email); + mockSingleUserStateProvider.getGlobal(SSO_EMAIL); + + const result = await sut.getSsoEmail(); + expect(result).toBe(email); + }); + + it("gets and sets active user organization SSO identifier", async () => { + const userId = Utils.newGuid() as UserId; + const orgIdentifier = "test-active-org-identifier"; + await sut.setActiveUserOrganizationSsoIdentifier(orgIdentifier, userId); + mockSingleUserStateProvider.getUser(userId, USER_ORGANIZATION_SSO_IDENTIFIER); + + const result = await sut.getActiveUserOrganizationSsoIdentifier(userId); + expect(result).toBe(orgIdentifier); + }); + + it("logs error when setting active user organization SSO identifier with undefined userId", async () => { + const orgIdentifier = "test-active-org-identifier"; + await sut.setActiveUserOrganizationSsoIdentifier(orgIdentifier, undefined); + + expect(mockLogService.error).toHaveBeenCalledWith( + "Tried to set a user organization sso identifier with an undefined user id.", + ); + }); +}); diff --git a/libs/common/src/auth/services/sso-login.service.ts b/libs/common/src/auth/services/sso-login.service.ts index 32019e8d568..9b4b8656782 100644 --- a/libs/common/src/auth/services/sso-login.service.ts +++ b/libs/common/src/auth/services/sso-login.service.ts @@ -1,11 +1,12 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore import { firstValueFrom } from "rxjs"; +import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; +import { UserId } from "@bitwarden/common/types/guid"; + import { - ActiveUserState, GlobalState, KeyDefinition, + SingleUserState, SSO_DISK, StateProvider, UserKeyDefinition, @@ -15,21 +16,21 @@ import { SsoLoginServiceAbstraction } from "../abstractions/sso-login.service.ab /** * Uses disk storage so that the code verifier can be persisted across sso redirects. */ -const CODE_VERIFIER = new KeyDefinition(SSO_DISK, "ssoCodeVerifier", { +export const CODE_VERIFIER = new KeyDefinition(SSO_DISK, "ssoCodeVerifier", { deserializer: (codeVerifier) => codeVerifier, }); /** * Uses disk storage so that the sso state can be persisted across sso redirects. */ -const SSO_STATE = new KeyDefinition(SSO_DISK, "ssoState", { +export const SSO_STATE = new KeyDefinition(SSO_DISK, "ssoState", { deserializer: (state) => state, }); /** * Uses disk storage so that the organization sso identifier can be persisted across sso redirects. */ -const USER_ORGANIZATION_SSO_IDENTIFIER = new UserKeyDefinition( +export const USER_ORGANIZATION_SSO_IDENTIFIER = new UserKeyDefinition( SSO_DISK, "organizationSsoIdentifier", { @@ -41,7 +42,7 @@ const USER_ORGANIZATION_SSO_IDENTIFIER = new UserKeyDefinition( /** * Uses disk storage so that the organization sso identifier can be persisted across sso redirects. */ -const GLOBAL_ORGANIZATION_SSO_IDENTIFIER = new KeyDefinition( +export const GLOBAL_ORGANIZATION_SSO_IDENTIFIER = new KeyDefinition( SSO_DISK, "organizationSsoIdentifier", { @@ -52,7 +53,7 @@ const GLOBAL_ORGANIZATION_SSO_IDENTIFIER = new KeyDefinition( /** * Uses disk storage so that the user's email can be persisted across sso redirects. */ -const SSO_EMAIL = new KeyDefinition(SSO_DISK, "ssoEmail", { +export const SSO_EMAIL = new KeyDefinition(SSO_DISK, "ssoEmail", { deserializer: (state) => state, }); @@ -61,19 +62,18 @@ export class SsoLoginService implements SsoLoginServiceAbstraction { private ssoState: GlobalState; private orgSsoIdentifierState: GlobalState; private ssoEmailState: GlobalState; - private activeUserOrgSsoIdentifierState: ActiveUserState; - constructor(private stateProvider: StateProvider) { + constructor( + private stateProvider: StateProvider, + private logService: LogService, + ) { this.codeVerifierState = this.stateProvider.getGlobal(CODE_VERIFIER); this.ssoState = this.stateProvider.getGlobal(SSO_STATE); this.orgSsoIdentifierState = this.stateProvider.getGlobal(GLOBAL_ORGANIZATION_SSO_IDENTIFIER); this.ssoEmailState = this.stateProvider.getGlobal(SSO_EMAIL); - this.activeUserOrgSsoIdentifierState = this.stateProvider.getActive( - USER_ORGANIZATION_SSO_IDENTIFIER, - ); } - getCodeVerifier(): Promise { + getCodeVerifier(): Promise { return firstValueFrom(this.codeVerifierState.state$); } @@ -81,7 +81,7 @@ export class SsoLoginService implements SsoLoginServiceAbstraction { await this.codeVerifierState.update((_) => codeVerifier); } - getSsoState(): Promise { + getSsoState(): Promise { return firstValueFrom(this.ssoState.state$); } @@ -89,7 +89,7 @@ export class SsoLoginService implements SsoLoginServiceAbstraction { await this.ssoState.update((_) => ssoState); } - getOrganizationSsoIdentifier(): Promise { + getOrganizationSsoIdentifier(): Promise { return firstValueFrom(this.orgSsoIdentifierState.state$); } @@ -97,7 +97,7 @@ export class SsoLoginService implements SsoLoginServiceAbstraction { await this.orgSsoIdentifierState.update((_) => organizationIdentifier); } - getSsoEmail(): Promise { + getSsoEmail(): Promise { return firstValueFrom(this.ssoEmailState.state$); } @@ -105,11 +105,24 @@ export class SsoLoginService implements SsoLoginServiceAbstraction { await this.ssoEmailState.update((_) => email); } - getActiveUserOrganizationSsoIdentifier(): Promise { - return firstValueFrom(this.activeUserOrgSsoIdentifierState.state$); + getActiveUserOrganizationSsoIdentifier(userId: UserId): Promise { + return firstValueFrom(this.userOrgSsoIdentifierState(userId).state$); } - async setActiveUserOrganizationSsoIdentifier(organizationIdentifier: string): Promise { - await this.activeUserOrgSsoIdentifierState.update((_) => organizationIdentifier); + async setActiveUserOrganizationSsoIdentifier( + organizationIdentifier: string, + userId: UserId | undefined, + ): Promise { + if (userId === undefined) { + this.logService.error( + "Tried to set a user organization sso identifier with an undefined user id.", + ); + return; + } + await this.userOrgSsoIdentifierState(userId).update((_) => organizationIdentifier); + } + + private userOrgSsoIdentifierState(userId: UserId): SingleUserState { + return this.stateProvider.getUser(userId, USER_ORGANIZATION_SSO_IDENTIFIER); } } diff --git a/libs/common/src/auth/services/token.service.spec.ts b/libs/common/src/auth/services/token.service.spec.ts index f8882e1b118..339f570a003 100644 --- a/libs/common/src/auth/services/token.service.spec.ts +++ b/libs/common/src/auth/services/token.service.spec.ts @@ -5,7 +5,7 @@ import { LogoutReason } from "@bitwarden/auth/common"; import { FakeSingleUserStateProvider, FakeGlobalStateProvider } from "../../../spec"; import { VaultTimeoutAction } from "../../enums/vault-timeout-action.enum"; -import { EncryptService } from "../../platform/abstractions/encrypt.service"; +import { EncryptService } from "../../key-management/crypto/abstractions/encrypt.service"; import { KeyGenerationService } from "../../platform/abstractions/key-generation.service"; import { LogService } from "../../platform/abstractions/log.service"; import { AbstractStorageService } from "../../platform/abstractions/storage.service"; diff --git a/libs/common/src/auth/services/token.service.ts b/libs/common/src/auth/services/token.service.ts index 4b7cc2cab01..72e082f2002 100644 --- a/libs/common/src/auth/services/token.service.ts +++ b/libs/common/src/auth/services/token.service.ts @@ -6,7 +6,7 @@ import { Opaque } from "type-fest"; import { LogoutReason, decodeJwtTokenToJson } from "@bitwarden/auth/common"; import { VaultTimeoutAction } from "../../enums/vault-timeout-action.enum"; -import { EncryptService } from "../../platform/abstractions/encrypt.service"; +import { EncryptService } from "../../key-management/crypto/abstractions/encrypt.service"; import { KeyGenerationService } from "../../platform/abstractions/key-generation.service"; import { LogService } from "../../platform/abstractions/log.service"; import { AbstractStorageService } from "../../platform/abstractions/storage.service"; diff --git a/libs/common/src/auth/services/user-verification/user-verification.service.spec.ts b/libs/common/src/auth/services/user-verification/user-verification.service.spec.ts index 102e4bac8da..677b6ff4499 100644 --- a/libs/common/src/auth/services/user-verification/user-verification.service.spec.ts +++ b/libs/common/src/auth/services/user-verification/user-verification.service.spec.ts @@ -12,11 +12,9 @@ import { BiometricsStatus, KdfConfig, KeyService, + KdfConfigService, } from "@bitwarden/key-management"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { KdfConfigService } from "../../../../../key-management/src/abstractions/kdf-config.service"; import { FakeAccountService, mockAccountServiceWith } from "../../../../spec"; import { VaultTimeoutSettingsService } from "../../../abstractions/vault-timeout/vault-timeout-settings.service"; import { I18nService } from "../../../platform/abstractions/i18n.service"; diff --git a/libs/common/src/billing/services/organization-billing.service.ts b/libs/common/src/billing/services/organization-billing.service.ts index e61b092d677..83efbf0a30c 100644 --- a/libs/common/src/billing/services/organization-billing.service.ts +++ b/libs/common/src/billing/services/organization-billing.service.ts @@ -7,7 +7,7 @@ import { OrganizationApiServiceAbstraction as OrganizationApiService } from "../ import { OrganizationCreateRequest } from "../../admin-console/models/request/organization-create.request"; import { OrganizationKeysRequest } from "../../admin-console/models/request/organization-keys.request"; import { OrganizationResponse } from "../../admin-console/models/response/organization.response"; -import { EncryptService } from "../../platform/abstractions/encrypt.service"; +import { EncryptService } from "../../key-management/crypto/abstractions/encrypt.service"; import { I18nService } from "../../platform/abstractions/i18n.service"; import { EncString } from "../../platform/models/domain/enc-string"; import { SyncService } from "../../platform/sync"; diff --git a/libs/common/src/enums/feature-flag.enum.ts b/libs/common/src/enums/feature-flag.enum.ts index 2900fd2fc8b..5137fda329f 100644 --- a/libs/common/src/enums/feature-flag.enum.ts +++ b/libs/common/src/enums/feature-flag.enum.ts @@ -8,7 +8,7 @@ export enum FeatureFlag { ProviderClientVaultPrivacyBanner = "ac-2833-provider-client-vault-privacy-banner", AccountDeprovisioning = "pm-10308-account-deprovisioning", VerifiedSsoDomainEndpoint = "pm-12337-refactor-sso-details-endpoint", - PM14505AdminConsoleIntegrationPage = "pm-14505-admin-console-integration-page", + LimitItemDeletion = "pm-15493-restrict-item-deletion-to-can-manage-permission", /* Autofill */ BlockBrowserInjectionsByDomain = "block-browser-injections-by-domain", @@ -23,8 +23,11 @@ export enum FeatureFlag { NotificationRefresh = "notification-refresh", UseTreeWalkerApiForPageDetailsCollection = "use-tree-walker-api-for-page-details-collection", + /* Tools */ ItemShare = "item-share", - GeneratorToolsModernization = "generator-tools-modernization", + CriticalApps = "pm-14466-risk-insights-critical-application", + EnableRiskInsightsNotifications = "enable-risk-insights-notifications", + AC1795_UpdatedSubscriptionStatusSection = "AC-1795_updated-subscription-status-section", ExtensionRefresh = "extension-refresh", PersistPopupView = "persist-popup-view", @@ -36,18 +39,17 @@ export enum FeatureFlag { SSHAgent = "ssh-agent", CipherKeyEncryption = "cipher-key-encryption", PM11901_RefactorSelfHostingLicenseUploader = "PM-11901-refactor-self-hosting-license-uploader", - CriticalApps = "pm-14466-risk-insights-critical-application", TrialPaymentOptional = "PM-8163-trial-payment", SecurityTasks = "security-tasks", NewDeviceVerificationTemporaryDismiss = "new-device-temporary-dismiss", NewDeviceVerificationPermanentDismiss = "new-device-permanent-dismiss", - DisableFreeFamiliesSponsorship = "PM-12274-disable-free-families-sponsorship", MacOsNativeCredentialSync = "macos-native-credential-sync", PM9111ExtensionPersistAddEditForm = "pm-9111-extension-persist-add-edit-form", PrivateKeyRegeneration = "pm-12241-private-key-regeneration", ResellerManagedOrgAlert = "PM-15814-alert-owners-of-reseller-managed-orgs", + AccountDeprovisioningBanner = "pm-17120-account-deprovisioning-admin-console-banner", NewDeviceVerification = "new-device-verification", - EnableRiskInsightsNotifications = "enable-risk-insights-notifications", + PM15179_AddExistingOrgsFromProviderPortal = "pm-15179-add-existing-orgs-from-provider-portal", } export type AllowedFeatureFlagTypes = boolean | number | string; @@ -66,7 +68,7 @@ export const DefaultFeatureFlagValue = { [FeatureFlag.ProviderClientVaultPrivacyBanner]: FALSE, [FeatureFlag.AccountDeprovisioning]: FALSE, [FeatureFlag.VerifiedSsoDomainEndpoint]: FALSE, - [FeatureFlag.PM14505AdminConsoleIntegrationPage]: FALSE, + [FeatureFlag.LimitItemDeletion]: FALSE, /* Autofill */ [FeatureFlag.BlockBrowserInjectionsByDomain]: FALSE, @@ -81,8 +83,11 @@ export const DefaultFeatureFlagValue = { [FeatureFlag.NotificationRefresh]: FALSE, [FeatureFlag.UseTreeWalkerApiForPageDetailsCollection]: FALSE, + /* Tools */ [FeatureFlag.ItemShare]: FALSE, - [FeatureFlag.GeneratorToolsModernization]: FALSE, + [FeatureFlag.CriticalApps]: FALSE, + [FeatureFlag.EnableRiskInsightsNotifications]: FALSE, + [FeatureFlag.AC1795_UpdatedSubscriptionStatusSection]: FALSE, [FeatureFlag.ExtensionRefresh]: FALSE, [FeatureFlag.PersistPopupView]: FALSE, @@ -94,18 +99,17 @@ export const DefaultFeatureFlagValue = { [FeatureFlag.SSHAgent]: FALSE, [FeatureFlag.CipherKeyEncryption]: FALSE, [FeatureFlag.PM11901_RefactorSelfHostingLicenseUploader]: FALSE, - [FeatureFlag.CriticalApps]: FALSE, [FeatureFlag.TrialPaymentOptional]: FALSE, [FeatureFlag.SecurityTasks]: FALSE, [FeatureFlag.NewDeviceVerificationTemporaryDismiss]: FALSE, [FeatureFlag.NewDeviceVerificationPermanentDismiss]: FALSE, - [FeatureFlag.DisableFreeFamiliesSponsorship]: FALSE, [FeatureFlag.MacOsNativeCredentialSync]: FALSE, [FeatureFlag.PM9111ExtensionPersistAddEditForm]: FALSE, [FeatureFlag.PrivateKeyRegeneration]: FALSE, [FeatureFlag.ResellerManagedOrgAlert]: FALSE, + [FeatureFlag.AccountDeprovisioningBanner]: FALSE, [FeatureFlag.NewDeviceVerification]: FALSE, - [FeatureFlag.EnableRiskInsightsNotifications]: FALSE, + [FeatureFlag.PM15179_AddExistingOrgsFromProviderPortal]: FALSE, } satisfies Record; export type DefaultFeatureFlagValueType = typeof DefaultFeatureFlagValue; diff --git a/libs/common/src/key-management/crypto/abstractions/bulk-encrypt.service.ts b/libs/common/src/key-management/crypto/abstractions/bulk-encrypt.service.ts new file mode 100644 index 00000000000..3e47ccdb5f2 --- /dev/null +++ b/libs/common/src/key-management/crypto/abstractions/bulk-encrypt.service.ts @@ -0,0 +1,10 @@ +import { Decryptable } from "@bitwarden/common/platform/interfaces/decryptable.interface"; +import { InitializerMetadata } from "@bitwarden/common/platform/interfaces/initializer-metadata.interface"; +import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; + +export abstract class BulkEncryptService { + abstract decryptItems( + items: Decryptable[], + key: SymmetricCryptoKey, + ): Promise; +} diff --git a/libs/common/src/platform/abstractions/encrypt.service.ts b/libs/common/src/key-management/crypto/abstractions/encrypt.service.ts similarity index 82% rename from libs/common/src/platform/abstractions/encrypt.service.ts rename to libs/common/src/key-management/crypto/abstractions/encrypt.service.ts index a660524699d..e00d053ce7b 100644 --- a/libs/common/src/platform/abstractions/encrypt.service.ts +++ b/libs/common/src/key-management/crypto/abstractions/encrypt.service.ts @@ -1,9 +1,9 @@ -import { Decryptable } from "../interfaces/decryptable.interface"; -import { Encrypted } from "../interfaces/encrypted"; -import { InitializerMetadata } from "../interfaces/initializer-metadata.interface"; -import { EncArrayBuffer } from "../models/domain/enc-array-buffer"; -import { EncString } from "../models/domain/enc-string"; -import { SymmetricCryptoKey } from "../models/domain/symmetric-crypto-key"; +import { Decryptable } from "@bitwarden/common/platform/interfaces/decryptable.interface"; +import { Encrypted } from "@bitwarden/common/platform/interfaces/encrypted"; +import { InitializerMetadata } from "@bitwarden/common/platform/interfaces/initializer-metadata.interface"; +import { EncArrayBuffer } from "@bitwarden/common/platform/models/domain/enc-array-buffer"; +import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; +import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; export abstract class EncryptService { abstract encrypt(plainValue: string | Uint8Array, key: SymmetricCryptoKey): Promise; diff --git a/libs/common/src/platform/services/cryptography/bulk-encrypt.service.implementation.ts b/libs/common/src/key-management/crypto/services/bulk-encrypt.service.implementation.ts similarity index 84% rename from libs/common/src/platform/services/cryptography/bulk-encrypt.service.implementation.ts rename to libs/common/src/key-management/crypto/services/bulk-encrypt.service.implementation.ts index 1320fbae0e0..1d1e0f52279 100644 --- a/libs/common/src/platform/services/cryptography/bulk-encrypt.service.implementation.ts +++ b/libs/common/src/key-management/crypto/services/bulk-encrypt.service.implementation.ts @@ -3,15 +3,14 @@ import { firstValueFrom, fromEvent, filter, map, takeUntil, defaultIfEmpty, Subject } from "rxjs"; import { Jsonify } from "type-fest"; -import { BulkEncryptService } from "../../abstractions/bulk-encrypt.service"; -import { CryptoFunctionService } from "../../abstractions/crypto-function.service"; -import { LogService } from "../../abstractions/log.service"; -import { Decryptable } from "../../interfaces/decryptable.interface"; -import { InitializerMetadata } from "../../interfaces/initializer-metadata.interface"; -import { Utils } from "../../misc/utils"; -import { SymmetricCryptoKey } from "../../models/domain/symmetric-crypto-key"; - -import { getClassInitializer } from "./get-class-initializer"; +import { BulkEncryptService } from "@bitwarden/common/key-management/crypto/abstractions/bulk-encrypt.service"; +import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; +import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; +import { Decryptable } from "@bitwarden/common/platform/interfaces/decryptable.interface"; +import { InitializerMetadata } from "@bitwarden/common/platform/interfaces/initializer-metadata.interface"; +import { Utils } from "@bitwarden/common/platform/misc/utils"; +import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; +import { getClassInitializer } from "@bitwarden/common/platform/services/cryptography/get-class-initializer"; // TTL (time to live) is not strictly required but avoids tying up memory resources if inactive const workerTTL = 60000; // 1 minute @@ -88,7 +87,7 @@ export class BulkEncryptServiceImplementation implements BulkEncryptService { new Worker( new URL( /* webpackChunkName: 'encrypt-worker' */ - "@bitwarden/common/platform/services/cryptography/encrypt.worker.ts", + "@bitwarden/common/key-management/crypto/services/encrypt.worker.ts", import.meta.url, ), ), diff --git a/libs/common/src/platform/services/cryptography/encrypt.service.implementation.ts b/libs/common/src/key-management/crypto/services/encrypt.service.implementation.ts similarity index 90% rename from libs/common/src/platform/services/cryptography/encrypt.service.implementation.ts rename to libs/common/src/key-management/crypto/services/encrypt.service.implementation.ts index 68263cadf27..075b9da4964 100644 --- a/libs/common/src/platform/services/cryptography/encrypt.service.implementation.ts +++ b/libs/common/src/key-management/crypto/services/encrypt.service.implementation.ts @@ -1,17 +1,21 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { Utils } from "../../../platform/misc/utils"; -import { CryptoFunctionService } from "../../abstractions/crypto-function.service"; -import { EncryptService } from "../../abstractions/encrypt.service"; -import { LogService } from "../../abstractions/log.service"; -import { EncryptionType, encryptionTypeToString as encryptionTypeName } from "../../enums"; -import { Decryptable } from "../../interfaces/decryptable.interface"; -import { Encrypted } from "../../interfaces/encrypted"; -import { InitializerMetadata } from "../../interfaces/initializer-metadata.interface"; -import { EncArrayBuffer } from "../../models/domain/enc-array-buffer"; -import { EncString } from "../../models/domain/enc-string"; -import { EncryptedObject } from "../../models/domain/encrypted-object"; -import { SymmetricCryptoKey } from "../../models/domain/symmetric-crypto-key"; +import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; +import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; +import { + EncryptionType, + encryptionTypeToString as encryptionTypeName, +} from "@bitwarden/common/platform/enums"; +import { Decryptable } from "@bitwarden/common/platform/interfaces/decryptable.interface"; +import { Encrypted } from "@bitwarden/common/platform/interfaces/encrypted"; +import { InitializerMetadata } from "@bitwarden/common/platform/interfaces/initializer-metadata.interface"; +import { Utils } from "@bitwarden/common/platform/misc/utils"; +import { EncArrayBuffer } from "@bitwarden/common/platform/models/domain/enc-array-buffer"; +import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; +import { EncryptedObject } from "@bitwarden/common/platform/models/domain/encrypted-object"; +import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; + +import { EncryptService } from "../abstractions/encrypt.service"; export class EncryptServiceImplementation implements EncryptService { constructor( diff --git a/libs/common/src/platform/services/encrypt.service.spec.ts b/libs/common/src/key-management/crypto/services/encrypt.service.spec.ts similarity index 91% rename from libs/common/src/platform/services/encrypt.service.spec.ts rename to libs/common/src/key-management/crypto/services/encrypt.service.spec.ts index 609b5100a10..8d75b528596 100644 --- a/libs/common/src/platform/services/encrypt.service.spec.ts +++ b/libs/common/src/key-management/crypto/services/encrypt.service.spec.ts @@ -1,15 +1,17 @@ import { mockReset, mock } from "jest-mock-extended"; -import { makeStaticByteArray } from "../../../spec"; -import { CsprngArray } from "../../types/csprng"; -import { CryptoFunctionService } from "../abstractions/crypto-function.service"; -import { LogService } from "../abstractions/log.service"; -import { EncryptionType } from "../enums"; -import { Utils } from "../misc/utils"; -import { EncArrayBuffer } from "../models/domain/enc-array-buffer"; -import { EncString } from "../models/domain/enc-string"; -import { SymmetricCryptoKey } from "../models/domain/symmetric-crypto-key"; -import { EncryptServiceImplementation } from "../services/cryptography/encrypt.service.implementation"; +import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; +import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; +import { EncryptionType } from "@bitwarden/common/platform/enums"; +import { Utils } from "@bitwarden/common/platform/misc/utils"; +import { EncArrayBuffer } from "@bitwarden/common/platform/models/domain/enc-array-buffer"; +import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; +import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; +import { CsprngArray } from "@bitwarden/common/types/csprng"; + +import { makeStaticByteArray } from "../../../../spec"; + +import { EncryptServiceImplementation } from "./encrypt.service.implementation"; describe("EncryptService", () => { const cryptoFunctionService = mock(); diff --git a/libs/common/src/platform/services/cryptography/encrypt.worker.ts b/libs/common/src/key-management/crypto/services/encrypt.worker.ts similarity index 71% rename from libs/common/src/platform/services/cryptography/encrypt.worker.ts rename to libs/common/src/key-management/crypto/services/encrypt.worker.ts index a293e1c6bb0..84ffcf56934 100644 --- a/libs/common/src/platform/services/cryptography/encrypt.worker.ts +++ b/libs/common/src/key-management/crypto/services/encrypt.worker.ts @@ -2,14 +2,14 @@ // @ts-strict-ignore import { Jsonify } from "type-fest"; -import { Decryptable } from "../../interfaces/decryptable.interface"; -import { SymmetricCryptoKey } from "../../models/domain/symmetric-crypto-key"; -import { ConsoleLogService } from "../console-log.service"; -import { ContainerService } from "../container.service"; -import { WebCryptoFunctionService } from "../web-crypto-function.service"; +import { Decryptable } from "@bitwarden/common/platform/interfaces/decryptable.interface"; +import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; +import { ConsoleLogService } from "@bitwarden/common/platform/services/console-log.service"; +import { ContainerService } from "@bitwarden/common/platform/services/container.service"; +import { getClassInitializer } from "@bitwarden/common/platform/services/cryptography/get-class-initializer"; +import { WebCryptoFunctionService } from "@bitwarden/common/platform/services/web-crypto-function.service"; import { EncryptServiceImplementation } from "./encrypt.service.implementation"; -import { getClassInitializer } from "./get-class-initializer"; const workerApi: Worker = self as any; diff --git a/libs/common/src/platform/services/cryptography/fallback-bulk-encrypt.service.ts b/libs/common/src/key-management/crypto/services/fallback-bulk-encrypt.service.ts similarity index 68% rename from libs/common/src/platform/services/cryptography/fallback-bulk-encrypt.service.ts rename to libs/common/src/key-management/crypto/services/fallback-bulk-encrypt.service.ts index 7a4fd8f3c1d..80fdd27895d 100644 --- a/libs/common/src/platform/services/cryptography/fallback-bulk-encrypt.service.ts +++ b/libs/common/src/key-management/crypto/services/fallback-bulk-encrypt.service.ts @@ -1,10 +1,11 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { BulkEncryptService } from "../../abstractions/bulk-encrypt.service"; -import { EncryptService } from "../../abstractions/encrypt.service"; -import { Decryptable } from "../../interfaces/decryptable.interface"; -import { InitializerMetadata } from "../../interfaces/initializer-metadata.interface"; -import { SymmetricCryptoKey } from "../../models/domain/symmetric-crypto-key"; +import { BulkEncryptService } from "@bitwarden/common/key-management/crypto/abstractions/bulk-encrypt.service"; +import { Decryptable } from "@bitwarden/common/platform/interfaces/decryptable.interface"; +import { InitializerMetadata } from "@bitwarden/common/platform/interfaces/initializer-metadata.interface"; +import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; + +import { EncryptService } from "../abstractions/encrypt.service"; /** * @deprecated For the feature flag from PM-4154, remove once feature is rolled out diff --git a/libs/common/src/platform/services/cryptography/multithread-encrypt.service.implementation.ts b/libs/common/src/key-management/crypto/services/multithread-encrypt.service.implementation.ts similarity index 81% rename from libs/common/src/platform/services/cryptography/multithread-encrypt.service.implementation.ts rename to libs/common/src/key-management/crypto/services/multithread-encrypt.service.implementation.ts index 100dcf152e6..0bf96851563 100644 --- a/libs/common/src/platform/services/cryptography/multithread-encrypt.service.implementation.ts +++ b/libs/common/src/key-management/crypto/services/multithread-encrypt.service.implementation.ts @@ -3,13 +3,13 @@ import { defaultIfEmpty, filter, firstValueFrom, fromEvent, map, Subject, takeUntil } from "rxjs"; import { Jsonify } from "type-fest"; -import { Utils } from "../../../platform/misc/utils"; -import { Decryptable } from "../../interfaces/decryptable.interface"; -import { InitializerMetadata } from "../../interfaces/initializer-metadata.interface"; -import { SymmetricCryptoKey } from "../../models/domain/symmetric-crypto-key"; +import { Decryptable } from "@bitwarden/common/platform/interfaces/decryptable.interface"; +import { InitializerMetadata } from "@bitwarden/common/platform/interfaces/initializer-metadata.interface"; +import { Utils } from "@bitwarden/common/platform/misc/utils"; +import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; +import { getClassInitializer } from "@bitwarden/common/platform/services/cryptography/get-class-initializer"; import { EncryptServiceImplementation } from "./encrypt.service.implementation"; -import { getClassInitializer } from "./get-class-initializer"; // TTL (time to live) is not strictly required but avoids tying up memory resources if inactive const workerTTL = 3 * 60000; // 3 minutes @@ -40,7 +40,7 @@ export class MultithreadEncryptServiceImplementation extends EncryptServiceImple this.worker ??= new Worker( new URL( /* webpackChunkName: 'encrypt-worker' */ - "@bitwarden/common/platform/services/cryptography/encrypt.worker.ts", + "@bitwarden/common/key-management/crypto/services/encrypt.worker.ts", import.meta.url, ), ); diff --git a/libs/common/src/key-management/services/default-process-reload.service.ts b/libs/common/src/key-management/services/default-process-reload.service.ts index 9f97e0a94c1..09fe4e7e10c 100644 --- a/libs/common/src/key-management/services/default-process-reload.service.ts +++ b/libs/common/src/key-management/services/default-process-reload.service.ts @@ -2,11 +2,9 @@ // @ts-strict-ignore import { firstValueFrom, map, timeout } from "rxjs"; +import { PinServiceAbstraction } from "@bitwarden/auth/common"; import { BiometricStateService } from "@bitwarden/key-management"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { PinServiceAbstraction } from "../../../../auth/src/common/abstractions"; import { VaultTimeoutSettingsService } from "../../abstractions/vault-timeout/vault-timeout-settings.service"; import { AccountService } from "../../auth/abstractions/account.service"; import { AuthService } from "../../auth/abstractions/auth.service"; diff --git a/libs/common/src/platform/abstractions/bulk-encrypt.service.ts b/libs/common/src/platform/abstractions/bulk-encrypt.service.ts deleted file mode 100644 index 4cdff0c769a..00000000000 --- a/libs/common/src/platform/abstractions/bulk-encrypt.service.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Decryptable } from "../interfaces/decryptable.interface"; -import { InitializerMetadata } from "../interfaces/initializer-metadata.interface"; -import { SymmetricCryptoKey } from "../models/domain/symmetric-crypto-key"; - -export abstract class BulkEncryptService { - abstract decryptItems( - items: Decryptable[], - key: SymmetricCryptoKey, - ): Promise; -} diff --git a/libs/common/src/platform/abstractions/sdk/sdk.service.ts b/libs/common/src/platform/abstractions/sdk/sdk.service.ts index 78ec11c4022..22ad2b44ff9 100644 --- a/libs/common/src/platform/abstractions/sdk/sdk.service.ts +++ b/libs/common/src/platform/abstractions/sdk/sdk.service.ts @@ -3,6 +3,7 @@ import { Observable } from "rxjs"; import { BitwardenClient } from "@bitwarden/sdk-internal"; import { UserId } from "../../../types/guid"; +import { Rc } from "../../misc/reference-counting/rc"; export abstract class SdkService { /** @@ -27,5 +28,5 @@ export abstract class SdkService { * * @param userId */ - abstract userClient$(userId: UserId): Observable; + abstract userClient$(userId: UserId): Observable | undefined>; } diff --git a/libs/common/src/platform/misc/reference-counting/rc.spec.ts b/libs/common/src/platform/misc/reference-counting/rc.spec.ts new file mode 100644 index 00000000000..094abfe3615 --- /dev/null +++ b/libs/common/src/platform/misc/reference-counting/rc.spec.ts @@ -0,0 +1,93 @@ +// Temporary workaround for Symbol.dispose +// remove when https://github.com/jestjs/jest/issues/14874 is resolved and *released* +const disposeSymbol: unique symbol = Symbol("Symbol.dispose"); +const asyncDisposeSymbol: unique symbol = Symbol("Symbol.asyncDispose"); +(Symbol as any).asyncDispose ??= asyncDisposeSymbol as unknown as SymbolConstructor["asyncDispose"]; +(Symbol as any).dispose ??= disposeSymbol as unknown as SymbolConstructor["dispose"]; + +// Import needs to be after the workaround +import { Rc } from "./rc"; + +export class FreeableTestValue { + isFreed = false; + + free() { + this.isFreed = true; + } +} + +describe("Rc", () => { + let value: FreeableTestValue; + let rc: Rc; + + beforeEach(() => { + value = new FreeableTestValue(); + rc = new Rc(value); + }); + + it("should increase refCount when taken", () => { + rc.take(); + + expect(rc["refCount"]).toBe(1); + }); + + it("should return value on take", () => { + // eslint-disable-next-line @bitwarden/platform/required-using + const reference = rc.take(); + + expect(reference.value).toBe(value); + }); + + it("should decrease refCount when disposing reference", () => { + // eslint-disable-next-line @bitwarden/platform/required-using + const reference = rc.take(); + + reference[Symbol.dispose](); + + expect(rc["refCount"]).toBe(0); + }); + + it("should automatically decrease refCount when reference goes out of scope", () => { + { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + using reference = rc.take(); + } + + expect(rc["refCount"]).toBe(0); + }); + + it("should not free value when refCount reaches 0 if not marked for disposal", () => { + // eslint-disable-next-line @bitwarden/platform/required-using + const reference = rc.take(); + + reference[Symbol.dispose](); + + expect(value.isFreed).toBe(false); + }); + + it("should free value when refCount reaches 0 and rc is marked for disposal", () => { + // eslint-disable-next-line @bitwarden/platform/required-using + const reference = rc.take(); + rc.markForDisposal(); + + reference[Symbol.dispose](); + + expect(value.isFreed).toBe(true); + }); + + it("should free value when marked for disposal if refCount is 0", () => { + // eslint-disable-next-line @bitwarden/platform/required-using + const reference = rc.take(); + reference[Symbol.dispose](); + + rc.markForDisposal(); + + expect(value.isFreed).toBe(true); + }); + + it("should throw error when trying to take a disposed reference", () => { + rc.markForDisposal(); + + expect(() => rc.take()).toThrow(); + }); +}); diff --git a/libs/common/src/platform/misc/reference-counting/rc.ts b/libs/common/src/platform/misc/reference-counting/rc.ts new file mode 100644 index 00000000000..9be102b43d3 --- /dev/null +++ b/libs/common/src/platform/misc/reference-counting/rc.ts @@ -0,0 +1,76 @@ +import { UsingRequired } from "../using-required"; + +export type Freeable = { free: () => void }; + +/** + * Reference counted disposable value. + * This class is used to manage the lifetime of a value that needs to be + * freed of at a specific time but might still be in-use when that happens. + */ +export class Rc { + private markedForDisposal = false; + private refCount = 0; + private value: T; + + constructor(value: T) { + this.value = value; + } + + /** + * Use this function when you want to use the underlying object. + * This will guarantee that you have a reference to the object + * and that it won't be freed until your reference goes out of scope. + * + * This function must be used with the `using` keyword. + * + * @example + * ```typescript + * function someFunction(rc: Rc) { + * using reference = rc.take(); + * reference.value.doSomething(); + * // reference is automatically disposed here + * } + * ``` + * + * @returns The value. + */ + take(): Ref { + if (this.markedForDisposal) { + throw new Error("Cannot take a reference to a value marked for disposal"); + } + + this.refCount++; + return new Ref(() => this.release(), this.value); + } + + /** + * Mark this Rc for disposal. When the refCount reaches 0, the value + * will be freed. + */ + markForDisposal() { + this.markedForDisposal = true; + this.freeIfPossible(); + } + + private release() { + this.refCount--; + this.freeIfPossible(); + } + + private freeIfPossible() { + if (this.refCount === 0 && this.markedForDisposal) { + this.value.free(); + } + } +} + +export class Ref implements UsingRequired { + constructor( + private readonly release: () => void, + readonly value: T, + ) {} + + [Symbol.dispose]() { + this.release(); + } +} diff --git a/libs/common/src/platform/misc/using-required.ts b/libs/common/src/platform/misc/using-required.ts new file mode 100644 index 00000000000..f641b9f312f --- /dev/null +++ b/libs/common/src/platform/misc/using-required.ts @@ -0,0 +1,11 @@ +export type Disposable = { [Symbol.dispose]: () => void }; + +/** + * Types implementing this type must be used together with the `using` keyword + * + * @example using ref = rc.take(); + */ +// We want to use `interface` here because it creates a separate type. +// Type aliasing would not expose `UsingRequired` to the linter. +// eslint-disable-next-line @typescript-eslint/no-empty-object-type +export interface UsingRequired extends Disposable {} diff --git a/libs/common/src/platform/misc/utils.ts b/libs/common/src/platform/misc/utils.ts index f654897e9e2..ef65d2130a0 100644 --- a/libs/common/src/platform/misc/utils.ts +++ b/libs/common/src/platform/misc/utils.ts @@ -8,10 +8,9 @@ import { Observable, of, switchMap } from "rxjs"; import { getHostname, parse } from "tldts"; import { Merge } from "type-fest"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { KeyService } from "../../../../key-management/src/abstractions/key.service"; -import { EncryptService } from "../abstractions/encrypt.service"; +import { KeyService } from "@bitwarden/key-management"; + +import { EncryptService } from "../../key-management/crypto/abstractions/encrypt.service"; import { I18nService } from "../abstractions/i18n.service"; // FIXME: Remove when updating file. Eslint update diff --git a/libs/common/src/platform/models/domain/domain-base.spec.ts b/libs/common/src/platform/models/domain/domain-base.spec.ts index 80a4e5e8606..0c13f9a2119 100644 --- a/libs/common/src/platform/models/domain/domain-base.spec.ts +++ b/libs/common/src/platform/models/domain/domain-base.spec.ts @@ -1,7 +1,7 @@ import { mock, MockProxy } from "jest-mock-extended"; import { makeEncString, makeSymmetricCryptoKey } from "../../../../spec"; -import { EncryptService } from "../../abstractions/encrypt.service"; +import { EncryptService } from "../../../key-management/crypto/abstractions/encrypt.service"; import { Utils } from "../../misc/utils"; import Domain from "./domain-base"; diff --git a/libs/common/src/platform/models/domain/domain-base.ts b/libs/common/src/platform/models/domain/domain-base.ts index 110a1dc7208..192034254b9 100644 --- a/libs/common/src/platform/models/domain/domain-base.ts +++ b/libs/common/src/platform/models/domain/domain-base.ts @@ -2,8 +2,8 @@ // @ts-strict-ignore import { ConditionalExcept, ConditionalKeys, Constructor } from "type-fest"; +import { EncryptService } from "../../../key-management/crypto/abstractions/encrypt.service"; import { View } from "../../../models/view/view"; -import { EncryptService } from "../../abstractions/encrypt.service"; import { EncString } from "./enc-string"; import { SymmetricCryptoKey } from "./symmetric-crypto-key"; diff --git a/libs/common/src/platform/models/domain/enc-string.spec.ts b/libs/common/src/platform/models/domain/enc-string.spec.ts index b4916b9f70a..3b2586fc22f 100644 --- a/libs/common/src/platform/models/domain/enc-string.spec.ts +++ b/libs/common/src/platform/models/domain/enc-string.spec.ts @@ -1,10 +1,9 @@ import { mock, MockProxy } from "jest-mock-extended"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { KeyService } from "../../../../../key-management/src/abstractions/key.service"; +import { KeyService } from "@bitwarden/key-management"; + import { makeEncString, makeStaticByteArray } from "../../../../spec"; -import { EncryptService } from "../../../platform/abstractions/encrypt.service"; +import { EncryptService } from "../../../key-management/crypto/abstractions/encrypt.service"; import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-crypto-key"; import { UserKey, OrgKey } from "../../../types/key"; import { EncryptionType } from "../../enums"; diff --git a/libs/common/src/platform/models/domain/enc-string.ts b/libs/common/src/platform/models/domain/enc-string.ts index f148664a4f9..a8fee428b13 100644 --- a/libs/common/src/platform/models/domain/enc-string.ts +++ b/libs/common/src/platform/models/domain/enc-string.ts @@ -2,7 +2,7 @@ // @ts-strict-ignore import { Jsonify, Opaque } from "type-fest"; -import { EncryptService } from "../../abstractions/encrypt.service"; +import { EncryptService } from "../../../key-management/crypto/abstractions/encrypt.service"; import { EncryptionType, EXPECTED_NUM_PARTS_BY_ENCRYPTION_TYPE } from "../../enums"; import { Encrypted } from "../../interfaces/encrypted"; import { Utils } from "../../misc/utils"; diff --git a/libs/common/src/platform/notifications/internal/default-notifications.service.ts b/libs/common/src/platform/notifications/internal/default-notifications.service.ts index c6b330857a4..f0586e37ff7 100644 --- a/libs/common/src/platform/notifications/internal/default-notifications.service.ts +++ b/libs/common/src/platform/notifications/internal/default-notifications.service.ts @@ -151,11 +151,15 @@ export class DefaultNotificationsService implements NotificationsServiceAbstract await this.syncService.syncUpsertCipher( notification.payload as SyncCipherNotification, notification.type === NotificationType.SyncCipherUpdate, + payloadUserId, ); break; case NotificationType.SyncCipherDelete: case NotificationType.SyncLoginDelete: - await this.syncService.syncDeleteCipher(notification.payload as SyncCipherNotification); + await this.syncService.syncDeleteCipher( + notification.payload as SyncCipherNotification, + payloadUserId, + ); break; case NotificationType.SyncFolderCreate: case NotificationType.SyncFolderUpdate: diff --git a/libs/common/src/platform/services/container.service.ts b/libs/common/src/platform/services/container.service.ts index c3e727a2e1e..1428b2bbd7c 100644 --- a/libs/common/src/platform/services/container.service.ts +++ b/libs/common/src/platform/services/container.service.ts @@ -1,7 +1,6 @@ -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { KeyService } from "../../../../key-management/src/abstractions/key.service"; -import { EncryptService } from "../abstractions/encrypt.service"; +import { KeyService } from "@bitwarden/key-management"; + +import { EncryptService } from "../../key-management/crypto/abstractions/encrypt.service"; export class ContainerService { constructor( diff --git a/libs/common/src/platform/services/fido2/fido2-authenticator.service.spec.ts b/libs/common/src/platform/services/fido2/fido2-authenticator.service.spec.ts index 226f4c2cfe9..3ea86a1f504 100644 --- a/libs/common/src/platform/services/fido2/fido2-authenticator.service.spec.ts +++ b/libs/common/src/platform/services/fido2/fido2-authenticator.service.spec.ts @@ -3,7 +3,8 @@ import { TextEncoder } from "util"; import { mock, MockProxy } from "jest-mock-extended"; import { BehaviorSubject, of } from "rxjs"; -import { Account, AccountService } from "../../../auth/abstractions/account.service"; +import { mockAccountServiceWith } from "../../../../spec"; +import { Account } from "../../../auth/abstractions/account.service"; import { UserId } from "../../../types/guid"; import { CipherService } from "../../../vault/abstractions/cipher.service"; import { SyncService } from "../../../vault/abstractions/sync/sync.service.abstraction"; @@ -46,7 +47,6 @@ describe("FidoAuthenticatorService", () => { let userInterface!: MockProxy>; let userInterfaceSession!: MockProxy; let syncService!: MockProxy; - let accountService!: MockProxy; let authenticator!: Fido2AuthenticatorService; let windowReference!: ParentWindowReference; @@ -58,7 +58,7 @@ describe("FidoAuthenticatorService", () => { syncService = mock({ activeUserLastSync$: () => of(new Date()), }); - accountService = mock(); + const accountService = mockAccountServiceWith("testId" as UserId); authenticator = new Fido2AuthenticatorService( cipherService, userInterface, diff --git a/libs/common/src/platform/services/fido2/fido2-authenticator.service.ts b/libs/common/src/platform/services/fido2/fido2-authenticator.service.ts index 376f4dcdced..76bd19b2876 100644 --- a/libs/common/src/platform/services/fido2/fido2-authenticator.service.ts +++ b/libs/common/src/platform/services/fido2/fido2-authenticator.service.ts @@ -1,8 +1,9 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { firstValueFrom, map } from "rxjs"; +import { firstValueFrom } from "rxjs"; import { AccountService } from "../../../auth/abstractions/account.service"; +import { getUserId } from "../../../auth/services/account.service"; import { CipherService } from "../../../vault/abstractions/cipher.service"; import { SyncService } from "../../../vault/abstractions/sync/sync.service.abstraction"; import { CipherRepromptType } from "../../../vault/enums/cipher-reprompt-type"; @@ -145,10 +146,10 @@ export class Fido2AuthenticatorService try { keyPair = await createKeyPair(); pubKeyDer = await crypto.subtle.exportKey("spki", keyPair.publicKey); - const encrypted = await this.cipherService.get(cipherId); const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), + this.accountService.activeAccount$.pipe(getUserId), ); + const encrypted = await this.cipherService.get(cipherId, activeUserId); cipher = await encrypted.decrypt( await this.cipherService.getKeyForCipherKeyDecryption(encrypted, activeUserId), @@ -309,7 +310,7 @@ export class Fido2AuthenticatorService if (selectedFido2Credential.counter > 0) { const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), + this.accountService.activeAccount$.pipe(getUserId), ); const encrypted = await this.cipherService.encrypt(selectedCipher, activeUserId); await this.cipherService.updateWithServer(encrypted); @@ -400,7 +401,8 @@ export class Fido2AuthenticatorService return []; } - const ciphers = await this.cipherService.getAllDecrypted(); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + const ciphers = await this.cipherService.getAllDecrypted(activeUserId); return ciphers .filter( (cipher) => @@ -421,7 +423,8 @@ export class Fido2AuthenticatorService return []; } - const ciphers = await this.cipherService.getAllDecrypted(); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + const ciphers = await this.cipherService.getAllDecrypted(activeUserId); return ciphers.filter( (cipher) => !cipher.isDeleted && @@ -438,7 +441,8 @@ export class Fido2AuthenticatorService } private async findCredentialsByRp(rpId: string): Promise { - const ciphers = await this.cipherService.getAllDecrypted(); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + const ciphers = await this.cipherService.getAllDecrypted(activeUserId); return ciphers.filter( (cipher) => !cipher.isDeleted && diff --git a/libs/common/src/platform/services/sdk/default-sdk.service.spec.ts b/libs/common/src/platform/services/sdk/default-sdk.service.spec.ts index c5917e0230f..e8dfde863ec 100644 --- a/libs/common/src/platform/services/sdk/default-sdk.service.spec.ts +++ b/libs/common/src/platform/services/sdk/default-sdk.service.spec.ts @@ -10,6 +10,7 @@ import { UserKey } from "../../../types/key"; import { Environment, EnvironmentService } from "../../abstractions/environment.service"; import { PlatformUtilsService } from "../../abstractions/platform-utils.service"; import { SdkClientFactory } from "../../abstractions/sdk/sdk-client-factory"; +import { Rc } from "../../misc/reference-counting/rc"; import { EncryptedString } from "../../models/domain/enc-string"; import { SymmetricCryptoKey } from "../../models/domain/symmetric-crypto-key"; @@ -75,15 +76,14 @@ describe("DefaultSdkService", () => { }); it("creates an SDK client when called the first time", async () => { - const result = await firstValueFrom(service.userClient$(userId)); + await firstValueFrom(service.userClient$(userId)); - expect(result).toBe(mockClient); expect(sdkClientFactory.createSdkClient).toHaveBeenCalled(); }); it("does not create an SDK client when called the second time with same userId", async () => { - const subject_1 = new BehaviorSubject(undefined); - const subject_2 = new BehaviorSubject(undefined); + const subject_1 = new BehaviorSubject | undefined>(undefined); + const subject_2 = new BehaviorSubject | undefined>(undefined); // Use subjects to ensure the subscription is kept alive service.userClient$(userId).subscribe(subject_1); @@ -92,14 +92,14 @@ describe("DefaultSdkService", () => { // Wait for the next tick to ensure all async operations are done await new Promise(process.nextTick); - expect(subject_1.value).toBe(mockClient); - expect(subject_2.value).toBe(mockClient); + expect(subject_1.value.take().value).toBe(mockClient); + expect(subject_2.value.take().value).toBe(mockClient); expect(sdkClientFactory.createSdkClient).toHaveBeenCalledTimes(1); }); it("destroys the SDK client when all subscriptions are closed", async () => { - const subject_1 = new BehaviorSubject(undefined); - const subject_2 = new BehaviorSubject(undefined); + const subject_1 = new BehaviorSubject | undefined>(undefined); + const subject_2 = new BehaviorSubject | undefined>(undefined); const subscription_1 = service.userClient$(userId).subscribe(subject_1); const subscription_2 = service.userClient$(userId).subscribe(subject_2); await new Promise(process.nextTick); @@ -107,6 +107,7 @@ describe("DefaultSdkService", () => { subscription_1.unsubscribe(); subscription_2.unsubscribe(); + await new Promise(process.nextTick); expect(mockClient.free).toHaveBeenCalledTimes(1); }); @@ -114,7 +115,7 @@ describe("DefaultSdkService", () => { const userKey$ = new BehaviorSubject(new SymmetricCryptoKey(new Uint8Array(64)) as UserKey); keyService.userKey$.calledWith(userId).mockReturnValue(userKey$); - const subject = new BehaviorSubject(undefined); + const subject = new BehaviorSubject | undefined>(undefined); service.userClient$(userId).subscribe(subject); await new Promise(process.nextTick); diff --git a/libs/common/src/platform/services/sdk/default-sdk.service.ts b/libs/common/src/platform/services/sdk/default-sdk.service.ts index e9cecbb15dc..516334c7fb4 100644 --- a/libs/common/src/platform/services/sdk/default-sdk.service.ts +++ b/libs/common/src/platform/services/sdk/default-sdk.service.ts @@ -30,10 +30,11 @@ import { PlatformUtilsService } from "../../abstractions/platform-utils.service" import { SdkClientFactory } from "../../abstractions/sdk/sdk-client-factory"; import { SdkService } from "../../abstractions/sdk/sdk.service"; import { compareValues } from "../../misc/compare-values"; +import { Rc } from "../../misc/reference-counting/rc"; import { EncryptedString } from "../../models/domain/enc-string"; export class DefaultSdkService implements SdkService { - private sdkClientCache = new Map>(); + private sdkClientCache = new Map>>(); client$ = this.environmentService.environment$.pipe( concatMap(async (env) => { @@ -58,7 +59,7 @@ export class DefaultSdkService implements SdkService { private userAgent: string = null, ) {} - userClient$(userId: UserId): Observable { + userClient$(userId: UserId): Observable | undefined> { // TODO: Figure out what happens when the user logs out if (this.sdkClientCache.has(userId)) { return this.sdkClientCache.get(userId); @@ -88,32 +89,31 @@ export class DefaultSdkService implements SdkService { // switchMap is required to allow the clean-up logic to be executed when `combineLatest` emits a new value. switchMap(([env, account, kdfParams, privateKey, userKey, orgKeys]) => { // Create our own observable to be able to implement clean-up logic - return new Observable((subscriber) => { - let client: BitwardenClient; - + return new Observable>((subscriber) => { const createAndInitializeClient = async () => { if (privateKey == null || userKey == null) { return undefined; } const settings = this.toSettings(env); - client = await this.sdkClientFactory.createSdkClient(settings, LogLevel.Info); + const client = await this.sdkClientFactory.createSdkClient(settings, LogLevel.Info); await this.initializeClient(client, account, kdfParams, privateKey, userKey, orgKeys); return client; }; + let client: Rc; createAndInitializeClient() .then((c) => { - client = c; - subscriber.next(c); + client = c === undefined ? undefined : new Rc(c); + subscriber.next(client); }) .catch((e) => { subscriber.error(e); }); - return () => client?.free(); + return () => client?.markForDisposal(); }); }), tap({ diff --git a/libs/common/src/platform/services/user-auto-unlock-key.service.spec.ts b/libs/common/src/platform/services/user-auto-unlock-key.service.spec.ts index 16b3968045a..84511d1e71a 100644 --- a/libs/common/src/platform/services/user-auto-unlock-key.service.spec.ts +++ b/libs/common/src/platform/services/user-auto-unlock-key.service.spec.ts @@ -1,8 +1,7 @@ import { mock } from "jest-mock-extended"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { DefaultKeyService } from "../../../../key-management/src/key.service"; +import { DefaultKeyService } from "@bitwarden/key-management"; + import { CsprngArray } from "../../types/csprng"; import { UserId } from "../../types/guid"; import { UserKey } from "../../types/key"; diff --git a/libs/common/src/platform/services/user-auto-unlock-key.service.ts b/libs/common/src/platform/services/user-auto-unlock-key.service.ts index a8947a49f45..bf64c13b060 100644 --- a/libs/common/src/platform/services/user-auto-unlock-key.service.ts +++ b/libs/common/src/platform/services/user-auto-unlock-key.service.ts @@ -1,6 +1,5 @@ -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { KeyService } from "../../../../key-management/src/abstractions/key.service"; +import { KeyService } from "@bitwarden/key-management"; + import { UserId } from "../../types/guid"; import { KeySuffixOptions } from "../enums"; diff --git a/libs/common/src/platform/state/global-state.ts b/libs/common/src/platform/state/global-state.ts index b0f19c53faa..b2ac634df24 100644 --- a/libs/common/src/platform/state/global-state.ts +++ b/libs/common/src/platform/state/global-state.ts @@ -9,7 +9,7 @@ import { StateUpdateOptions } from "./state-update-options"; export interface GlobalState { /** * Method for allowing you to manipulate state in an additive way. - * @param configureState callback for how you want manipulate this section of state + * @param configureState callback for how you want to manipulate this section of state * @param options Defaults given by @see {module:state-update-options#DEFAULT_OPTIONS} * @param options.shouldUpdate A callback for determining if you want to update state. Defaults to () => true * @param options.combineLatestWith An observable that you want to combine with the current state for callbacks. Defaults to null @@ -18,13 +18,13 @@ export interface GlobalState { * Resolves to the new state. If `shouldUpdate` returns false, the promise will resolve to the current state. */ update: ( - configureState: (state: T, dependency: TCombine) => T, + configureState: (state: T | null, dependency: TCombine) => T | null, options?: StateUpdateOptions, - ) => Promise; + ) => Promise; /** * An observable stream of this state, the first emission of this will be the current state on disk * and subsequent updates will be from an update to that state. */ - state$: Observable; + state$: Observable; } diff --git a/libs/common/src/platform/state/implementations/default-single-user-state.ts b/libs/common/src/platform/state/implementations/default-single-user-state.ts index 4cfba1ffa95..1dafd3aecad 100644 --- a/libs/common/src/platform/state/implementations/default-single-user-state.ts +++ b/libs/common/src/platform/state/implementations/default-single-user-state.ts @@ -16,7 +16,7 @@ export class DefaultSingleUserState extends StateBase> implements SingleUserState { - readonly combinedState$: Observable>; + readonly combinedState$: Observable>; constructor( readonly userId: UserId, diff --git a/libs/common/src/platform/state/implementations/default-state.provider.ts b/libs/common/src/platform/state/implementations/default-state.provider.ts index f86ba11b268..31795767979 100644 --- a/libs/common/src/platform/state/implementations/default-state.provider.ts +++ b/libs/common/src/platform/state/implementations/default-state.provider.ts @@ -54,9 +54,9 @@ export class DefaultStateProvider implements StateProvider { async setUserState( userKeyDefinition: UserKeyDefinition, - value: T, + value: T | null, userId?: UserId, - ): Promise<[UserId, T]> { + ): Promise<[UserId, T | null]> { if (userId) { return [userId, await this.getUser(userId, userKeyDefinition).update(() => value)]; } else { diff --git a/libs/common/src/platform/state/implementations/state-base.ts b/libs/common/src/platform/state/implementations/state-base.ts index f285963d6e6..578720a2281 100644 --- a/libs/common/src/platform/state/implementations/state-base.ts +++ b/libs/common/src/platform/state/implementations/state-base.ts @@ -1,12 +1,12 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore import { - Observable, - ReplaySubject, defer, filter, firstValueFrom, merge, + Observable, + ReplaySubject, share, switchMap, tap, @@ -22,7 +22,7 @@ import { ObservableStorageService, } from "../../abstractions/storage.service"; import { DebugOptions } from "../key-definition"; -import { StateUpdateOptions, populateOptionsWithDefault } from "../state-update-options"; +import { populateOptionsWithDefault, StateUpdateOptions } from "../state-update-options"; import { getStoredValue } from "./util"; @@ -36,7 +36,7 @@ type KeyDefinitionRequirements = { export abstract class StateBase> { private updatePromise: Promise; - readonly state$: Observable; + readonly state$: Observable; constructor( protected readonly key: StorageKey, @@ -86,9 +86,9 @@ export abstract class StateBase> } async update( - configureState: (state: T, dependency: TCombine) => T, + configureState: (state: T | null, dependency: TCombine) => T | null, options: StateUpdateOptions = {}, - ): Promise { + ): Promise { options = populateOptionsWithDefault(options); if (this.updatePromise != null) { await this.updatePromise; @@ -96,17 +96,16 @@ export abstract class StateBase> try { this.updatePromise = this.internalUpdate(configureState, options); - const newState = await this.updatePromise; - return newState; + return await this.updatePromise; } finally { this.updatePromise = null; } } private async internalUpdate( - configureState: (state: T, dependency: TCombine) => T, + configureState: (state: T | null, dependency: TCombine) => T | null, options: StateUpdateOptions, - ): Promise { + ): Promise { const currentState = await this.getStateForUpdate(); const combinedDependencies = options.combineLatestWith != null @@ -122,7 +121,7 @@ export abstract class StateBase> return newState; } - protected async doStorageSave(newState: T, oldState: T) { + protected async doStorageSave(newState: T | null, oldState: T) { if (this.keyDefinition.debug.enableUpdateLogging) { this.logService.info( `Updating '${this.key}' from ${oldState == null ? "null" : "non-null"} to ${newState == null ? "null" : "non-null"}`, diff --git a/libs/common/src/platform/state/state-definitions.ts b/libs/common/src/platform/state/state-definitions.ts index c83119d9ad4..c7901bc34e2 100644 --- a/libs/common/src/platform/state/state-definitions.ts +++ b/libs/common/src/platform/state/state-definitions.ts @@ -29,9 +29,20 @@ export const ORGANIZATION_MANAGEMENT_PREFERENCES_DISK = new StateDefinition( web: "disk-local", }, ); -export const AC_BANNERS_DISMISSED_DISK = new StateDefinition("acBannersDismissed", "disk", { - web: "disk-local", -}); +export const ACCOUNT_DEPROVISIONING_BANNER_DISK = new StateDefinition( + "showAccountDeprovisioningBanner", + "disk", + { + web: "disk-local", + }, +); +export const DELETE_MANAGED_USER_WARNING = new StateDefinition( + "showDeleteManagedUserWarning", + "disk", + { + web: "disk-local", + }, +); // Billing export const BILLING_DISK = new StateDefinition("billing", "disk"); diff --git a/libs/common/src/platform/state/state.provider.ts b/libs/common/src/platform/state/state.provider.ts index 44736500afc..dc8cb3e9359 100644 --- a/libs/common/src/platform/state/state.provider.ts +++ b/libs/common/src/platform/state/state.provider.ts @@ -60,9 +60,9 @@ export abstract class StateProvider { */ abstract setUserState( keyDefinition: UserKeyDefinition, - value: T, + value: T | null, userId?: UserId, - ): Promise<[UserId, T]>; + ): Promise<[UserId, T | null]>; /** @see{@link ActiveUserStateProvider.get} */ abstract getActive(userKeyDefinition: UserKeyDefinition): ActiveUserState; diff --git a/libs/common/src/platform/state/user-state.ts b/libs/common/src/platform/state/user-state.ts index 44bc8732544..26fa6f83fa3 100644 --- a/libs/common/src/platform/state/user-state.ts +++ b/libs/common/src/platform/state/user-state.ts @@ -12,10 +12,11 @@ export interface UserState { readonly state$: Observable; /** Emits a stream of tuples, with the first element being a user id and the second element being the data for that user. */ - readonly combinedState$: Observable>; + readonly combinedState$: Observable>; } export const activeMarker: unique symbol = Symbol("active"); + export interface ActiveUserState extends UserState { readonly [activeMarker]: true; @@ -32,15 +33,16 @@ export interface ActiveUserState extends UserState { * @param options.shouldUpdate A callback for determining if you want to update state. Defaults to () => true * @param options.combineLatestWith An observable that you want to combine with the current state for callbacks. Defaults to null * @param options.msTimeout A timeout for how long you are willing to wait for a `combineLatestWith` option to complete. Defaults to 1000ms. Only applies if `combineLatestWith` is set. - + * * @returns A promise that must be awaited before your next action to ensure the update has been written to state. * Resolves to the new state. If `shouldUpdate` returns false, the promise will resolve to the current state. */ readonly update: ( - configureState: (state: T, dependencies: TCombine) => T, + configureState: (state: T | null, dependencies: TCombine) => T | null, options?: StateUpdateOptions, - ) => Promise<[UserId, T]>; + ) => Promise<[UserId, T | null]>; } + export interface SingleUserState extends UserState { readonly userId: UserId; @@ -51,12 +53,12 @@ export interface SingleUserState extends UserState { * @param options.shouldUpdate A callback for determining if you want to update state. Defaults to () => true * @param options.combineLatestWith An observable that you want to combine with the current state for callbacks. Defaults to null * @param options.msTimeout A timeout for how long you are willing to wait for a `combineLatestWith` option to complete. Defaults to 1000ms. Only applies if `combineLatestWith` is set. - + * * @returns A promise that must be awaited before your next action to ensure the update has been written to state. * Resolves to the new state. If `shouldUpdate` returns false, the promise will resolve to the current state. */ readonly update: ( - configureState: (state: T, dependencies: TCombine) => T, + configureState: (state: T | null, dependencies: TCombine) => T | null, options?: StateUpdateOptions, - ) => Promise; + ) => Promise; } diff --git a/libs/common/src/platform/sync/core-sync.service.ts b/libs/common/src/platform/sync/core-sync.service.ts index cfa9030c9de..92a10baf6d2 100644 --- a/libs/common/src/platform/sync/core-sync.service.ts +++ b/libs/common/src/platform/sync/core-sync.service.ts @@ -129,12 +129,18 @@ export abstract class CoreSyncService implements SyncService { return this.syncCompleted(false); } - async syncUpsertCipher(notification: SyncCipherNotification, isEdit: boolean): Promise { + async syncUpsertCipher( + notification: SyncCipherNotification, + isEdit: boolean, + userId: UserId, + ): Promise { this.syncStarted(); - if (await this.stateService.getIsAuthenticated()) { + + const authStatus = await firstValueFrom(this.authService.authStatusFor$(userId)); + if (authStatus >= AuthenticationStatus.Locked) { try { let shouldUpdate = true; - const localCipher = await this.cipherService.get(notification.id); + const localCipher = await this.cipherService.get(notification.id, userId); if (localCipher != null && localCipher.revisionDate >= notification.revisionDate) { shouldUpdate = false; } @@ -182,7 +188,7 @@ export abstract class CoreSyncService implements SyncService { } } catch (e) { if (e != null && e.statusCode === 404 && isEdit) { - await this.cipherService.delete(notification.id); + await this.cipherService.delete(notification.id, userId); this.messageSender.send("syncedDeletedCipher", { cipherId: notification.id }); return this.syncCompleted(true); } @@ -191,10 +197,12 @@ export abstract class CoreSyncService implements SyncService { return this.syncCompleted(false); } - async syncDeleteCipher(notification: SyncCipherNotification): Promise { + async syncDeleteCipher(notification: SyncCipherNotification, userId: UserId): Promise { this.syncStarted(); - if (await this.stateService.getIsAuthenticated()) { - await this.cipherService.delete(notification.id); + + const authStatus = await firstValueFrom(this.authService.authStatusFor$(userId)); + if (authStatus >= AuthenticationStatus.Locked) { + await this.cipherService.delete(notification.id, userId); this.messageSender.send("syncedDeletedCipher", { cipherId: notification.id }); return this.syncCompleted(true); } diff --git a/libs/common/src/platform/sync/default-sync.service.ts b/libs/common/src/platform/sync/default-sync.service.ts index 982be453457..b47f0c54208 100644 --- a/libs/common/src/platform/sync/default-sync.service.ts +++ b/libs/common/src/platform/sync/default-sync.service.ts @@ -7,6 +7,7 @@ import { CollectionData, CollectionDetailsResponse, } from "@bitwarden/admin-console/common"; +import { KeyService } from "@bitwarden/key-management"; // FIXME: remove `src` and fix import // eslint-disable-next-line no-restricted-imports @@ -14,9 +15,6 @@ import { UserDecryptionOptionsServiceAbstraction } from "../../../../auth/src/co // FIXME: remove `src` and fix import // eslint-disable-next-line no-restricted-imports import { LogoutReason } from "../../../../auth/src/common/types"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { KeyService } from "../../../../key-management/src/abstractions/key.service"; import { ApiService } from "../../abstractions/api.service"; import { InternalOrganizationServiceAbstraction } from "../../admin-console/abstractions/organization/organization.service.abstraction"; import { InternalPolicyService } from "../../admin-console/abstractions/policy/policy.service.abstraction"; diff --git a/libs/common/src/platform/sync/sync.service.ts b/libs/common/src/platform/sync/sync.service.ts index 6763e01cab7..967e4db27a5 100644 --- a/libs/common/src/platform/sync/sync.service.ts +++ b/libs/common/src/platform/sync/sync.service.ts @@ -62,8 +62,9 @@ export abstract class SyncService { abstract syncUpsertCipher( notification: SyncCipherNotification, isEdit: boolean, + userId: UserId, ): Promise; - abstract syncDeleteCipher(notification: SyncFolderNotification): Promise; + abstract syncDeleteCipher(notification: SyncFolderNotification, userId: UserId): Promise; abstract syncUpsertSend(notification: SyncSendNotification, isEdit: boolean): Promise; abstract syncDeleteSend(notification: SyncSendNotification): Promise; } diff --git a/libs/common/src/platform/theming/theme-state.service.ts b/libs/common/src/platform/theming/theme-state.service.ts index bb146be4927..df2c96c49d0 100644 --- a/libs/common/src/platform/theming/theme-state.service.ts +++ b/libs/common/src/platform/theming/theme-state.service.ts @@ -32,7 +32,11 @@ export class DefaultThemeStateService implements ThemeStateService { map(([theme, isExtensionRefresh]) => { // The extension refresh should not allow for Nord or SolarizedDark // Default the user to their system theme - if (isExtensionRefresh && [ThemeType.Nord, ThemeType.SolarizedDark].includes(theme)) { + if ( + isExtensionRefresh && + theme != null && + [ThemeType.Nord, ThemeType.SolarizedDark].includes(theme) + ) { return ThemeType.System; } diff --git a/libs/common/src/services/event/event-collection.service.ts b/libs/common/src/services/event/event-collection.service.ts index da38ca5bfff..b37ec0de271 100644 --- a/libs/common/src/services/event/event-collection.service.ts +++ b/libs/common/src/services/event/event-collection.service.ts @@ -6,6 +6,7 @@ import { OrganizationService } from "@bitwarden/common/admin-console/abstraction import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { getUserId } from "@bitwarden/common/auth/services/account.service"; +import { UserId } from "@bitwarden/common/types/guid"; import { EventCollectionService as EventCollectionServiceAbstraction } from "../../abstractions/event/event-collection.service"; import { EventUploadService } from "../../abstractions/event/event-upload.service"; @@ -46,7 +47,7 @@ export class EventCollectionService implements EventCollectionServiceAbstraction const userId = await firstValueFrom(getUserId(this.accountService.activeAccount$)); const eventStore = this.stateProvider.getUser(userId, EVENT_COLLECTION); - if (!(await this.shouldUpdate(null, eventType, ciphers))) { + if (!(await this.shouldUpdate(userId, null, eventType, ciphers))) { return; } @@ -91,7 +92,7 @@ export class EventCollectionService implements EventCollectionServiceAbstraction const userId = await firstValueFrom(getUserId(this.accountService.activeAccount$)); const eventStore = this.stateProvider.getUser(userId, EVENT_COLLECTION); - if (!(await this.shouldUpdate(organizationId, eventType, undefined, cipherId))) { + if (!(await this.shouldUpdate(userId, organizationId, eventType, undefined, cipherId))) { return; } @@ -113,18 +114,18 @@ export class EventCollectionService implements EventCollectionServiceAbstraction } /** Verifies if the event collection should be updated for the provided information + * @param userId the active user's id * @param cipherId the cipher for the event * @param organizationId the organization for the event */ private async shouldUpdate( + userId: UserId, organizationId: string = null, eventType: EventType = null, ciphers: CipherView[] = [], cipherId?: string, ): Promise { - const cipher$ = from(this.cipherService.get(cipherId)); - - const userId = await firstValueFrom(getUserId(this.accountService.activeAccount$)); + const cipher$ = from(this.cipherService.get(cipherId, userId)); const orgIds$ = this.organizationService .organizations$(userId) diff --git a/libs/common/src/services/vault-timeout/vault-timeout-settings.service.spec.ts b/libs/common/src/services/vault-timeout/vault-timeout-settings.service.spec.ts index 77ed6c960ab..78c0bc43331 100644 --- a/libs/common/src/services/vault-timeout/vault-timeout-settings.service.spec.ts +++ b/libs/common/src/services/vault-timeout/vault-timeout-settings.service.spec.ts @@ -6,11 +6,8 @@ import { FakeUserDecryptionOptions as UserDecryptionOptions, UserDecryptionOptionsServiceAbstraction, } from "@bitwarden/auth/common"; -import { BiometricStateService } from "@bitwarden/key-management"; +import { BiometricStateService, KeyService } from "@bitwarden/key-management"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { KeyService } from "../../../../key-management/src/abstractions/key.service"; import { FakeAccountService, mockAccountServiceWith, FakeStateProvider } from "../../../spec"; import { VaultTimeoutSettingsService as VaultTimeoutSettingsServiceAbstraction } from "../../abstractions/vault-timeout/vault-timeout-settings.service"; import { PolicyService } from "../../admin-console/abstractions/policy/policy.service.abstraction"; diff --git a/libs/common/src/services/vault-timeout/vault-timeout-settings.service.ts b/libs/common/src/services/vault-timeout/vault-timeout-settings.service.ts index ffc8b6e0144..813f187043b 100644 --- a/libs/common/src/services/vault-timeout/vault-timeout-settings.service.ts +++ b/libs/common/src/services/vault-timeout/vault-timeout-settings.service.ts @@ -19,11 +19,8 @@ import { PinServiceAbstraction, UserDecryptionOptionsServiceAbstraction, } from "@bitwarden/auth/common"; -import { BiometricStateService } from "@bitwarden/key-management"; +import { BiometricStateService, KeyService } from "@bitwarden/key-management"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { KeyService } from "../../../../key-management/src/abstractions/key.service"; import { VaultTimeoutSettingsService as VaultTimeoutSettingsServiceAbstraction } from "../../abstractions/vault-timeout/vault-timeout-settings.service"; import { PolicyService } from "../../admin-console/abstractions/policy/policy.service.abstraction"; import { PolicyType } from "../../admin-console/enums"; diff --git a/libs/common/src/state-migrations/migrate.ts b/libs/common/src/state-migrations/migrate.ts index 169de447f10..b409f52d936 100644 --- a/libs/common/src/state-migrations/migrate.ts +++ b/libs/common/src/state-migrations/migrate.ts @@ -68,12 +68,13 @@ import { RemoveUnassignedItemsBannerDismissed } from "./migrations/67-remove-una import { MoveLastSyncDate } from "./migrations/68-move-last-sync-date"; import { MigrateIncorrectFolderKey } from "./migrations/69-migrate-incorrect-folder-key"; import { MoveBiometricAutoPromptToAccount } from "./migrations/7-move-biometric-auto-prompt-to-account"; +import { RemoveAcBannersDismissed } from "./migrations/70-remove-ac-banner-dismissed"; import { MoveStateVersionMigrator } from "./migrations/8-move-state-version"; import { MoveBrowserSettingsToGlobal } from "./migrations/9-move-browser-settings-to-global"; import { MinVersionMigrator } from "./migrations/min-version"; export const MIN_VERSION = 3; -export const CURRENT_VERSION = 69; +export const CURRENT_VERSION = 70; export type MinVersion = typeof MIN_VERSION; export function createMigrationBuilder() { @@ -144,7 +145,8 @@ export function createMigrationBuilder() { .with(MoveFinalDesktopSettingsMigrator, 65, 66) .with(RemoveUnassignedItemsBannerDismissed, 66, 67) .with(MoveLastSyncDate, 67, 68) - .with(MigrateIncorrectFolderKey, 68, CURRENT_VERSION); + .with(MigrateIncorrectFolderKey, 68, 69) + .with(RemoveAcBannersDismissed, 69, CURRENT_VERSION); } export async function currentVersion( diff --git a/libs/common/src/state-migrations/migrations/70-remove-ac-banner-dismissed.spec.ts b/libs/common/src/state-migrations/migrations/70-remove-ac-banner-dismissed.spec.ts new file mode 100644 index 00000000000..59f39d195e9 --- /dev/null +++ b/libs/common/src/state-migrations/migrations/70-remove-ac-banner-dismissed.spec.ts @@ -0,0 +1,50 @@ +import { runMigrator } from "../migration-helper.spec"; +import { IRREVERSIBLE } from "../migrator"; + +import { RemoveAcBannersDismissed } from "./70-remove-ac-banner-dismissed"; + +describe("RemoveAcBannersDismissed", () => { + const sut = new RemoveAcBannersDismissed(69, 70); + + describe("migrate", () => { + it("deletes ac banner from all users", async () => { + const output = await runMigrator(sut, { + global_account_accounts: { + user1: { + email: "user1@email.com", + name: "User 1", + emailVerified: true, + }, + user2: { + email: "user2@email.com", + name: "User 2", + emailVerified: true, + }, + }, + user_user1_showProviderClientVaultPrivacyBanner_acBannersDismissed: true, + user_user2_showProviderClientVaultPrivacyBanner_acBannersDismissed: true, + }); + + expect(output).toEqual({ + global_account_accounts: { + user1: { + email: "user1@email.com", + name: "User 1", + emailVerified: true, + }, + user2: { + email: "user2@email.com", + name: "User 2", + emailVerified: true, + }, + }, + }); + }); + }); + + describe("rollback", () => { + it("is irreversible", async () => { + await expect(runMigrator(sut, {}, "rollback")).rejects.toThrow(IRREVERSIBLE); + }); + }); +}); diff --git a/libs/common/src/state-migrations/migrations/70-remove-ac-banner-dismissed.ts b/libs/common/src/state-migrations/migrations/70-remove-ac-banner-dismissed.ts new file mode 100644 index 00000000000..087994b508f --- /dev/null +++ b/libs/common/src/state-migrations/migrations/70-remove-ac-banner-dismissed.ts @@ -0,0 +1,23 @@ +import { KeyDefinitionLike, MigrationHelper } from "../migration-helper"; +import { IRREVERSIBLE, Migrator } from "../migrator"; + +export const SHOW_BANNER_KEY: KeyDefinitionLike = { + key: "acBannersDismissed", + stateDefinition: { name: "showProviderClientVaultPrivacyBanner" }, +}; + +export class RemoveAcBannersDismissed extends Migrator<69, 70> { + async migrate(helper: MigrationHelper): Promise { + await Promise.all( + (await helper.getAccounts()).map(async ({ userId }) => { + if (helper.getFromUser(userId, SHOW_BANNER_KEY) != null) { + await helper.removeFromUser(userId, SHOW_BANNER_KEY); + } + }), + ); + } + + async rollback(helper: MigrationHelper): Promise { + throw IRREVERSIBLE; + } +} diff --git a/libs/common/src/tools/cryptography/key-service-legacy-encryptor-provider.spec.ts b/libs/common/src/tools/cryptography/key-service-legacy-encryptor-provider.spec.ts index 0b60aef4917..66edc5a4838 100644 --- a/libs/common/src/tools/cryptography/key-service-legacy-encryptor-provider.spec.ts +++ b/libs/common/src/tools/cryptography/key-service-legacy-encryptor-provider.spec.ts @@ -3,7 +3,7 @@ import { BehaviorSubject, Subject } from "rxjs"; import { KeyService } from "@bitwarden/key-management"; -import { EncryptService } from "../../platform/abstractions/encrypt.service"; +import { EncryptService } from "../../key-management/crypto/abstractions/encrypt.service"; import { SymmetricCryptoKey } from "../../platform/models/domain/symmetric-crypto-key"; import { CsprngArray } from "../../types/csprng"; import { OrganizationId, UserId } from "../../types/guid"; diff --git a/libs/common/src/tools/cryptography/key-service-legacy-encryptor-provider.ts b/libs/common/src/tools/cryptography/key-service-legacy-encryptor-provider.ts index d4a8dec7dc3..c91181a004a 100644 --- a/libs/common/src/tools/cryptography/key-service-legacy-encryptor-provider.ts +++ b/libs/common/src/tools/cryptography/key-service-legacy-encryptor-provider.ts @@ -14,7 +14,7 @@ import { import { KeyService } from "@bitwarden/key-management"; -import { EncryptService } from "../../platform/abstractions/encrypt.service"; +import { EncryptService } from "../../key-management/crypto/abstractions/encrypt.service"; import { OrganizationId, UserId } from "../../types/guid"; import { OrganizationBound, diff --git a/libs/common/src/tools/cryptography/organization-key-encryptor.spec.ts b/libs/common/src/tools/cryptography/organization-key-encryptor.spec.ts index 62c8ea24ae6..3d93db81389 100644 --- a/libs/common/src/tools/cryptography/organization-key-encryptor.spec.ts +++ b/libs/common/src/tools/cryptography/organization-key-encryptor.spec.ts @@ -1,6 +1,6 @@ import { mock } from "jest-mock-extended"; -import { EncryptService } from "../../platform/abstractions/encrypt.service"; +import { EncryptService } from "../../key-management/crypto/abstractions/encrypt.service"; import { EncString } from "../../platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "../../platform/models/domain/symmetric-crypto-key"; import { CsprngArray } from "../../types/csprng"; diff --git a/libs/common/src/tools/cryptography/organization-key-encryptor.ts b/libs/common/src/tools/cryptography/organization-key-encryptor.ts index d3b7dae10f5..31f3db91232 100644 --- a/libs/common/src/tools/cryptography/organization-key-encryptor.ts +++ b/libs/common/src/tools/cryptography/organization-key-encryptor.ts @@ -2,7 +2,7 @@ // @ts-strict-ignore import { Jsonify } from "type-fest"; -import { EncryptService } from "../../platform/abstractions/encrypt.service"; +import { EncryptService } from "../../key-management/crypto/abstractions/encrypt.service"; import { EncString } from "../../platform/models/domain/enc-string"; import { OrganizationId } from "../../types/guid"; import { OrgKey } from "../../types/key"; diff --git a/libs/common/src/tools/cryptography/user-key-encryptor.spec.ts b/libs/common/src/tools/cryptography/user-key-encryptor.spec.ts index 5b0ee5103cb..e52190500b0 100644 --- a/libs/common/src/tools/cryptography/user-key-encryptor.spec.ts +++ b/libs/common/src/tools/cryptography/user-key-encryptor.spec.ts @@ -1,6 +1,6 @@ import { mock } from "jest-mock-extended"; -import { EncryptService } from "../../platform/abstractions/encrypt.service"; +import { EncryptService } from "../../key-management/crypto/abstractions/encrypt.service"; import { EncString } from "../../platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "../../platform/models/domain/symmetric-crypto-key"; import { CsprngArray } from "../../types/csprng"; diff --git a/libs/common/src/tools/cryptography/user-key-encryptor.ts b/libs/common/src/tools/cryptography/user-key-encryptor.ts index 296c33ea1dc..4b7cd1516a0 100644 --- a/libs/common/src/tools/cryptography/user-key-encryptor.ts +++ b/libs/common/src/tools/cryptography/user-key-encryptor.ts @@ -2,7 +2,7 @@ // @ts-strict-ignore import { Jsonify } from "type-fest"; -import { EncryptService } from "../../platform/abstractions/encrypt.service"; +import { EncryptService } from "../../key-management/crypto/abstractions/encrypt.service"; import { EncString } from "../../platform/models/domain/enc-string"; import { UserId } from "../../types/guid"; import { UserKey } from "../../types/key"; diff --git a/libs/common/src/tools/log/default-semantic-logger.spec.ts b/libs/common/src/tools/log/default-semantic-logger.spec.ts new file mode 100644 index 00000000000..8d1dadb66af --- /dev/null +++ b/libs/common/src/tools/log/default-semantic-logger.spec.ts @@ -0,0 +1,199 @@ +import { mock } from "jest-mock-extended"; + +import { LogService } from "../../platform/abstractions/log.service"; +import { LogLevelType } from "../../platform/enums"; + +import { DefaultSemanticLogger } from "./default-semantic-logger"; + +const logger = mock(); + +describe("DefaultSemanticLogger", () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe("debug", () => { + it("writes structural log messages to console.log", () => { + const log = new DefaultSemanticLogger(logger, {}); + + log.debug("this is a debug message"); + + expect(logger.write).toHaveBeenCalledWith(LogLevelType.Debug, { + message: "this is a debug message", + level: LogLevelType.Debug, + }); + }); + + it("writes structural content to console.log", () => { + const log = new DefaultSemanticLogger(logger, {}); + + log.debug({ example: "this is content" }); + + expect(logger.write).toHaveBeenCalledWith(LogLevelType.Debug, { + content: { example: "this is content" }, + level: LogLevelType.Debug, + }); + }); + + it("writes structural content to console.log with a message", () => { + const log = new DefaultSemanticLogger(logger, {}); + + log.info({ example: "this is content" }, "this is a message"); + + expect(logger.write).toHaveBeenCalledWith(LogLevelType.Info, { + content: { example: "this is content" }, + message: "this is a message", + level: LogLevelType.Info, + }); + }); + }); + + describe("info", () => { + it("writes structural log messages to console.log", () => { + const log = new DefaultSemanticLogger(logger, {}); + + log.info("this is an info message"); + + expect(logger.write).toHaveBeenCalledWith(LogLevelType.Info, { + message: "this is an info message", + level: LogLevelType.Info, + }); + }); + + it("writes structural content to console.log", () => { + const log = new DefaultSemanticLogger(logger, {}); + + log.info({ example: "this is content" }); + + expect(logger.write).toHaveBeenCalledWith(LogLevelType.Info, { + content: { example: "this is content" }, + level: LogLevelType.Info, + }); + }); + + it("writes structural content to console.log with a message", () => { + const log = new DefaultSemanticLogger(logger, {}); + + log.info({ example: "this is content" }, "this is a message"); + + expect(logger.write).toHaveBeenCalledWith(LogLevelType.Info, { + content: { example: "this is content" }, + message: "this is a message", + level: LogLevelType.Info, + }); + }); + }); + + describe("warn", () => { + it("writes structural log messages to console.warn", () => { + const log = new DefaultSemanticLogger(logger, {}); + + log.warn("this is a warning message"); + + expect(logger.write).toHaveBeenCalledWith(LogLevelType.Warning, { + message: "this is a warning message", + level: LogLevelType.Warning, + }); + }); + + it("writes structural content to console.warn", () => { + const log = new DefaultSemanticLogger(logger, {}); + + log.warn({ example: "this is content" }); + + expect(logger.write).toHaveBeenCalledWith(LogLevelType.Warning, { + content: { example: "this is content" }, + level: LogLevelType.Warning, + }); + }); + + it("writes structural content to console.warn with a message", () => { + const log = new DefaultSemanticLogger(logger, {}); + + log.warn({ example: "this is content" }, "this is a message"); + + expect(logger.write).toHaveBeenCalledWith(LogLevelType.Warning, { + content: { example: "this is content" }, + message: "this is a message", + level: LogLevelType.Warning, + }); + }); + }); + + describe("error", () => { + it("writes structural log messages to console.error", () => { + const log = new DefaultSemanticLogger(logger, {}); + + log.error("this is an error message"); + + expect(logger.write).toHaveBeenCalledWith(LogLevelType.Error, { + message: "this is an error message", + level: LogLevelType.Error, + }); + }); + + it("writes structural content to console.error", () => { + const log = new DefaultSemanticLogger(logger, {}); + + log.error({ example: "this is content" }); + + expect(logger.write).toHaveBeenCalledWith(LogLevelType.Error, { + content: { example: "this is content" }, + level: LogLevelType.Error, + }); + }); + + it("writes structural content to console.error with a message", () => { + const log = new DefaultSemanticLogger(logger, {}); + + log.error({ example: "this is content" }, "this is a message"); + + expect(logger.write).toHaveBeenCalledWith(LogLevelType.Error, { + content: { example: "this is content" }, + message: "this is a message", + level: LogLevelType.Error, + }); + }); + }); + + describe("panic", () => { + it("writes structural log messages to console.error before throwing the message", () => { + const log = new DefaultSemanticLogger(logger, {}); + + expect(() => log.panic("this is an error message")).toThrow("this is an error message"); + + expect(logger.write).toHaveBeenCalledWith(LogLevelType.Error, { + message: "this is an error message", + level: LogLevelType.Error, + }); + }); + + it("writes structural log messages to console.error with a message before throwing the message", () => { + const log = new DefaultSemanticLogger(logger, {}); + + expect(() => log.panic({ example: "this is content" }, "this is an error message")).toThrow( + "this is an error message", + ); + + expect(logger.write).toHaveBeenCalledWith(LogLevelType.Error, { + content: { example: "this is content" }, + message: "this is an error message", + level: LogLevelType.Error, + }); + }); + + it("writes structural log messages to console.error with a content before throwing the message", () => { + const log = new DefaultSemanticLogger(logger, {}); + + expect(() => log.panic("this is content", "this is an error message")).toThrow( + "this is an error message", + ); + + expect(logger.write).toHaveBeenCalledWith(LogLevelType.Error, { + content: "this is content", + message: "this is an error message", + level: LogLevelType.Error, + }); + }); + }); +}); diff --git a/libs/common/src/tools/log/default-semantic-logger.ts b/libs/common/src/tools/log/default-semantic-logger.ts new file mode 100644 index 00000000000..1bd62baf126 --- /dev/null +++ b/libs/common/src/tools/log/default-semantic-logger.ts @@ -0,0 +1,65 @@ +import { Jsonify } from "type-fest"; + +import { LogService } from "../../platform/abstractions/log.service"; +import { LogLevelType } from "../../platform/enums"; + +import { SemanticLogger } from "./semantic-logger.abstraction"; + +/** Sends semantic logs to the console. + * @remarks the behavior of this logger is based on `LogService`; it + * replaces dynamic messages (`%s`) with a JSON-formatted semantic log. + */ +export class DefaultSemanticLogger implements SemanticLogger { + /** Instantiates a console semantic logger + * @param context a static payload that is cloned when the logger + * logs a message. The `messages`, `level`, and `content` fields + * are reserved for use by loggers. + */ + constructor( + private logger: LogService, + context: Jsonify, + ) { + this.context = context && typeof context === "object" ? context : {}; + } + + readonly context: object; + + debug(content: Jsonify, message?: string): void { + this.log(content, LogLevelType.Debug, message); + } + + info(content: Jsonify, message?: string): void { + this.log(content, LogLevelType.Info, message); + } + + warn(content: Jsonify, message?: string): void { + this.log(content, LogLevelType.Warning, message); + } + + error(content: Jsonify, message?: string): void { + this.log(content, LogLevelType.Error, message); + } + + panic(content: Jsonify, message?: string): never { + this.log(content, LogLevelType.Error, message); + const panicMessage = + message ?? (typeof content === "string" ? content : "a fatal error occurred"); + throw new Error(panicMessage); + } + + private log(content: Jsonify, level: LogLevelType, message?: string) { + const log = { + ...this.context, + message, + content: content ?? undefined, + level, + }; + + if (typeof content === "string" && !message) { + log.message = content; + delete log.content; + } + + this.logger.write(level, log); + } +} diff --git a/libs/common/src/tools/log/disabled-semantic-logger.ts b/libs/common/src/tools/log/disabled-semantic-logger.ts new file mode 100644 index 00000000000..054c3ed390b --- /dev/null +++ b/libs/common/src/tools/log/disabled-semantic-logger.ts @@ -0,0 +1,18 @@ +import { Jsonify } from "type-fest"; + +import { SemanticLogger } from "./semantic-logger.abstraction"; + +/** Disables semantic logs. Still panics. */ +export class DisabledSemanticLogger implements SemanticLogger { + debug(_content: Jsonify, _message?: string): void {} + + info(_content: Jsonify, _message?: string): void {} + + warn(_content: Jsonify, _message?: string): void {} + + error(_content: Jsonify, _message?: string): void {} + + panic(_content: Jsonify, message?: string): never { + throw new Error(message); + } +} diff --git a/libs/common/src/tools/log/factory.ts b/libs/common/src/tools/log/factory.ts new file mode 100644 index 00000000000..d887c4e310a --- /dev/null +++ b/libs/common/src/tools/log/factory.ts @@ -0,0 +1,30 @@ +import { Jsonify } from "type-fest"; + +import { LogService } from "../../platform/abstractions/log.service"; + +import { DefaultSemanticLogger } from "./default-semantic-logger"; +import { DisabledSemanticLogger } from "./disabled-semantic-logger"; +import { SemanticLogger } from "./semantic-logger.abstraction"; + +/** Instantiates a semantic logger that emits nothing when a message + * is logged. + * @param _context a static payload that is cloned when the logger + * logs a message. The `messages`, `level`, and `content` fields + * are reserved for use by loggers. + */ +export function disabledSemanticLoggerProvider( + _context: Jsonify, +): SemanticLogger { + return new DisabledSemanticLogger(); +} + +/** Instantiates a semantic logger that emits logs to the console. + * @param context a static payload that is cloned when the logger + * logs a message. The `messages`, `level`, and `content` fields + * are reserved for use by loggers. + * @param settings specializes how the semantic logger functions. + * If this is omitted, the logger suppresses debug messages. + */ +export function consoleSemanticLoggerProvider(logger: LogService): SemanticLogger { + return new DefaultSemanticLogger(logger, {}); +} diff --git a/libs/common/src/tools/log/index.ts b/libs/common/src/tools/log/index.ts new file mode 100644 index 00000000000..1f86ca4e4d7 --- /dev/null +++ b/libs/common/src/tools/log/index.ts @@ -0,0 +1,2 @@ +export { disabledSemanticLoggerProvider, consoleSemanticLoggerProvider } from "./factory"; +export { SemanticLogger } from "./semantic-logger.abstraction"; diff --git a/libs/common/src/tools/log/semantic-logger.abstraction.ts b/libs/common/src/tools/log/semantic-logger.abstraction.ts new file mode 100644 index 00000000000..196d1f3f12c --- /dev/null +++ b/libs/common/src/tools/log/semantic-logger.abstraction.ts @@ -0,0 +1,94 @@ +import { Jsonify } from "type-fest"; + +/** Semantic/structural logging component */ +export interface SemanticLogger { + /** Logs a message at debug priority. + * Debug messages are used for diagnostics, and are typically disabled + * in production builds. + * @param message - a message to record in the log's `message` field. + */ + debug(message: string): void; + + /** Logs the content at debug priority. + * Debug messages are used for diagnostics, and are typically disabled + * in production builds. + * @param content - JSON content included in the log's `content` field. + * @param message - a message to record in the log's `message` field. + */ + debug(content: Jsonify, message?: string): void; + + /** combined signature for overloaded methods */ + debug(content: Jsonify | string, message?: string): void; + + /** Logs a message at informational priority. + * Information messages are used for status reports. + * @param message - a message to record in the log's `message` field. + */ + info(message: string): void; + + /** Logs the content at informational priority. + * Information messages are used for status reports. + * @param content - JSON content included in the log's `content` field. + * @param message - a message to record in the log's `message` field. + */ + info(content: Jsonify, message?: string): void; + + /** combined signature for overloaded methods */ + info(content: Jsonify | string, message?: string): void; + + /** Logs a message at warn priority. + * Warn messages are used to indicate a operation that may affect system + * stability occurred. + * @param message - a message to record in the log's `message` field. + */ + warn(message: string): void; + + /** Logs the content at warn priority. + * Warn messages are used to indicate a operation that may affect system + * stability occurred. + * @param content - JSON content included in the log's `content` field. + * @param message - a message to record in the log's `message` field. + */ + warn(content: Jsonify, message?: string): void; + + /** combined signature for overloaded methods */ + warn(content: Jsonify | string, message?: string): void; + + /** Logs a message at error priority. + * Error messages are used to indicate a operation that affects system + * stability occurred and the system was able to recover. + * @param message - a message to record in the log's `message` field. + */ + error(message: string): void; + + /** Logs the content at debug priority. + * Error messages are used to indicate a operation that affects system + * stability occurred and the system was able to recover. + * @param content - JSON content included in the log's `content` field. + * @param message - a message to record in the log's `message` field. + */ + error(content: Jsonify, message?: string): void; + + /** combined signature for overloaded methods */ + error(content: Jsonify | string, message?: string): void; + + /** Logs a message at panic priority and throws an error. + * Panic messages are used to indicate a operation that affects system + * stability occurred and the system cannot recover. Panic messages + * log an error and throw an `Error`. + * @param message - a message to record in the log's `message` field. + */ + panic(message: string): never; + + /** Logs the content at debug priority and throws an error. + * Panic messages are used to indicate a operation that affects system + * stability occurred and the system cannot recover. Panic messages + * log an error and throw an `Error`. + * @param content - JSON content included in the log's `content` field. + * @param message - a message to record in the log's `message` field. + */ + panic(content: Jsonify, message?: string): never; + + /** combined signature for overloaded methods */ + panic(content: Jsonify | string, message?: string): never; +} diff --git a/libs/common/src/tools/send/models/domain/send.spec.ts b/libs/common/src/tools/send/models/domain/send.spec.ts index fcc273d41bb..79f6c03adc8 100644 --- a/libs/common/src/tools/send/models/domain/send.spec.ts +++ b/libs/common/src/tools/send/models/domain/send.spec.ts @@ -3,7 +3,7 @@ import { mock } from "jest-mock-extended"; import { KeyService } from "@bitwarden/key-management"; import { makeStaticByteArray, mockEnc } from "../../../../../spec"; -import { EncryptService } from "../../../../platform/abstractions/encrypt.service"; +import { EncryptService } from "../../../../key-management/crypto/abstractions/encrypt.service"; import { SymmetricCryptoKey } from "../../../../platform/models/domain/symmetric-crypto-key"; import { ContainerService } from "../../../../platform/services/container.service"; import { UserKey } from "../../../../types/key"; diff --git a/libs/common/src/tools/send/services/send.service.spec.ts b/libs/common/src/tools/send/services/send.service.spec.ts index 662fee02bbf..26cc0a46708 100644 --- a/libs/common/src/tools/send/services/send.service.spec.ts +++ b/libs/common/src/tools/send/services/send.service.spec.ts @@ -10,7 +10,7 @@ import { awaitAsync, mockAccountServiceWith, } from "../../../../spec"; -import { EncryptService } from "../../../platform/abstractions/encrypt.service"; +import { EncryptService } from "../../../key-management/crypto/abstractions/encrypt.service"; import { EnvironmentService } from "../../../platform/abstractions/environment.service"; import { I18nService } from "../../../platform/abstractions/i18n.service"; import { KeyGenerationService } from "../../../platform/abstractions/key-generation.service"; diff --git a/libs/common/src/tools/send/services/send.service.ts b/libs/common/src/tools/send/services/send.service.ts index 7021c942d44..1b5e5f6aa31 100644 --- a/libs/common/src/tools/send/services/send.service.ts +++ b/libs/common/src/tools/send/services/send.service.ts @@ -4,7 +4,7 @@ import { Observable, concatMap, distinctUntilChanged, firstValueFrom, map } from import { PBKDF2KdfConfig, KeyService } from "@bitwarden/key-management"; -import { EncryptService } from "../../../platform/abstractions/encrypt.service"; +import { EncryptService } from "../../../key-management/crypto/abstractions/encrypt.service"; import { I18nService } from "../../../platform/abstractions/i18n.service"; import { KeyGenerationService } from "../../../platform/abstractions/key-generation.service"; import { Utils } from "../../../platform/misc/utils"; diff --git a/libs/common/src/vault/abstractions/cipher.service.ts b/libs/common/src/vault/abstractions/cipher.service.ts index 0672ae29e91..1e4275ff89b 100644 --- a/libs/common/src/vault/abstractions/cipher.service.ts +++ b/libs/common/src/vault/abstractions/cipher.service.ts @@ -19,57 +19,70 @@ import { FieldView } from "../models/view/field.view"; import { AddEditCipherInfo } from "../types/add-edit-cipher-info"; export abstract class CipherService implements UserKeyRotationDataProvider { - cipherViews$: Observable; - ciphers$: Observable>; - localData$: Observable>; + abstract cipherViews$(userId: UserId): Observable; + abstract ciphers$(userId: UserId): Observable>; + abstract localData$(userId: UserId): Observable>; /** * An observable monitoring the add/edit cipher info saved to memory. */ - addEditCipherInfo$: Observable; + abstract addEditCipherInfo$(userId: UserId): Observable; /** * Observable that emits an array of cipherViews that failed to decrypt. Does not emit until decryption has completed. * * An empty array indicates that all ciphers were successfully decrypted. */ - failedToDecryptCiphers$: Observable; - clearCache: (userId?: string) => Promise; - encrypt: ( + abstract failedToDecryptCiphers$(userId: UserId): Observable; + abstract clearCache(userId: UserId): Promise; + abstract encrypt( model: CipherView, userId: UserId, keyForEncryption?: SymmetricCryptoKey, keyForCipherKeyDecryption?: SymmetricCryptoKey, originalCipher?: Cipher, - ) => Promise; - encryptFields: (fieldsModel: FieldView[], key: SymmetricCryptoKey) => Promise; - encryptField: (fieldModel: FieldView, key: SymmetricCryptoKey) => Promise; - get: (id: string) => Promise; - getAll: () => Promise; - getAllDecrypted: () => Promise; - getAllDecryptedForGrouping: (groupingId: string, folder?: boolean) => Promise; - getAllDecryptedForUrl: ( + ): Promise; + abstract encryptFields(fieldsModel: FieldView[], key: SymmetricCryptoKey): Promise; + abstract encryptField(fieldModel: FieldView, key: SymmetricCryptoKey): Promise; + abstract get(id: string, userId: UserId): Promise; + abstract getAll(userId: UserId): Promise; + abstract getAllDecrypted(userId: UserId): Promise; + abstract getAllDecryptedForGrouping( + groupingId: string, + userId: UserId, + folder?: boolean, + ): Promise; + abstract getAllDecryptedForUrl( url: string, + userId: UserId, includeOtherTypes?: CipherType[], defaultMatch?: UriMatchStrategySetting, - ) => Promise; - filterCiphersForUrl: ( + ): Promise; + abstract filterCiphersForUrl( ciphers: CipherView[], url: string, includeOtherTypes?: CipherType[], defaultMatch?: UriMatchStrategySetting, - ) => Promise; - getAllFromApiForOrganization: (organizationId: string) => Promise; + ): Promise; + abstract getAllFromApiForOrganization(organizationId: string): Promise; /** * Gets ciphers belonging to the specified organization that the user has explicit collection level access to. * Ciphers that are not assigned to any collections are only included for users with admin access. */ - getManyFromApiForOrganization: (organizationId: string) => Promise; - getLastUsedForUrl: (url: string, autofillOnPageLoad: boolean) => Promise; - getLastLaunchedForUrl: (url: string, autofillOnPageLoad: boolean) => Promise; - getNextCipherForUrl: (url: string) => Promise; - updateLastUsedIndexForUrl: (url: string) => void; - updateLastUsedDate: (id: string) => Promise; - updateLastLaunchedDate: (id: string) => Promise; - saveNeverDomain: (domain: string) => Promise; + abstract getManyFromApiForOrganization(organizationId: string): Promise; + abstract getLastUsedForUrl( + url: string, + userId: UserId, + autofillOnPageLoad: boolean, + ): Promise; + abstract getLastLaunchedForUrl( + url: string, + userId: UserId, + autofillOnPageLoad: boolean, + ): Promise; + abstract getNextCipherForUrl(url: string, userId: UserId): Promise; + abstract updateLastUsedIndexForUrl(url: string): void; + abstract updateLastUsedDate(id: string, userId: UserId): Promise; + abstract updateLastLaunchedDate(id: string, userId: UserId): Promise; + abstract saveNeverDomain(domain: string): Promise; /** * Create a cipher with the server * @@ -78,7 +91,7 @@ export abstract class CipherService implements UserKeyRotationDataProvider Promise; + abstract createWithServer(cipher: Cipher, orgAdmin?: boolean): Promise; /** * Update a cipher with the server * @param cipher The cipher to update @@ -87,88 +100,105 @@ export abstract class CipherService implements UserKeyRotationDataProvider Promise; - shareWithServer: ( + abstract updateWithServer( + cipher: Cipher, + orgAdmin?: boolean, + isNotClone?: boolean, + ): Promise; + abstract shareWithServer( cipher: CipherView, organizationId: string, collectionIds: string[], userId: UserId, - ) => Promise; - shareManyWithServer: ( + ): Promise; + abstract shareManyWithServer( ciphers: CipherView[], organizationId: string, collectionIds: string[], userId: UserId, - ) => Promise; - saveAttachmentWithServer: ( + ): Promise; + abstract saveAttachmentWithServer( cipher: Cipher, unencryptedFile: any, userId: UserId, admin?: boolean, - ) => Promise; - saveAttachmentRawWithServer: ( + ): Promise; + abstract saveAttachmentRawWithServer( cipher: Cipher, filename: string, data: ArrayBuffer, userId: UserId, admin?: boolean, - ) => Promise; + ): Promise; /** * Save the collections for a cipher with the server * * @param cipher The cipher to save collections for + * @param userId The user ID * * @returns A promise that resolves when the collections have been saved */ - saveCollectionsWithServer: (cipher: Cipher) => Promise; + abstract saveCollectionsWithServer(cipher: Cipher, userId: UserId): Promise; /** * Save the collections for a cipher with the server as an admin. * Used for Unassigned ciphers or when the user only has admin access to the cipher (not assigned normally). * @param cipher */ - saveCollectionsWithServerAdmin: (cipher: Cipher) => Promise; + abstract saveCollectionsWithServerAdmin(cipher: Cipher): Promise; /** * Bulk update collections for many ciphers with the server * @param orgId + * @param userId * @param cipherIds * @param collectionIds * @param removeCollections - If true, the collections will be removed from the ciphers, otherwise they will be added */ - bulkUpdateCollectionsWithServer: ( + abstract bulkUpdateCollectionsWithServer( orgId: OrganizationId, + userId: UserId, cipherIds: CipherId[], collectionIds: CollectionId[], removeCollections: boolean, - ) => Promise; + ): Promise; /** * Update the local store of CipherData with the provided data. Values are upserted into the existing store. * * @param cipher The cipher data to upsert. Can be a single CipherData object or an array of CipherData objects. * @returns A promise that resolves to a record of updated cipher store, keyed by their cipher ID. Returns all ciphers, not just those updated */ - upsert: (cipher: CipherData | CipherData[]) => Promise>; - replace: (ciphers: { [id: string]: CipherData }, userId: UserId) => Promise; - clear: (userId?: string) => Promise; - moveManyWithServer: (ids: string[], folderId: string) => Promise; - delete: (id: string | string[]) => Promise; - deleteWithServer: (id: string, asAdmin?: boolean) => Promise; - deleteManyWithServer: (ids: string[], asAdmin?: boolean) => Promise; - deleteAttachment: (id: string, revisionDate: string, attachmentId: string) => Promise; - deleteAttachmentWithServer: (id: string, attachmentId: string) => Promise; - sortCiphersByLastUsed: (a: CipherView, b: CipherView) => number; - sortCiphersByLastUsedThenName: (a: CipherView, b: CipherView) => number; - getLocaleSortingFunction: () => (a: CipherView, b: CipherView) => number; - softDelete: (id: string | string[]) => Promise; - softDeleteWithServer: (id: string, asAdmin?: boolean) => Promise; - softDeleteManyWithServer: (ids: string[], asAdmin?: boolean) => Promise; - restore: ( + abstract upsert(cipher: CipherData | CipherData[]): Promise>; + abstract replace(ciphers: { [id: string]: CipherData }, userId: UserId): Promise; + abstract clear(userId?: string): Promise; + abstract moveManyWithServer(ids: string[], folderId: string, userId: UserId): Promise; + abstract delete(id: string | string[], userId: UserId): Promise; + abstract deleteWithServer(id: string, userId: UserId, asAdmin?: boolean): Promise; + abstract deleteManyWithServer(ids: string[], userId: UserId, asAdmin?: boolean): Promise; + abstract deleteAttachment( + id: string, + revisionDate: string, + attachmentId: string, + userId: UserId, + ): Promise; + abstract deleteAttachmentWithServer( + id: string, + attachmentId: string, + userId: UserId, + ): Promise; + abstract sortCiphersByLastUsed(a: CipherView, b: CipherView): number; + abstract sortCiphersByLastUsedThenName(a: CipherView, b: CipherView): number; + abstract getLocaleSortingFunction(): (a: CipherView, b: CipherView) => number; + abstract softDelete(id: string | string[], userId: UserId): Promise; + abstract softDeleteWithServer(id: string, userId: UserId, asAdmin?: boolean): Promise; + abstract softDeleteManyWithServer(ids: string[], userId: UserId, asAdmin?: boolean): Promise; + abstract restore( cipher: { id: string; revisionDate: string } | { id: string; revisionDate: string }[], - ) => Promise; - restoreWithServer: (id: string, asAdmin?: boolean) => Promise; - restoreManyWithServer: (ids: string[], orgId?: string) => Promise; - getKeyForCipherKeyDecryption: (cipher: Cipher, userId: UserId) => Promise; - setAddEditCipherInfo: (value: AddEditCipherInfo) => Promise; + userId: UserId, + ): Promise; + abstract restoreWithServer(id: string, userId: UserId, asAdmin?: boolean): Promise; + abstract restoreManyWithServer(ids: string[], orgId?: string): Promise; + abstract getKeyForCipherKeyDecryption(cipher: Cipher, userId: UserId): Promise; + abstract setAddEditCipherInfo(value: AddEditCipherInfo, userId: UserId): Promise; /** * Returns user ciphers re-encrypted with the new user key. * @param originalUserKey the original user key @@ -177,11 +207,11 @@ export abstract class CipherService implements UserKeyRotationDataProvider Promise; - getNextCardCipher: () => Promise; - getNextIdentityCipher: () => Promise; + ): Promise; + abstract getNextCardCipher(userId: UserId): Promise; + abstract getNextIdentityCipher(userId: UserId): Promise; } diff --git a/libs/common/src/vault/models/domain/attachment.spec.ts b/libs/common/src/vault/models/domain/attachment.spec.ts index 8cae7170738..d1ee1dcc1ef 100644 --- a/libs/common/src/vault/models/domain/attachment.spec.ts +++ b/libs/common/src/vault/models/domain/attachment.spec.ts @@ -1,10 +1,9 @@ import { mock, MockProxy } from "jest-mock-extended"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { KeyService } from "../../../../../key-management/src/abstractions/key.service"; +import { KeyService } from "@bitwarden/key-management"; + import { makeStaticByteArray, mockEnc, mockFromJson } from "../../../../spec"; -import { EncryptService } from "../../../platform/abstractions/encrypt.service"; +import { EncryptService } from "../../../key-management/crypto/abstractions/encrypt.service"; import { EncryptedString, EncString } from "../../../platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-crypto-key"; import { ContainerService } from "../../../platform/services/container.service"; diff --git a/libs/common/src/vault/models/domain/cipher.spec.ts b/libs/common/src/vault/models/domain/cipher.spec.ts index dd79da3086e..9eadd20f543 100644 --- a/libs/common/src/vault/models/domain/cipher.spec.ts +++ b/libs/common/src/vault/models/domain/cipher.spec.ts @@ -1,12 +1,11 @@ import { mock } from "jest-mock-extended"; import { Jsonify } from "type-fest"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { KeyService } from "../../../../../key-management/src/abstractions/key.service"; +import { KeyService } from "@bitwarden/key-management"; + import { makeStaticByteArray, mockEnc, mockFromJson } from "../../../../spec/utils"; +import { EncryptService } from "../../../key-management/crypto/abstractions/encrypt.service"; import { UriMatchStrategy } from "../../../models/domain/domain-service"; -import { EncryptService } from "../../../platform/abstractions/encrypt.service"; import { EncString } from "../../../platform/models/domain/enc-string"; import { ContainerService } from "../../../platform/services/container.service"; import { InitializerKey } from "../../../platform/services/cryptography/initializer-key"; diff --git a/libs/common/src/vault/models/domain/folder.spec.ts b/libs/common/src/vault/models/domain/folder.spec.ts index 785852b884e..ff1c38bdd45 100644 --- a/libs/common/src/vault/models/domain/folder.spec.ts +++ b/libs/common/src/vault/models/domain/folder.spec.ts @@ -1,7 +1,7 @@ import { mock, MockProxy } from "jest-mock-extended"; import { makeEncString, makeSymmetricCryptoKey, mockEnc, mockFromJson } from "../../../../spec"; -import { EncryptService } from "../../../platform/abstractions/encrypt.service"; +import { EncryptService } from "../../../key-management/crypto/abstractions/encrypt.service"; import { EncryptedString, EncString } from "../../../platform/models/domain/enc-string"; import { FolderData } from "../../models/data/folder.data"; import { Folder } from "../../models/domain/folder"; diff --git a/libs/common/src/vault/models/domain/folder.ts b/libs/common/src/vault/models/domain/folder.ts index 93d04607af5..65018e3cf08 100644 --- a/libs/common/src/vault/models/domain/folder.ts +++ b/libs/common/src/vault/models/domain/folder.ts @@ -2,7 +2,7 @@ // @ts-strict-ignore import { Jsonify } from "type-fest"; -import { EncryptService } from "../../../platform/abstractions/encrypt.service"; +import { EncryptService } from "../../../key-management/crypto/abstractions/encrypt.service"; import Domain from "../../../platform/models/domain/domain-base"; import { EncString } from "../../../platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-crypto-key"; diff --git a/libs/common/src/vault/models/domain/login-uri.spec.ts b/libs/common/src/vault/models/domain/login-uri.spec.ts index a1ecb473597..6346f38f0de 100644 --- a/libs/common/src/vault/models/domain/login-uri.spec.ts +++ b/libs/common/src/vault/models/domain/login-uri.spec.ts @@ -2,8 +2,8 @@ import { MockProxy, mock } from "jest-mock-extended"; import { Jsonify } from "type-fest"; import { mockEnc, mockFromJson } from "../../../../spec"; +import { EncryptService } from "../../../key-management/crypto/abstractions/encrypt.service"; import { UriMatchStrategy } from "../../../models/domain/domain-service"; -import { EncryptService } from "../../../platform/abstractions/encrypt.service"; import { EncString } from "../../../platform/models/domain/enc-string"; import { LoginUriData } from "../data/login-uri.data"; diff --git a/libs/common/src/vault/models/view/cipher.view.ts b/libs/common/src/vault/models/view/cipher.view.ts index 20dbd23065c..650a1e9dc45 100644 --- a/libs/common/src/vault/models/view/cipher.view.ts +++ b/libs/common/src/vault/models/view/cipher.view.ts @@ -142,6 +142,13 @@ export class CipherView implements View, InitializerMetadata { ); } + get canAssignToCollections(): boolean { + if (this.organizationId == null) { + return true; + } + + return this.edit && this.viewPassword; + } /** * Determines if the cipher can be launched in a new browser tab. */ diff --git a/libs/common/src/vault/services/cipher.service.spec.ts b/libs/common/src/vault/services/cipher.service.spec.ts index 0d6578f165d..d87ee56ddda 100644 --- a/libs/common/src/vault/services/cipher.service.spec.ts +++ b/libs/common/src/vault/services/cipher.service.spec.ts @@ -1,12 +1,8 @@ import { mock } from "jest-mock-extended"; import { BehaviorSubject, map, of } from "rxjs"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { - CipherDecryptionKeys, - KeyService, -} from "../../../../key-management/src/abstractions/key.service"; +import { CipherDecryptionKeys, KeyService } from "@bitwarden/key-management"; + import { FakeAccountService, mockAccountServiceWith } from "../../../spec/fake-account-service"; import { FakeStateProvider } from "../../../spec/fake-state-provider"; import { makeStaticByteArray } from "../../../spec/utils"; @@ -14,10 +10,10 @@ import { ApiService } from "../../abstractions/api.service"; import { SearchService } from "../../abstractions/search.service"; import { AutofillSettingsService } from "../../autofill/services/autofill-settings.service"; import { DomainSettingsService } from "../../autofill/services/domain-settings.service"; +import { BulkEncryptService } from "../../key-management/crypto/abstractions/bulk-encrypt.service"; +import { EncryptService } from "../../key-management/crypto/abstractions/encrypt.service"; import { UriMatchStrategy } from "../../models/domain/domain-service"; -import { BulkEncryptService } from "../../platform/abstractions/bulk-encrypt.service"; import { ConfigService } from "../../platform/abstractions/config/config.service"; -import { EncryptService } from "../../platform/abstractions/encrypt.service"; import { I18nService } from "../../platform/abstractions/i18n.service"; import { StateService } from "../../platform/abstractions/state.service"; import { Utils } from "../../platform/misc/utils"; @@ -386,8 +382,16 @@ describe("Cipher Service", () => { Cipher1: cipher1, Cipher2: cipher2, }); - cipherService.cipherViews$ = decryptedCiphers.pipe(map((ciphers) => Object.values(ciphers))); - cipherService.failedToDecryptCiphers$ = failedCiphers = new BehaviorSubject([]); + jest + .spyOn(cipherService, "cipherViews$") + .mockImplementation((userId: UserId) => + decryptedCiphers.pipe(map((ciphers) => Object.values(ciphers))), + ); + + failedCiphers = new BehaviorSubject([]); + jest + .spyOn(cipherService, "failedToDecryptCiphers$") + .mockImplementation((userId: UserId) => failedCiphers); encryptService.decryptToBytes.mockResolvedValue(new Uint8Array(32)); encryptedKey = new EncString("Re-encrypted Cipher Key"); diff --git a/libs/common/src/vault/services/cipher.service.ts b/libs/common/src/vault/services/cipher.service.ts index 18295453d9a..73d9511fb2b 100644 --- a/libs/common/src/vault/services/cipher.service.ts +++ b/libs/common/src/vault/services/cipher.service.ts @@ -14,22 +14,21 @@ import { } from "rxjs"; import { SemVer } from "semver"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { KeyService } from "../../../../key-management/src/abstractions/key.service"; +import { KeyService } from "@bitwarden/key-management"; + import { ApiService } from "../../abstractions/api.service"; import { SearchService } from "../../abstractions/search.service"; import { AccountService } from "../../auth/abstractions/account.service"; import { AutofillSettingsServiceAbstraction } from "../../autofill/services/autofill-settings.service"; import { DomainSettingsService } from "../../autofill/services/domain-settings.service"; import { FeatureFlag } from "../../enums/feature-flag.enum"; +import { BulkEncryptService } from "../../key-management/crypto/abstractions/bulk-encrypt.service"; +import { EncryptService } from "../../key-management/crypto/abstractions/encrypt.service"; import { UriMatchStrategySetting } from "../../models/domain/domain-service"; import { ErrorResponse } from "../../models/response/error.response"; import { ListResponse } from "../../models/response/list.response"; import { View } from "../../models/view/view"; -import { BulkEncryptService } from "../../platform/abstractions/bulk-encrypt.service"; import { ConfigService } from "../../platform/abstractions/config/config.service"; -import { EncryptService } from "../../platform/abstractions/encrypt.service"; import { I18nService } from "../../platform/abstractions/i18n.service"; import { StateService } from "../../platform/abstractions/state.service"; import { sequentialize } from "../../platform/misc/sequentialize"; @@ -38,7 +37,7 @@ import Domain from "../../platform/models/domain/domain-base"; import { EncArrayBuffer } from "../../platform/models/domain/enc-array-buffer"; import { EncString } from "../../platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "../../platform/models/domain/symmetric-crypto-key"; -import { ActiveUserState, StateProvider } from "../../platform/state"; +import { StateProvider } from "../../platform/state"; import { CipherId, CollectionId, OrganizationId, UserId } from "../../types/guid"; import { OrgKey, UserKey } from "../../types/key"; import { CipherService as CipherServiceAbstraction } from "../abstractions/cipher.service"; @@ -98,33 +97,6 @@ export class CipherService implements CipherServiceAbstraction { */ private forceCipherViews$: Subject = new Subject(); - localData$: Observable>; - ciphers$: Observable>; - - /** - * Observable that emits an array of decrypted ciphers for the active user. - * This observable will not emit until the encrypted ciphers have either been loaded from state or after sync. - * - * A `null` value indicates that the latest encrypted ciphers have not been decrypted yet and that - * decryption is in progress. The latest decrypted ciphers will be emitted once decryption is complete. - * - */ - cipherViews$: Observable; - addEditCipherInfo$: Observable; - - /** - * Observable that emits an array of cipherViews that failed to decrypt. Does not emit until decryption has completed. - * - * An empty array indicates that all ciphers were successfully decrypted. - */ - failedToDecryptCiphers$: Observable; - - private localDataState: ActiveUserState>; - private encryptedCiphersState: ActiveUserState>; - private decryptedCiphersState: ActiveUserState>; - private failedToDecryptCiphersState: ActiveUserState; - private addEditCipherInfoState: ActiveUserState; - constructor( private keyService: KeyService, private domainSettingsService: DomainSettingsService, @@ -139,30 +111,49 @@ export class CipherService implements CipherServiceAbstraction { private configService: ConfigService, private stateProvider: StateProvider, private accountService: AccountService, - ) { - this.localDataState = this.stateProvider.getActive(LOCAL_DATA_KEY); - this.encryptedCiphersState = this.stateProvider.getActive(ENCRYPTED_CIPHERS); - this.decryptedCiphersState = this.stateProvider.getActive(DECRYPTED_CIPHERS); - this.failedToDecryptCiphersState = this.stateProvider.getActive(FAILED_DECRYPTED_CIPHERS); - this.addEditCipherInfoState = this.stateProvider.getActive(ADD_EDIT_CIPHER_INFO_KEY); + ) {} - this.localData$ = this.localDataState.state$.pipe(map((data) => data ?? {})); - this.ciphers$ = this.encryptedCiphersState.state$.pipe(map((ciphers) => ciphers ?? {})); + localData$(userId: UserId): Observable> { + return this.localDataState(userId).state$.pipe(map((data) => data ?? {})); + } - // Decrypted ciphers depend on both ciphers and local data and need to be updated when either changes - this.cipherViews$ = combineLatest([this.encryptedCiphersState.state$, this.localData$]).pipe( + /** + * Observable that emits an object of encrypted ciphers for the active user. + */ + ciphers$(userId: UserId): Observable> { + return this.encryptedCiphersState(userId).state$.pipe(map((ciphers) => ciphers ?? {})); + } + + /** + * Observable that emits an array of decrypted ciphers for the active user. + * This observable will not emit until the encrypted ciphers have either been loaded from state or after sync. + * + * A `null` value indicates that the latest encrypted ciphers have not been decrypted yet and that + * decryption is in progress. The latest decrypted ciphers will be emitted once decryption is complete. + */ + cipherViews$(userId: UserId): Observable { + return combineLatest([this.encryptedCiphersState(userId).state$, this.localData$(userId)]).pipe( filter(([ciphers]) => ciphers != null), // Skip if ciphers haven't been loaded yor synced yet - switchMap(() => merge(this.forceCipherViews$, this.getAllDecrypted())), + switchMap(() => merge(this.forceCipherViews$, this.getAllDecrypted(userId))), shareReplay({ bufferSize: 1, refCount: true }), ); + } - this.failedToDecryptCiphers$ = this.failedToDecryptCiphersState.state$.pipe( + addEditCipherInfo$(userId: UserId): Observable { + return this.addEditCipherInfoState(userId).state$; + } + + /** + * Observable that emits an array of cipherViews that failed to decrypt. Does not emit until decryption has completed. + * + * An empty array indicates that all ciphers were successfully decrypted. + */ + failedToDecryptCiphers$(userId: UserId): Observable { + return this.failedToDecryptCiphersState(userId).state$.pipe( filter((ciphers) => ciphers != null), switchMap((ciphers) => merge(this.forceCipherViews$, of(ciphers))), shareReplay({ bufferSize: 1, refCount: true }), ); - - this.addEditCipherInfo$ = this.addEditCipherInfoState.state$; } async setDecryptedCipherCache(value: CipherView[], userId: UserId) { @@ -213,7 +204,7 @@ export class CipherService implements CipherServiceAbstraction { ): Promise { if (model.id != null) { if (originalCipher == null) { - originalCipher = await this.get(model.id); + originalCipher = await this.get(model.id, userId); } if (originalCipher != null) { await this.updateModelfromExistingCipher(model, originalCipher, userId); @@ -367,22 +358,22 @@ export class CipherService implements CipherServiceAbstraction { return ph; } - async get(id: string): Promise { - const ciphers = await firstValueFrom(this.ciphers$); + async get(id: string, userId: UserId): Promise { + const ciphers = await firstValueFrom(this.ciphers$(userId)); // eslint-disable-next-line if (ciphers == null || !ciphers.hasOwnProperty(id)) { return null; } - const localData = await firstValueFrom(this.localData$); + const localData = await firstValueFrom(this.localData$(userId)); const cipherId = id as CipherId; return new Cipher(ciphers[cipherId], localData ? localData[cipherId] : null); } - async getAll(): Promise { - const localData = await firstValueFrom(this.localData$); - const ciphers = await firstValueFrom(this.ciphers$); + async getAll(userId: UserId): Promise { + const localData = await firstValueFrom(this.localData$(userId)); + const ciphers = await firstValueFrom(this.ciphers$(userId)); const response: Cipher[] = []; for (const id in ciphers) { // eslint-disable-next-line @@ -400,33 +391,27 @@ export class CipherService implements CipherServiceAbstraction { * @deprecated Use `cipherViews$` observable instead */ @sequentialize(() => "getAllDecrypted") - async getAllDecrypted(): Promise { - const decCiphers = await this.getDecryptedCiphers(); + async getAllDecrypted(userId: UserId): Promise { + const decCiphers = await this.getDecryptedCiphers(userId); if (decCiphers != null && decCiphers.length !== 0) { - await this.reindexCiphers(); - return await this.getDecryptedCiphers(); - } - - const activeUserId = await firstValueFrom(this.stateProvider.activeUserId$); - - if (activeUserId == null) { - return []; + await this.reindexCiphers(userId); + return await this.getDecryptedCiphers(userId); } const [newDecCiphers, failedCiphers] = await this.decryptCiphers( - await this.getAll(), - activeUserId, + await this.getAll(userId), + userId, ); - await this.setDecryptedCipherCache(newDecCiphers, activeUserId); - await this.setFailedDecryptedCiphers(failedCiphers, activeUserId); + await this.setDecryptedCipherCache(newDecCiphers, userId); + await this.setFailedDecryptedCiphers(failedCiphers, userId); return newDecCiphers; } - private async getDecryptedCiphers() { + private async getDecryptedCiphers(userId: UserId) { return Object.values( - await firstValueFrom(this.decryptedCiphersState.state$.pipe(map((c) => c ?? {}))), + await firstValueFrom(this.decryptedCiphersState(userId).state$.pipe(map((c) => c ?? {}))), ); } @@ -492,18 +477,21 @@ export class CipherService implements CipherServiceAbstraction { ); } - private async reindexCiphers() { - const userId = await this.stateService.getUserId(); + private async reindexCiphers(userId: UserId) { const reindexRequired = this.searchService != null && ((await firstValueFrom(this.searchService.indexedEntityId$)) ?? userId) !== userId; if (reindexRequired) { - await this.searchService.indexCiphers(await this.getDecryptedCiphers(), userId); + await this.searchService.indexCiphers(await this.getDecryptedCiphers(userId), userId); } } - async getAllDecryptedForGrouping(groupingId: string, folder = true): Promise { - const ciphers = await this.getAllDecrypted(); + async getAllDecryptedForGrouping( + groupingId: string, + userId: UserId, + folder = true, + ): Promise { + const ciphers = await this.getAllDecrypted(userId); return ciphers.filter((cipher) => { if (cipher.isDeleted) { @@ -525,10 +513,11 @@ export class CipherService implements CipherServiceAbstraction { async getAllDecryptedForUrl( url: string, + userId: UserId, includeOtherTypes?: CipherType[], defaultMatch: UriMatchStrategySetting = null, ): Promise { - const ciphers = await this.getAllDecrypted(); + const ciphers = await this.getAllDecrypted(userId); return await this.filterCiphersForUrl(ciphers, url, includeOtherTypes, defaultMatch); } @@ -570,8 +559,11 @@ export class CipherService implements CipherServiceAbstraction { }); } - private async getAllDecryptedCiphersOfType(type: CipherType[]): Promise { - const ciphers = await this.getAllDecrypted(); + private async getAllDecryptedCiphersOfType( + type: CipherType[], + userId: UserId, + ): Promise { + const ciphers = await this.getAllDecrypted(userId); return ciphers .filter((cipher) => cipher.deletedDate == null && type.includes(cipher.type)) .sort((a, b) => this.sortCiphersByLastUsedThenName(a, b)); @@ -614,23 +606,31 @@ export class CipherService implements CipherServiceAbstraction { return decCiphers; } - async getLastUsedForUrl(url: string, autofillOnPageLoad = false): Promise { - return this.getCipherForUrl(url, true, false, autofillOnPageLoad); + async getLastUsedForUrl( + url: string, + userId: UserId, + autofillOnPageLoad = false, + ): Promise { + return this.getCipherForUrl(url, userId, true, false, autofillOnPageLoad); } - async getLastLaunchedForUrl(url: string, autofillOnPageLoad = false): Promise { - return this.getCipherForUrl(url, false, true, autofillOnPageLoad); + async getLastLaunchedForUrl( + url: string, + userId: UserId, + autofillOnPageLoad = false, + ): Promise { + return this.getCipherForUrl(url, userId, false, true, autofillOnPageLoad); } - async getNextCipherForUrl(url: string): Promise { - return this.getCipherForUrl(url, false, false, false); + async getNextCipherForUrl(url: string, userId: UserId): Promise { + return this.getCipherForUrl(url, userId, false, false, false); } - async getNextCardCipher(): Promise { + async getNextCardCipher(userId: UserId): Promise { const cacheKey = "cardCiphers"; if (!this.sortedCiphersCache.isCached(cacheKey)) { - const ciphers = await this.getAllDecryptedCiphersOfType([CipherType.Card]); + const ciphers = await this.getAllDecryptedCiphersOfType([CipherType.Card], userId); if (!ciphers?.length) { return null; } @@ -641,11 +641,11 @@ export class CipherService implements CipherServiceAbstraction { return this.sortedCiphersCache.getNext(cacheKey); } - async getNextIdentityCipher(): Promise { + async getNextIdentityCipher(userId: UserId): Promise { const cacheKey = "identityCiphers"; if (!this.sortedCiphersCache.isCached(cacheKey)) { - const ciphers = await this.getAllDecryptedCiphersOfType([CipherType.Identity]); + const ciphers = await this.getAllDecryptedCiphersOfType([CipherType.Identity], userId); if (!ciphers?.length) { return null; } @@ -660,9 +660,8 @@ export class CipherService implements CipherServiceAbstraction { this.sortedCiphersCache.updateLastUsedIndex(url); } - async updateLastUsedDate(id: string): Promise { - const userId = await firstValueFrom(this.stateProvider.activeUserId$); - let ciphersLocalData = await firstValueFrom(this.localData$); + async updateLastUsedDate(id: string, userId: UserId): Promise { + let ciphersLocalData = await firstValueFrom(this.localData$(userId)); if (!ciphersLocalData) { ciphersLocalData = {}; @@ -677,9 +676,9 @@ export class CipherService implements CipherServiceAbstraction { }; } - await this.localDataState.update(() => ciphersLocalData); + await this.localDataState(userId).update(() => ciphersLocalData); - const decryptedCipherCache = await this.getDecryptedCiphers(); + const decryptedCipherCache = await this.getDecryptedCiphers(userId); if (!decryptedCipherCache) { return; } @@ -694,9 +693,8 @@ export class CipherService implements CipherServiceAbstraction { await this.setDecryptedCiphers(decryptedCipherCache, userId); } - async updateLastLaunchedDate(id: string): Promise { - const userId = await firstValueFrom(this.stateProvider.activeUserId$); - let ciphersLocalData = await firstValueFrom(this.localData$); + async updateLastLaunchedDate(id: string, userId: UserId): Promise { + let ciphersLocalData = await firstValueFrom(this.localData$(userId)); if (!ciphersLocalData) { ciphersLocalData = {}; @@ -708,9 +706,9 @@ export class CipherService implements CipherServiceAbstraction { lastUsedDate: currentTime, }; - await this.localDataState.update(() => ciphersLocalData); + await this.localDataState(userId).update(() => ciphersLocalData); - const decryptedCipherCache = await this.getDecryptedCiphers(); + const decryptedCipherCache = await this.getDecryptedCiphers(userId); if (!decryptedCipherCache) { return; } @@ -915,13 +913,13 @@ export class CipherService implements CipherServiceAbstraction { return new Cipher(cData); } - async saveCollectionsWithServer(cipher: Cipher): Promise { + async saveCollectionsWithServer(cipher: Cipher, userId: UserId): Promise { const request = new CipherCollectionsRequest(cipher.collectionIds); const response = await this.apiService.putCipherCollections(cipher.id, request); // The response will now check for an unavailable value. This value determines whether // the user still has Can Manage access to the item after updating. if (response.unavailable) { - await this.delete(cipher.id); + await this.delete(cipher.id, userId); return; } const data = new CipherData(response.cipher); @@ -945,6 +943,7 @@ export class CipherService implements CipherServiceAbstraction { */ async bulkUpdateCollectionsWithServer( orgId: OrganizationId, + userId: UserId, cipherIds: CipherId[], collectionIds: CollectionId[], removeCollections: boolean = false, @@ -959,7 +958,7 @@ export class CipherService implements CipherServiceAbstraction { await this.apiService.send("POST", "/ciphers/bulk-collections", request, true, false); // Update the local state - const ciphers = await firstValueFrom(this.ciphers$); + const ciphers = await firstValueFrom(this.ciphers$(userId)); for (const id of cipherIds) { const cipher = ciphers[id]; @@ -976,7 +975,7 @@ export class CipherService implements CipherServiceAbstraction { } await this.clearCache(); - await this.encryptedCiphersState.update(() => ciphers); + await this.encryptedCiphersState(userId).update(() => ciphers); } async upsert(cipher: CipherData | CipherData[]): Promise> { @@ -1017,10 +1016,10 @@ export class CipherService implements CipherServiceAbstraction { await this.clearCache(userId); } - async moveManyWithServer(ids: string[], folderId: string): Promise { + async moveManyWithServer(ids: string[], folderId: string, userId: UserId): Promise { await this.apiService.putMoveCiphers(new CipherBulkMoveRequest(ids, folderId)); - let ciphers = await firstValueFrom(this.ciphers$); + let ciphers = await firstValueFrom(this.ciphers$(userId)); if (ciphers == null) { ciphers = {}; } @@ -1033,11 +1032,11 @@ export class CipherService implements CipherServiceAbstraction { }); await this.clearCache(); - await this.encryptedCiphersState.update(() => ciphers); + await this.encryptedCiphersState(userId).update(() => ciphers); } - async delete(id: string | string[]): Promise { - const ciphers = await firstValueFrom(this.ciphers$); + async delete(id: string | string[], userId: UserId): Promise { + const ciphers = await firstValueFrom(this.ciphers$(userId)); if (ciphers == null) { return; } @@ -1055,35 +1054,36 @@ export class CipherService implements CipherServiceAbstraction { } await this.clearCache(); - await this.encryptedCiphersState.update(() => ciphers); + await this.encryptedCiphersState(userId).update(() => ciphers); } - async deleteWithServer(id: string, asAdmin = false): Promise { + async deleteWithServer(id: string, userId: UserId, asAdmin = false): Promise { if (asAdmin) { await this.apiService.deleteCipherAdmin(id); } else { await this.apiService.deleteCipher(id); } - await this.delete(id); + await this.delete(id, userId); } - async deleteManyWithServer(ids: string[], asAdmin = false): Promise { + async deleteManyWithServer(ids: string[], userId: UserId, asAdmin = false): Promise { const request = new CipherBulkDeleteRequest(ids); if (asAdmin) { await this.apiService.deleteManyCiphersAdmin(request); } else { await this.apiService.deleteManyCiphers(request); } - await this.delete(ids); + await this.delete(ids, userId); } async deleteAttachment( id: string, revisionDate: string, attachmentId: string, + userId: UserId, ): Promise { - let ciphers = await firstValueFrom(this.ciphers$); + let ciphers = await firstValueFrom(this.ciphers$(userId)); const cipherId = id as CipherId; // eslint-disable-next-line if (ciphers == null || !ciphers.hasOwnProperty(id) || ciphers[cipherId].attachments == null) { @@ -1101,7 +1101,7 @@ export class CipherService implements CipherServiceAbstraction { ciphers[cipherId].revisionDate = revisionDate; await this.clearCache(); - await this.encryptedCiphersState.update(() => { + await this.encryptedCiphersState(userId).update(() => { if (ciphers == null) { ciphers = {}; } @@ -1111,7 +1111,11 @@ export class CipherService implements CipherServiceAbstraction { return ciphers[cipherId]; } - async deleteAttachmentWithServer(id: string, attachmentId: string): Promise { + async deleteAttachmentWithServer( + id: string, + attachmentId: string, + userId: UserId, + ): Promise { let cipherResponse = null; try { cipherResponse = await this.apiService.deleteCipherAttachment(id, attachmentId); @@ -1120,7 +1124,7 @@ export class CipherService implements CipherServiceAbstraction { } const cipherData = CipherData.fromJSON(cipherResponse?.cipher); - return await this.deleteAttachment(id, cipherData.revisionDate, attachmentId); + return await this.deleteAttachment(id, cipherData.revisionDate, attachmentId, userId); } sortCiphersByLastUsed(a: CipherView, b: CipherView): number { @@ -1193,8 +1197,8 @@ export class CipherService implements CipherServiceAbstraction { }; } - async softDelete(id: string | string[]): Promise { - let ciphers = await firstValueFrom(this.ciphers$); + async softDelete(id: string | string[], userId: UserId): Promise { + let ciphers = await firstValueFrom(this.ciphers$(userId)); if (ciphers == null) { return; } @@ -1213,7 +1217,7 @@ export class CipherService implements CipherServiceAbstraction { } await this.clearCache(); - await this.encryptedCiphersState.update(() => { + await this.encryptedCiphersState(userId).update(() => { if (ciphers == null) { ciphers = {}; } @@ -1221,17 +1225,17 @@ export class CipherService implements CipherServiceAbstraction { }); } - async softDeleteWithServer(id: string, asAdmin = false): Promise { + async softDeleteWithServer(id: string, userId: UserId, asAdmin = false): Promise { if (asAdmin) { await this.apiService.putDeleteCipherAdmin(id); } else { await this.apiService.putDeleteCipher(id); } - await this.softDelete(id); + await this.softDelete(id, userId); } - async softDeleteManyWithServer(ids: string[], asAdmin = false): Promise { + async softDeleteManyWithServer(ids: string[], userId: UserId, asAdmin = false): Promise { const request = new CipherBulkDeleteRequest(ids); if (asAdmin) { await this.apiService.putDeleteManyCiphersAdmin(request); @@ -1239,13 +1243,14 @@ export class CipherService implements CipherServiceAbstraction { await this.apiService.putDeleteManyCiphers(request); } - await this.softDelete(ids); + await this.softDelete(ids, userId); } async restore( cipher: { id: string; revisionDate: string } | { id: string; revisionDate: string }[], + userId: UserId, ) { - let ciphers = await firstValueFrom(this.ciphers$); + let ciphers = await firstValueFrom(this.ciphers$(userId)); if (ciphers == null) { return; } @@ -1266,7 +1271,7 @@ export class CipherService implements CipherServiceAbstraction { } await this.clearCache(); - await this.encryptedCiphersState.update(() => { + await this.encryptedCiphersState(userId).update(() => { if (ciphers == null) { ciphers = {}; } @@ -1274,7 +1279,7 @@ export class CipherService implements CipherServiceAbstraction { }); } - async restoreWithServer(id: string, asAdmin = false): Promise { + async restoreWithServer(id: string, userId: UserId, asAdmin = false): Promise { let response; if (asAdmin) { response = await this.apiService.putRestoreCipherAdmin(id); @@ -1282,14 +1287,14 @@ export class CipherService implements CipherServiceAbstraction { response = await this.apiService.putRestoreCipher(id); } - await this.restore({ id: id, revisionDate: response.revisionDate }); + await this.restore({ id: id, revisionDate: response.revisionDate }, userId); } /** * No longer using an asAdmin Param. Org Vault bulkRestore will assess if an item is unassigned or editable * The Org Vault will pass those ids an array as well as the orgId when calling bulkRestore */ - async restoreManyWithServer(ids: string[], orgId: string = null): Promise { + async restoreManyWithServer(ids: string[], userId: UserId, orgId: string = null): Promise { let response; if (orgId) { @@ -1304,7 +1309,7 @@ export class CipherService implements CipherServiceAbstraction { for (const cipher of response.data) { restores.push({ id: cipher.id, revisionDate: cipher.revisionDate }); } - await this.restore(restores); + await this.restore(restores, userId); } async getKeyForCipherKeyDecryption(cipher: Cipher, userId: UserId): Promise { @@ -1314,8 +1319,8 @@ export class CipherService implements CipherServiceAbstraction { ); } - async setAddEditCipherInfo(value: AddEditCipherInfo) { - await this.addEditCipherInfoState.update(() => value, { + async setAddEditCipherInfo(value: AddEditCipherInfo, userId: UserId) { + await this.addEditCipherInfoState(userId).update(() => value, { shouldUpdate: (current) => !(current == null && value == null), }); } @@ -1334,8 +1339,8 @@ export class CipherService implements CipherServiceAbstraction { let encryptedCiphers: CipherWithIdRequest[] = []; - const ciphers = await firstValueFrom(this.cipherViews$); - const failedCiphers = await firstValueFrom(this.failedToDecryptCiphers$); + const ciphers = await firstValueFrom(this.cipherViews$(userId)); + const failedCiphers = await firstValueFrom(this.failedToDecryptCiphers$(userId)); if (!ciphers) { return encryptedCiphers; } @@ -1358,6 +1363,41 @@ export class CipherService implements CipherServiceAbstraction { return encryptedCiphers; } + /** + * @returns a SingleUserState + */ + private localDataState(userId: UserId) { + return this.stateProvider.getUser(userId, LOCAL_DATA_KEY); + } + + /** + * @returns a SingleUserState for the encrypted ciphers + */ + private encryptedCiphersState(userId: UserId) { + return this.stateProvider.getUser(userId, ENCRYPTED_CIPHERS); + } + + /** + * @returns a SingleUserState for the decrypted ciphers + */ + private decryptedCiphersState(userId: UserId) { + return this.stateProvider.getUser(userId, DECRYPTED_CIPHERS); + } + + /** + * @returns a SingleUserState for the add/edit cipher info + */ + private addEditCipherInfoState(userId: UserId) { + return this.stateProvider.getUser(userId, ADD_EDIT_CIPHER_INFO_KEY); + } + + /** + * @returns a SingleUserState for the failed to decrypt ciphers + */ + private failedToDecryptCiphersState(userId: UserId) { + return this.stateProvider.getUser(userId, FAILED_DECRYPTED_CIPHERS); + } + // Helpers // In the case of a cipher that is being shared with an organization, we want to decrypt the @@ -1661,6 +1701,7 @@ export class CipherService implements CipherServiceAbstraction { private async getCipherForUrl( url: string, + userId: UserId, lastUsed: boolean, lastLaunched: boolean, autofillOnPageLoad: boolean, @@ -1668,7 +1709,7 @@ export class CipherService implements CipherServiceAbstraction { const cacheKey = autofillOnPageLoad ? "autofillOnPageLoad-" + url : url; if (!this.sortedCiphersCache.isCached(cacheKey)) { - let ciphers = await this.getAllDecryptedForUrl(url); + let ciphers = await this.getAllDecryptedForUrl(url, userId); if (!ciphers) { return null; } diff --git a/libs/common/src/vault/services/folder/folder.service.spec.ts b/libs/common/src/vault/services/folder/folder.service.spec.ts index cc3aa1946ca..ced4e2dceb7 100644 --- a/libs/common/src/vault/services/folder/folder.service.spec.ts +++ b/libs/common/src/vault/services/folder/folder.service.spec.ts @@ -1,14 +1,13 @@ import { mock, MockProxy } from "jest-mock-extended"; import { BehaviorSubject, firstValueFrom } from "rxjs"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { KeyService } from "../../../../../key-management/src/abstractions/key.service"; +import { KeyService } from "@bitwarden/key-management"; + import { makeEncString } from "../../../../spec"; import { FakeAccountService, mockAccountServiceWith } from "../../../../spec/fake-account-service"; import { FakeSingleUserState } from "../../../../spec/fake-state"; import { FakeStateProvider } from "../../../../spec/fake-state-provider"; -import { EncryptService } from "../../../platform/abstractions/encrypt.service"; +import { EncryptService } from "../../../key-management/crypto/abstractions/encrypt.service"; import { I18nService } from "../../../platform/abstractions/i18n.service"; import { Utils } from "../../../platform/misc/utils"; import { EncString } from "../../../platform/models/domain/enc-string"; diff --git a/libs/common/src/vault/services/folder/folder.service.ts b/libs/common/src/vault/services/folder/folder.service.ts index c21a92fd894..89bc5353f88 100644 --- a/libs/common/src/vault/services/folder/folder.service.ts +++ b/libs/common/src/vault/services/folder/folder.service.ts @@ -2,12 +2,11 @@ // @ts-strict-ignore import { Observable, Subject, firstValueFrom, map, shareReplay, switchMap, merge } from "rxjs"; -import { EncryptService } from ".././../../platform/abstractions/encrypt.service"; -import { Utils } from ".././../../platform/misc/utils"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { KeyService } from "../../../../../key-management/src/abstractions/key.service"; +import { KeyService } from "@bitwarden/key-management"; + +import { EncryptService } from "../../../key-management/crypto/abstractions/encrypt.service"; import { I18nService } from "../../../platform/abstractions/i18n.service"; +import { Utils } from "../../../platform/misc/utils"; import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-crypto-key"; import { StateProvider } from "../../../platform/state"; import { UserId } from "../../../types/guid"; @@ -191,7 +190,7 @@ export class FolderService implements InternalFolderServiceAbstraction { }); // Items in a deleted folder are re-assigned to "No Folder" - const ciphers = await this.cipherService.getAll(); + const ciphers = await this.cipherService.getAll(userId); if (ciphers != null) { const updates: Cipher[] = []; for (const cId in ciphers) { diff --git a/libs/components/src/async-actions/in-forms.stories.ts b/libs/components/src/async-actions/in-forms.stories.ts index 7ddb32da281..b45f750084c 100644 --- a/libs/components/src/async-actions/in-forms.stories.ts +++ b/libs/components/src/async-actions/in-forms.stories.ts @@ -4,10 +4,8 @@ import { action } from "@storybook/addon-actions"; import { Meta, moduleMetadata, StoryObj } from "@storybook/angular"; import { delay, of } from "rxjs"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { I18nService } from "@bitwarden/common/src/platform/abstractions/i18n.service"; import { ButtonModule } from "../button"; import { FormFieldModule } from "../form-field"; diff --git a/libs/components/src/avatar/avatar.component.ts b/libs/components/src/avatar/avatar.component.ts index 76ff702e88b..0e3dbd6f1b9 100644 --- a/libs/components/src/avatar/avatar.component.ts +++ b/libs/components/src/avatar/avatar.component.ts @@ -1,6 +1,6 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { NgIf, NgClass } from "@angular/common"; +import { NgClass } from "@angular/common"; import { Component, Input, OnChanges } from "@angular/core"; import { DomSanitizer, SafeResourceUrl } from "@angular/platform-browser"; @@ -18,9 +18,11 @@ const SizeClasses: Record = { @Component({ selector: "bit-avatar", - template: ``, + template: `@if (src) { + + }`, standalone: true, - imports: [NgIf, NgClass], + imports: [NgClass], }) export class AvatarComponent implements OnChanges { @Input() border = false; diff --git a/libs/components/src/avatar/avatar.mdx b/libs/components/src/avatar/avatar.mdx index 0f3f6f06a9b..627ba526ed9 100644 --- a/libs/components/src/avatar/avatar.mdx +++ b/libs/components/src/avatar/avatar.mdx @@ -1,4 +1,4 @@ -import { Meta, Story, Primary, Controls } from "@storybook/addon-docs"; +import { Meta, Canvas, Primary, Controls } from "@storybook/addon-docs"; import * as stories from "./avatar.stories"; @@ -18,15 +18,15 @@ visual indicator to recognize which of a personal or work account a user is logg ### Large: 64px - + ### Default: 48px - + ### Small 28px - + ## Background color @@ -37,9 +37,9 @@ priority: - ID - Text, usually set to the user's Name field - + Use the user 'ID' field if `Name` is not defined. - + ## Outline @@ -47,7 +47,7 @@ If the avatar is displayed on one of the theme's `background` color variables or display the avatar with a 1 pixel `secondary-600` border to meet WCAG AA graphic contrast guidelines for interactive elements. - + ## Avatar as a button diff --git a/libs/components/src/badge-list/badge-list.component.html b/libs/components/src/badge-list/badge-list.component.html index ebd63117d03..c8aa7b84680 100644 --- a/libs/components/src/badge-list/badge-list.component.html +++ b/libs/components/src/badge-list/badge-list.component.html @@ -1,11 +1,15 @@

- + @for (item of filteredItems; track item; let last = $last) { {{ item }} - , - - - {{ "plusNMore" | i18n: (items.length - filteredItems.length).toString() }} - + @if (!last || isFiltered) { + , + } + } + @if (isFiltered) { + + {{ "plusNMore" | i18n: (items.length - filteredItems.length).toString() }} + + }
diff --git a/libs/components/src/badge-list/badge-list.component.ts b/libs/components/src/badge-list/badge-list.component.ts index 7d152761ed0..86e9a84cb77 100644 --- a/libs/components/src/badge-list/badge-list.component.ts +++ b/libs/components/src/badge-list/badge-list.component.ts @@ -1,6 +1,6 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { CommonModule } from "@angular/common"; + import { Component, Input, OnChanges } from "@angular/core"; import { I18nPipe } from "@bitwarden/ui-common"; @@ -11,7 +11,7 @@ import { BadgeModule, BadgeVariant } from "../badge"; selector: "bit-badge-list", templateUrl: "badge-list.component.html", standalone: true, - imports: [CommonModule, BadgeModule, I18nPipe], + imports: [BadgeModule, I18nPipe], }) export class BadgeListComponent implements OnChanges { private _maxItems: number; diff --git a/libs/components/src/badge/badge.mdx b/libs/components/src/badge/badge.mdx index fb2dceb0fa8..55f32183899 100644 --- a/libs/components/src/badge/badge.mdx +++ b/libs/components/src/badge/badge.mdx @@ -1,4 +1,4 @@ -import { Meta, Story, Primary, Controls } from "@storybook/addon-docs"; +import { Meta, Canvas, Primary, Controls } from "@storybook/addon-docs"; import * as stories from "./badge.stories"; @@ -31,39 +31,39 @@ The story below uses the ` + @if (showClose) { + + }
diff --git a/libs/components/src/banner/banner.mdx b/libs/components/src/banner/banner.mdx index d5b6a3b5279..67fb796a548 100644 --- a/libs/components/src/banner/banner.mdx +++ b/libs/components/src/banner/banner.mdx @@ -1,4 +1,4 @@ -import { Meta, Story, Controls, Canvas, Primary } from "@storybook/addon-docs"; +import { Meta, Controls, Canvas, Primary } from "@storybook/addon-docs"; import * as stories from "./banner.stories"; @@ -31,25 +31,25 @@ Use the following guidelines to help choose the correct type of banner. ### Premium - + Used primarily to encourage user to upgrade to premium. ### Info - + Used to communicate release notes, server maintenance or other informative event. ### Warning - + Used to alert the user of outdated info or versions. ### Danger - + Rarely used, but may be used to alert users over critical messages or very outdated versions. diff --git a/libs/components/src/breadcrumbs/breadcrumb.component.html b/libs/components/src/breadcrumbs/breadcrumb.component.html index dd5bac9beb4..bb4dc7cdffe 100644 --- a/libs/components/src/breadcrumbs/breadcrumb.component.html +++ b/libs/components/src/breadcrumbs/breadcrumb.component.html @@ -1,3 +1,6 @@ - + @if (icon) { + + } + diff --git a/libs/components/src/breadcrumbs/breadcrumb.component.ts b/libs/components/src/breadcrumbs/breadcrumb.component.ts index ce18bde171f..53c46a9b24a 100644 --- a/libs/components/src/breadcrumbs/breadcrumb.component.ts +++ b/libs/components/src/breadcrumbs/breadcrumb.component.ts @@ -1,6 +1,6 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { NgIf } from "@angular/common"; + import { Component, EventEmitter, Input, Output, TemplateRef, ViewChild } from "@angular/core"; import { QueryParamsHandling } from "@angular/router"; @@ -8,7 +8,6 @@ import { QueryParamsHandling } from "@angular/router"; selector: "bit-breadcrumb", templateUrl: "./breadcrumb.component.html", standalone: true, - imports: [NgIf], }) export class BreadcrumbComponent { @Input() diff --git a/libs/components/src/breadcrumbs/breadcrumbs.component.html b/libs/components/src/breadcrumbs/breadcrumbs.component.html index 502bb0bb8e7..5205e19cee5 100644 --- a/libs/components/src/breadcrumbs/breadcrumbs.component.html +++ b/libs/components/src/breadcrumbs/breadcrumbs.component.html @@ -1,5 +1,5 @@ - - +@for (breadcrumb of beforeOverflow; track breadcrumb; let last = $last) { + @if (breadcrumb.route) { - - + } + @if (!breadcrumb.route) { - - - - - - + } + @if (!last) { + + } +} +@if (hasOverflow) { + @if (beforeOverflow.length > 0) { + + } - - - + @for (breadcrumb of overflow; track breadcrumb) { + @if (breadcrumb.route) { - - + } + @if (!breadcrumb.route) { - - + } + } - - - + @for (breadcrumb of afterOverflow; track breadcrumb; let last = $last) { + @if (breadcrumb.route) { - - + } + @if (!breadcrumb.route) { - - - - + } + @if (!last) { + + } + } +} diff --git a/libs/components/src/breadcrumbs/breadcrumbs.mdx b/libs/components/src/breadcrumbs/breadcrumbs.mdx index 9dd23c530d1..1ea0aff8c36 100644 --- a/libs/components/src/breadcrumbs/breadcrumbs.mdx +++ b/libs/components/src/breadcrumbs/breadcrumbs.mdx @@ -1,4 +1,4 @@ -import { Meta, Story, Primary, Controls } from "@storybook/addon-docs"; +import { Meta, Canvas, Primary, Controls } from "@storybook/addon-docs"; import * as stories from "./breadcrumbs.stories"; @@ -23,7 +23,7 @@ See [Header with Breadcrumbs](?path=/story/web-header--with-breadcrumbs). When a user is 1 level deep into a tree, the top level is displayed as a single link above the page title. - + ### Second Level @@ -31,7 +31,7 @@ When a user is 2 or more levels deep into a tree, the top level is displayed fol icon, and the following pages. - + ### Overflow @@ -42,7 +42,7 @@ When a user is several levels deep into a tree, the top level or 2 are displayed When the user selects the icon button, a menu opens displaying the pages between the top level and the previous page. - + ### Small screens diff --git a/libs/components/src/button/button.mdx b/libs/components/src/button/button.mdx index 33e4aed19f7..21c992982d8 100644 --- a/libs/components/src/button/button.mdx +++ b/libs/components/src/button/button.mdx @@ -1,4 +1,4 @@ -import { Meta, Story, Primary, Controls } from "@storybook/addon-docs"; +import { Meta, Canvas, Primary, Controls } from "@storybook/addon-docs"; import * as stories from "./button.stories"; @@ -43,14 +43,14 @@ There are 3 main styles for the button: Primary, Secondary, and Danger. ### Primary - + Use the primary button styling for all Primary call to actions. An action is "primary" if it relates to the main purpose of a page. There should never be 2 primary styled buttons next to each other. ### Secondary - + The secondary styling should be used for secondary calls to action. An action is "secondary" if it relates indirectly to the purpose of a page. There may be multiple secondary buttons next to each @@ -58,20 +58,20 @@ other; however, generally there should only be 1 or 2 calls to action per page. ### Danger - + Use the danger styling only in settings when the user may preform a permanent action. ## Disabled UI - + ## Block Typically button widths expand with their text. In some causes though buttons may need to be block where the width is fixed and the text wraps to 2 lines if exceeding the button’s width. - + ## Accessibility @@ -96,7 +96,7 @@ Both submit and async action buttons use a loading button state while an action button is preforming a long running task in the background like a server API call, be sure to review the [Async Actions Directive](?path=/story/component-library-async-actions-overview--page). - + ### appA11yTitle diff --git a/libs/components/src/button/button.stories.ts b/libs/components/src/button/button.stories.ts index 469c2d1b51b..6024b0559f2 100644 --- a/libs/components/src/button/button.stories.ts +++ b/libs/components/src/button/button.stories.ts @@ -86,16 +86,15 @@ export const DisabledWithAttribute: Story = { render: (args) => ({ props: args, template: ` - + @if (disabled) { - - + } @else { - + } `, }), args: { diff --git a/libs/components/src/callout/callout.component.html b/libs/components/src/callout/callout.component.html index f64e197b9ef..bb7f918df32 100644 --- a/libs/components/src/callout/callout.component.html +++ b/libs/components/src/callout/callout.component.html @@ -3,10 +3,14 @@ [ngClass]="calloutClass" [attr.aria-labelledby]="titleId" > -
- - {{ title }} -
+ @if (title) { +
+ @if (icon) { + + } + {{ title }} +
+ }
diff --git a/libs/components/src/callout/callout.mdx b/libs/components/src/callout/callout.mdx index 3fdb53943b4..160b1e1cc33 100644 --- a/libs/components/src/callout/callout.mdx +++ b/libs/components/src/callout/callout.mdx @@ -1,4 +1,4 @@ -import { Meta, Story, Primary, Controls } from "@storybook/addon-docs"; +import { Meta, Canvas, Primary, Controls } from "@storybook/addon-docs"; import * as stories from "./callout.stories"; @@ -28,7 +28,7 @@ Use the success callout to communicate a positive messaging to the user. The success callout may also be used for the information related to a premium membership. In this case, replace the icon with - + ### Info @@ -39,7 +39,7 @@ information. **Example:** in the Domain Claiming modal, an info callout is used to tell the user the domain will automatically be checked. - + ### Warning @@ -49,7 +49,7 @@ irreversible results. **Example:** the warning callout is used before the change master password and encryption key form to alert the user that they will be logged out. - + ### Danger @@ -59,7 +59,7 @@ not reversible. The danger callout can also be used to alert the user of an error or errors, such as a server side errors after form submit or failed communication request. - + ## Accessibility diff --git a/libs/components/src/card/card.component.ts b/libs/components/src/card/card.component.ts index 37756088e0d..fdb02f280da 100644 --- a/libs/components/src/card/card.component.ts +++ b/libs/components/src/card/card.component.ts @@ -1,10 +1,8 @@ -import { CommonModule } from "@angular/common"; import { ChangeDetectionStrategy, Component } from "@angular/core"; @Component({ selector: "bit-card", standalone: true, - imports: [CommonModule], template: ``, changeDetection: ChangeDetectionStrategy.OnPush, host: { diff --git a/libs/components/src/checkbox/checkbox.stories.ts b/libs/components/src/checkbox/checkbox.stories.ts index 908085bb6df..9a59897e009 100644 --- a/libs/components/src/checkbox/checkbox.stories.ts +++ b/libs/components/src/checkbox/checkbox.stories.ts @@ -9,9 +9,7 @@ import { } from "@angular/forms"; import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { I18nService } from "@bitwarden/common/src/platform/abstractions/i18n.service"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { BadgeModule } from "../badge"; import { FormControlModule } from "../form-control"; diff --git a/libs/components/src/chip-select/chip-select.component.html b/libs/components/src/chip-select/chip-select.component.html index 81480f107f1..e88200b6e4f 100644 --- a/libs/components/src/chip-select/chip-select.component.html +++ b/libs/components/src/chip-select/chip-select.component.html @@ -30,78 +30,80 @@ {{ label }} - + @if (!selectedOption) { + + } - + @if (selectedOption) { + + }
-
- - - - - - - -
+ @if (getParent(renderedOptions); as parent) { + + + } + @for (option of renderedOptions.children; track option) { + + } +
+ } diff --git a/libs/components/src/chip-select/chip-select.component.ts b/libs/components/src/chip-select/chip-select.component.ts index a653d79f83f..e9be66da7d4 100644 --- a/libs/components/src/chip-select/chip-select.component.ts +++ b/libs/components/src/chip-select/chip-select.component.ts @@ -18,9 +18,8 @@ import { import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { compareValues } from "../../../common/src/platform/misc/compare-values"; +import { compareValues } from "@bitwarden/common/platform/misc/compare-values"; + import { ButtonModule } from "../button"; import { IconButtonModule } from "../icon-button"; import { MenuComponent, MenuItemDirective, MenuModule } from "../menu"; @@ -46,6 +45,7 @@ export type ChipSelectOption = Option & { multi: true, }, ], + preserveWhitespaces: false, }) export class ChipSelectComponent implements ControlValueAccessor, AfterViewInit { @ViewChild(MenuComponent) menu: MenuComponent; diff --git a/libs/components/src/chip-select/chip-select.mdx b/libs/components/src/chip-select/chip-select.mdx index 90bc7556209..d569158b75a 100644 --- a/libs/components/src/chip-select/chip-select.mdx +++ b/libs/components/src/chip-select/chip-select.mdx @@ -1,4 +1,4 @@ -import { Meta, Story, Primary, Controls, Canvas } from "@storybook/addon-docs"; +import { Meta, Primary, Controls, Canvas } from "@storybook/addon-docs"; import * as stories from "./chip-select.stories"; @@ -12,9 +12,7 @@ import { ChipSelectComponent } from "@bitwarden/components"; `` is a select element that is commonly used to filter items in lists or tables. - - - + ## Options @@ -91,9 +89,7 @@ const options = [ ]; ``` - - - + ## Placeholder Content diff --git a/libs/components/src/color-password/color-password.component.ts b/libs/components/src/color-password/color-password.component.ts index cbf746e9d73..e48758ca59a 100644 --- a/libs/components/src/color-password/color-password.component.ts +++ b/libs/components/src/color-password/color-password.component.ts @@ -1,6 +1,6 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { NgFor, NgIf } from "@angular/common"; + import { Component, HostBinding, Input } from "@angular/core"; import { Utils } from "@bitwarden/common/platform/misc/utils"; @@ -14,18 +14,16 @@ enum CharacterType { @Component({ selector: "bit-color-password", - template: ` - {{ character }} - {{ - i + 1 - }} - `, + template: `@for (character of passwordArray; track character; let i = $index) { + + {{ character }} + @if (showCount) { + {{ i + 1 }} + } + + }`, preserveWhitespaces: false, standalone: true, - imports: [NgFor, NgIf], }) export class ColorPasswordComponent { @Input() password: string = null; diff --git a/libs/components/src/color-password/color-password.mdx b/libs/components/src/color-password/color-password.mdx index d01c81b0073..8f3746715e1 100644 --- a/libs/components/src/color-password/color-password.mdx +++ b/libs/components/src/color-password/color-password.mdx @@ -1,4 +1,4 @@ -import { Meta, Story, Primary, Controls } from "@storybook/addon-docs"; +import { Meta, Canvas, Primary, Controls } from "@storybook/addon-docs"; import * as stories from "./color-password.stories"; @@ -18,15 +18,15 @@ the logic for displaying letters as `text-main`, numbers as `primary`, and speci The password count option is used in the Login type form. It is used to highlight each character's position in the password string. - + ## Wrapped Password When the password length is longer than the container's width, it should wrap as shown below. - + - + ## Accessibility diff --git a/libs/components/src/color-password/index.ts b/libs/components/src/color-password/index.ts index 86718f037f7..24870ca75d9 100644 --- a/libs/components/src/color-password/index.ts +++ b/libs/components/src/color-password/index.ts @@ -1 +1,2 @@ export * from "./color-password.module"; +export * from "./color-password.component"; diff --git a/libs/components/src/container/container.component.ts b/libs/components/src/container/container.component.ts index fbd9e40a7ca..1bcdb8f459b 100644 --- a/libs/components/src/container/container.component.ts +++ b/libs/components/src/container/container.component.ts @@ -1,4 +1,3 @@ -import { CommonModule } from "@angular/common"; import { Component } from "@angular/core"; /** @@ -7,7 +6,6 @@ import { Component } from "@angular/core"; @Component({ selector: "bit-container", templateUrl: "container.component.html", - imports: [CommonModule], standalone: true, }) export class ContainerComponent {} diff --git a/libs/components/src/dialog/dialog/dialog.component.html b/libs/components/src/dialog/dialog/dialog.component.html index ef9824471e7..01f05985127 100644 --- a/libs/components/src/dialog/dialog/dialog.component.html +++ b/libs/components/src/dialog/dialog/dialog.component.html @@ -13,9 +13,11 @@ class="tw-text-main tw-mb-0 tw-truncate" > {{ title }} - - {{ subtitle }} - + @if (subtitle) { + + {{ subtitle }} + + } - + @if (showCancelButton) { + + } diff --git a/libs/components/src/dialog/simple-dialog/simple-configurable-dialog/simple-configurable-dialog.component.ts b/libs/components/src/dialog/simple-dialog/simple-configurable-dialog/simple-configurable-dialog.component.ts index 60b2e1c3a3f..00026209183 100644 --- a/libs/components/src/dialog/simple-dialog/simple-configurable-dialog/simple-configurable-dialog.component.ts +++ b/libs/components/src/dialog/simple-dialog/simple-configurable-dialog/simple-configurable-dialog.component.ts @@ -1,7 +1,6 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore import { DialogRef, DIALOG_DATA } from "@angular/cdk/dialog"; -import { NgIf } from "@angular/common"; import { Component, Inject } from "@angular/core"; import { FormGroup, ReactiveFormsModule } from "@angular/forms"; @@ -39,7 +38,6 @@ const DEFAULT_COLOR: Record = { IconDirective, ButtonComponent, BitFormButtonDirective, - NgIf, ], }) export class SimpleConfigurableDialogComponent { diff --git a/libs/components/src/dialog/simple-dialog/simple-configurable-dialog/simple-configurable-dialog.service.stories.ts b/libs/components/src/dialog/simple-dialog/simple-configurable-dialog/simple-configurable-dialog.service.stories.ts index b4bf199358b..87d6eb9fbfc 100644 --- a/libs/components/src/dialog/simple-dialog/simple-configurable-dialog/simple-configurable-dialog.service.stories.ts +++ b/libs/components/src/dialog/simple-dialog/simple-configurable-dialog/simple-configurable-dialog.service.stories.ts @@ -12,23 +12,24 @@ import { DialogModule } from "../../dialog.module"; @Component({ template: ` -
-

{{ group.title }}

-
- + @for (group of dialogs; track group) { +
+

{{ group.title }}

+
+ @for (dialog of group.dialogs; track dialog) { + + } +
-
+ } - - {{ dialogCloseResult }} - + @if (showCallout) { + + {{ dialogCloseResult }} + + } `, }) class StoryDialogComponent { diff --git a/libs/components/src/dialog/simple-dialog/simple-dialog.component.html b/libs/components/src/dialog/simple-dialog/simple-dialog.component.html index 0b56c6287dc..1f154a8d543 100644 --- a/libs/components/src/dialog/simple-dialog/simple-dialog.component.html +++ b/libs/components/src/dialog/simple-dialog/simple-dialog.component.html @@ -3,12 +3,11 @@ @fadeIn >
- + @if (hasIcon) { - - + } @else { - + }

+ diff --git a/libs/components/src/dialog/simple-dialog/types.ts b/libs/components/src/dialog/simple-dialog/types.ts index 4032b499cbe..9724111b4c2 100644 --- a/libs/components/src/dialog/simple-dialog/types.ts +++ b/libs/components/src/dialog/simple-dialog/types.ts @@ -46,7 +46,7 @@ export type SimpleDialogOptions = { * If null is provided, the cancel button will be removed. * * If not localized, pass in a `Translation` */ - cancelButtonText?: string | Translation; + cancelButtonText?: string | Translation | null; /** Whether or not the user can use escape or clicking the backdrop to close the dialog */ disableClose?: boolean; diff --git a/libs/components/src/disclosure/disclosure.mdx b/libs/components/src/disclosure/disclosure.mdx index 8df8e7025b8..2fcff6f5982 100644 --- a/libs/components/src/disclosure/disclosure.mdx +++ b/libs/components/src/disclosure/disclosure.mdx @@ -1,4 +1,4 @@ -import { Meta, Story, Primary, Controls } from "@storybook/addon-docs"; +import { Meta, Canvas, Primary, Controls } from "@storybook/addon-docs"; import * as stories from "./disclosure.stories"; @@ -34,7 +34,7 @@ To compose a disclosure and trigger: click button to hide this content ``` - +

diff --git a/libs/components/src/drawer/drawer.mdx b/libs/components/src/drawer/drawer.mdx index 0098ce64ea9..57d618cfe95 100644 --- a/libs/components/src/drawer/drawer.mdx +++ b/libs/components/src/drawer/drawer.mdx @@ -1,4 +1,4 @@ -import { Meta, Story, Primary, Controls } from "@storybook/addon-docs"; +import { Meta, Canvas, Primary, Controls } from "@storybook/addon-docs"; import * as stories from "./drawer.stories"; @@ -83,13 +83,13 @@ directive: Only one drawer can be open at a time, and they do not stack. If a drawer is already open, opening another will close and replace the one already open. - + ## Headless Omitting `bit-drawer-header` and `bit-drawer-body` allows for fully customizable content. - + ## Accessibility @@ -117,4 +117,4 @@ Omitting `bit-drawer-header` and `bit-drawer-body` allows for fully customizable ## Kitchen Sink - + diff --git a/libs/components/src/form-control/form-control.component.html b/libs/components/src/form-control/form-control.component.html index aed8f7e3b24..b15202b0223 100644 --- a/libs/components/src/form-control/form-control.component.html +++ b/libs/components/src/form-control/form-control.component.html @@ -9,11 +9,17 @@ > - ({{ "required" | i18n }}) + @if (required) { + ({{ "required" | i18n }}) + } - + @if (!hasError) { + + } -
- {{ displayError }} -
+@if (hasError) { +
+ {{ displayError }} +
+} diff --git a/libs/components/src/form-control/form-control.component.ts b/libs/components/src/form-control/form-control.component.ts index d22d49ac03a..690c00a9dc0 100644 --- a/libs/components/src/form-control/form-control.component.ts +++ b/libs/components/src/form-control/form-control.component.ts @@ -1,7 +1,7 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore import { coerceBooleanProperty } from "@angular/cdk/coercion"; -import { NgClass, NgIf } from "@angular/common"; +import { NgClass } from "@angular/common"; import { Component, ContentChild, HostBinding, Input } from "@angular/core"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; @@ -15,7 +15,7 @@ import { BitFormControlAbstraction } from "./form-control.abstraction"; selector: "bit-form-control", templateUrl: "form-control.component.html", standalone: true, - imports: [NgClass, TypographyDirective, NgIf, I18nPipe], + imports: [NgClass, TypographyDirective, I18nPipe], }) export class FormControlComponent { @Input() label: string; diff --git a/libs/components/src/form-control/label.component.html b/libs/components/src/form-control/label.component.html index 64ba1ce9501..2a0a57e35d8 100644 --- a/libs/components/src/form-control/label.component.html +++ b/libs/components/src/form-control/label.component.html @@ -5,10 +5,10 @@ - + @if (isInsideFormControl) { - + } - +@if (!isInsideFormControl) { - +} diff --git a/libs/components/src/form-field/error-summary.component.ts b/libs/components/src/form-field/error-summary.component.ts index f9325d8f82a..1709c3078fa 100644 --- a/libs/components/src/form-field/error-summary.component.ts +++ b/libs/components/src/form-field/error-summary.component.ts @@ -1,6 +1,6 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { NgIf } from "@angular/common"; + import { Component, Input } from "@angular/core"; import { AbstractControl, UntypedFormGroup } from "@angular/forms"; @@ -8,15 +8,15 @@ import { I18nPipe } from "@bitwarden/ui-common"; @Component({ selector: "bit-error-summary", - template: ` + template: ` @if (errorCount > 0) { {{ "fieldsNeedAttention" | i18n: errorString }} - `, + }`, host: { class: "tw-block tw-text-danger tw-mt-2", "aria-live": "assertive", }, standalone: true, - imports: [NgIf, I18nPipe], + imports: [I18nPipe], }) export class BitErrorSummary { @Input() diff --git a/libs/components/src/form-field/form-field.component.html b/libs/components/src/form-field/form-field.component.html index f3c27aecafe..bd099859608 100644 --- a/libs/components/src/form-field/form-field.component.html +++ b/libs/components/src/form-field/form-field.component.html @@ -15,63 +15,65 @@ -
-
-
-
-
-
-
-
- -
-
- -
-
- -
-
-
- - +} @else {
- +} - - - - +@switch (input.hasError) { + @case (false) { + + } + @case (true) { + + } +} diff --git a/libs/components/src/form-field/index.ts b/libs/components/src/form-field/index.ts index 613ebaf9a9d..0c45f215ec9 100644 --- a/libs/components/src/form-field/index.ts +++ b/libs/components/src/form-field/index.ts @@ -1,4 +1,5 @@ export * from "./form-field.module"; export * from "./form-field.component"; export * from "./form-field-control"; +export * from "./password-input-toggle.directive"; export * as BitValidators from "./bit-validators"; diff --git a/libs/components/src/form/forms.mdx b/libs/components/src/form/forms.mdx index fbb3a20e518..e3baf200f96 100644 --- a/libs/components/src/form/forms.mdx +++ b/libs/components/src/form/forms.mdx @@ -1,4 +1,4 @@ -import { Meta, Story, Source } from "@storybook/addon-docs"; +import { Meta, Canvas, Source } from "@storybook/addon-docs"; import * as formStories from "./form.stories"; import * as fieldStories from "../form-field/form-field.stories"; @@ -17,7 +17,7 @@ Component Library forms should always be built using [Angular Reactive Forms][re [ADR-0001][adr-0001] for a background to this decision. In practice this means that forms should always use the native `form` element and bind a `formGroup`. - +
@@ -69,25 +69,25 @@ is too long, such as info link buttons or badges. #### Default with required attribute - + #### Password Toggle - + ### Search - + ### Selects #### Searchable single select (default) - + #### Multi-select - + ### Radio group @@ -113,11 +113,11 @@ using a radio group for more than 5 options even if the options require addition #### Block - + #### Inline - + ### Checkbox @@ -140,7 +140,7 @@ If a checkbox group has more than 4 options a #### Single checkbox - + ## Accessibility diff --git a/libs/components/src/icon-button/icon-button.mdx b/libs/components/src/icon-button/icon-button.mdx index a45160d7884..85164717de7 100644 --- a/libs/components/src/icon-button/icon-button.mdx +++ b/libs/components/src/icon-button/icon-button.mdx @@ -1,4 +1,4 @@ -import { Meta, Story, Primary, Controls } from "@storybook/addon-docs"; +import { Meta, Canvas, Primary, Controls } from "@storybook/addon-docs"; import * as stories from "./icon-button.stories"; @@ -38,48 +38,48 @@ button component styles. Used for general icon buttons appearing on the theme’s main `background` - + ### Muted Used for low emphasis icon buttons appearing on the theme’s main `background` - + ### Contrast Used on a theme’s colored or contrasting backgrounds such as in the navigation or on toasts and banners. - + ### Danger Danger is used for “trash” actions throughout the experience, most commonly in the bottom right of the dialog component. - + ### Primary Used in place of the main button component if no text is used. This allows the button to display square. - + ### Secondary Used in place of the main button component if no text is used. This allows the button to display square. - + ### Light Used on a background that is dark in both light theme and dark theme. Example: end user navigation styles. - + **Note:** Main and contrast styles appear on backgrounds where using `primary-700` as a focus indicator does not meet WCAG graphic contrast guidelines. @@ -93,11 +93,11 @@ with less padding around the icon, such as in the navigation component. ### Small - + ### Default - + ## Accessibility diff --git a/libs/components/src/input/index.ts b/libs/components/src/input/index.ts index 9713d2b9192..6bd64495910 100644 --- a/libs/components/src/input/index.ts +++ b/libs/components/src/input/index.ts @@ -1,2 +1,3 @@ export * from "./input.module"; export * from "./autofocus.directive"; +export * from "./input.directive"; diff --git a/libs/components/src/item/item-content.component.html b/libs/components/src/item/item-content.component.html index 6f900c5c6e1..4010970dc9e 100644 --- a/libs/components/src/item/item-content.component.html +++ b/libs/components/src/item/item-content.component.html @@ -6,14 +6,26 @@ bitTypography="body2" class="tw-text-main tw-truncate tw-inline-flex tw-items-center tw-gap-1.5 tw-w-full" > -
+
-
+
diff --git a/libs/components/src/item/item-content.component.ts b/libs/components/src/item/item-content.component.ts index f6cc3f133ad..2a6e06291fd 100644 --- a/libs/components/src/item/item-content.component.ts +++ b/libs/components/src/item/item-content.component.ts @@ -1,11 +1,13 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { CommonModule } from "@angular/common"; + +import { NgClass } from "@angular/common"; import { AfterContentChecked, ChangeDetectionStrategy, Component, ElementRef, + Input, signal, ViewChild, } from "@angular/core"; @@ -15,7 +17,7 @@ import { TypographyModule } from "../typography"; @Component({ selector: "bit-item-content, [bit-item-content]", standalone: true, - imports: [CommonModule, TypographyModule], + imports: [TypographyModule, NgClass], templateUrl: `item-content.component.html`, host: { class: @@ -32,6 +34,13 @@ export class ItemContentComponent implements AfterContentChecked { protected endSlotHasChildren = signal(false); + /** + * Determines whether text will truncate or wrap. + * + * Default behavior is truncation. + */ + @Input() truncate = true; + ngAfterContentChecked(): void { this.endSlotHasChildren.set(this.endSlot?.nativeElement.childElementCount > 0); } diff --git a/libs/components/src/item/item.component.ts b/libs/components/src/item/item.component.ts index 97a80484373..1ef4a4af1fa 100644 --- a/libs/components/src/item/item.component.ts +++ b/libs/components/src/item/item.component.ts @@ -1,4 +1,3 @@ -import { CommonModule } from "@angular/common"; import { ChangeDetectionStrategy, Component, @@ -14,7 +13,7 @@ import { ItemActionComponent } from "./item-action.component"; @Component({ selector: "bit-item", standalone: true, - imports: [CommonModule, ItemActionComponent], + imports: [ItemActionComponent], changeDetection: ChangeDetectionStrategy.OnPush, templateUrl: "item.component.html", providers: [{ provide: A11yRowDirective, useExisting: ItemComponent }], diff --git a/libs/components/src/item/item.mdx b/libs/components/src/item/item.mdx index ca697ebb436..d3e6065487a 100644 --- a/libs/components/src/item/item.mdx +++ b/libs/components/src/item/item.mdx @@ -1,4 +1,4 @@ -import { Meta, Story, Primary, Controls } from "@storybook/addon-docs"; +import { Meta, Canvas, Primary, Controls } from "@storybook/addon-docs"; import * as stories from "./item.stories"; @@ -15,14 +15,14 @@ import { ItemModule } from "@bitwarden/components"; It is a generic container that can be used for either standalone content, an alternative to tables, or to list nav links. - +
Items used within a parent `bit-layout` component will not have a border radius, since the `bit-layout` background is white. - +

@@ -49,7 +49,7 @@ The content can be a button, anchor, or static container. ``` - + ### Content Slots @@ -82,7 +82,7 @@ The content can be a button, anchor, or static container. ``` - + ## Secondary Actions @@ -111,13 +111,37 @@ Actions are commonly icon buttons or badge buttons. ``` +## Text Overflow Behavior + +The default behavior for long text is to truncate it. However, you have the option of changing it to +wrap instead if that is what the design calls for. + +This can be changed by passing `[truncate]="false"` to the `bit-item-content`. + +```html + + + Long text goes here! + This could also be very long text + + +``` + +### Truncation (Default) + + + +### Wrap + + + ## Item Groups Groups of items can be associated by wrapping them in the ``. - + - + ### A11y @@ -138,4 +162,4 @@ Use `aria-label` or `aria-labelledby` to give groups an accessible name. ### Virtual Scrolling - + diff --git a/libs/components/src/item/item.stories.ts b/libs/components/src/item/item.stories.ts index 3a64a334d0a..fd2d59c7ac2 100644 --- a/libs/components/src/item/item.stories.ts +++ b/libs/components/src/item/item.stories.ts @@ -135,7 +135,7 @@ export const ContentTypes: Story = { }), }; -export const TextOverflow: Story = { +export const TextOverflowTruncate: Story = { render: (args) => ({ props: args, template: /*html*/ ` @@ -158,6 +158,29 @@ export const TextOverflow: Story = { }), }; +export const TextOverflowWrap: Story = { + render: (args) => ({ + props: args, + template: /*html*/ ` + + + + Helloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo! + Worlddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd! + + + + + + + + + + + `, + }), +}; + const multipleActionListTemplate = /*html*/ ` diff --git a/libs/components/src/layout/layout.component.html b/libs/components/src/layout/layout.component.html index 489a0dc876f..33b8de81572 100644 --- a/libs/components/src/layout/layout.component.html +++ b/libs/components/src/layout/layout.component.html @@ -23,19 +23,21 @@ -
+ }; + as data + ) {
-
+ class="tw-pointer-events-none tw-fixed tw-inset-0 tw-z-10 tw-bg-black tw-bg-opacity-0 motion-safe:tw-transition-colors md:tw-hidden" + [ngClass]="[data.open ? 'tw-bg-opacity-30 md:tw-bg-opacity-0' : 'tw-bg-opacity-0']" + > + @if (data.open) { +
+ } +

+ }
diff --git a/libs/components/src/menu/menu.mdx b/libs/components/src/menu/menu.mdx index 67c276cf372..d77dc0a7d7b 100644 --- a/libs/components/src/menu/menu.mdx +++ b/libs/components/src/menu/menu.mdx @@ -1,4 +1,4 @@ -import { Meta, Story, Primary, Controls } from "@storybook/addon-docs"; +import { Meta, Canvas, Primary, Controls } from "@storybook/addon-docs"; import * as stories from "./menu.stories"; @@ -9,7 +9,7 @@ import * as stories from "./menu.stories"; Menus are used to help organize related options. Menus are most often used for item options in tables. - +
diff --git a/libs/components/src/multi-select/multi-select.component.html b/libs/components/src/multi-select/multi-select.component.html index 0c45e2d333f..e157871e17a 100644 --- a/libs/components/src/multi-select/multi-select.component.html +++ b/libs/components/src/multi-select/multi-select.component.html @@ -31,7 +31,9 @@ [disabled]="disabled" (click)="clear(item)" > - + @if (item.icon != null) { + + } {{ item.labelName }} @@ -41,10 +43,14 @@
- + @if (isSelected(item)) { + + }
- + @if (item.icon != null) { + + }
{{ item.listName }} diff --git a/libs/components/src/multi-select/multi-select.component.ts b/libs/components/src/multi-select/multi-select.component.ts index 71b00404cfb..cd92eb1d7ae 100644 --- a/libs/components/src/multi-select/multi-select.component.ts +++ b/libs/components/src/multi-select/multi-select.component.ts @@ -2,7 +2,6 @@ // @ts-strict-ignore import { coerceBooleanProperty } from "@angular/cdk/coercion"; import { hasModifierKey } from "@angular/cdk/keycodes"; -import { NgIf } from "@angular/common"; import { Component, Input, @@ -39,7 +38,7 @@ let nextId = 0; templateUrl: "./multi-select.component.html", providers: [{ provide: BitFormFieldControl, useExisting: MultiSelectComponent }], standalone: true, - imports: [NgSelectModule, ReactiveFormsModule, FormsModule, BadgeModule, NgIf, I18nPipe], + imports: [NgSelectModule, ReactiveFormsModule, FormsModule, BadgeModule, I18nPipe], }) /** * This component has been implemented to only support Multi-select list events diff --git a/libs/components/src/navigation/nav-divider.component.html b/libs/components/src/navigation/nav-divider.component.html index 224f6ae0657..64e43aeab4e 100644 --- a/libs/components/src/navigation/nav-divider.component.html +++ b/libs/components/src/navigation/nav-divider.component.html @@ -1 +1,3 @@ -
+@if (sideNavService.open$ | async) { +
+} diff --git a/libs/components/src/navigation/nav-group.component.html b/libs/components/src/navigation/nav-group.component.html index 9f6d9ac034d..9752fe56eb1 100644 --- a/libs/components/src/navigation/nav-group.component.html +++ b/libs/components/src/navigation/nav-group.component.html @@ -1,5 +1,5 @@ - +@if (!hideIfEmpty || nestedNavComponents.length > 0) { - - - - - - - + @if (variant === "tree") { + + } + + + @if (variant !== "tree") { + + } - - -
- -
-
-
+ @if (sideNavService.open$ | async) { + @if (open) { +
+ +
+ } + } +} diff --git a/libs/components/src/navigation/nav-group.component.ts b/libs/components/src/navigation/nav-group.component.ts index 37244f37c8d..62bdee26740 100644 --- a/libs/components/src/navigation/nav-group.component.ts +++ b/libs/components/src/navigation/nav-group.component.ts @@ -29,6 +29,7 @@ import { SideNavService } from "./side-nav.service"; ], standalone: true, imports: [CommonModule, NavItemComponent, IconButtonModule, I18nPipe], + preserveWhitespaces: false, }) export class NavGroupComponent extends NavBaseComponent implements AfterContentInit { @ContentChildren(NavBaseComponent, { diff --git a/libs/components/src/navigation/nav-logo.component.html b/libs/components/src/navigation/nav-logo.component.html index 427e926f2d7..a6169315333 100644 --- a/libs/components/src/navigation/nav-logo.component.html +++ b/libs/components/src/navigation/nav-logo.component.html @@ -1,20 +1,23 @@ - - +@if (sideNavService.open) { +
+ + + +
+} +@if (!sideNavService.open) { + +} diff --git a/libs/components/src/navigation/nav-logo.component.ts b/libs/components/src/navigation/nav-logo.component.ts index 8a84970500c..de9d801e553 100644 --- a/libs/components/src/navigation/nav-logo.component.ts +++ b/libs/components/src/navigation/nav-logo.component.ts @@ -1,6 +1,6 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { NgIf } from "@angular/common"; + import { Component, Input } from "@angular/core"; import { RouterLinkActive, RouterLink } from "@angular/router"; @@ -14,7 +14,7 @@ import { SideNavService } from "./side-nav.service"; selector: "bit-nav-logo", templateUrl: "./nav-logo.component.html", standalone: true, - imports: [NgIf, RouterLinkActive, RouterLink, BitIconComponent, NavItemComponent], + imports: [RouterLinkActive, RouterLink, BitIconComponent, NavItemComponent], }) export class NavLogoComponent { /** Icon that is displayed when the side nav is closed */ diff --git a/libs/components/src/navigation/side-nav.component.html b/libs/components/src/navigation/side-nav.component.html index 05c99c7d64e..3b77c981be4 100644 --- a/libs/components/src/navigation/side-nav.component.html +++ b/libs/components/src/navigation/side-nav.component.html @@ -1,42 +1,46 @@ - + +} diff --git a/libs/components/src/popover/popover.mdx b/libs/components/src/popover/popover.mdx index 7b47b160ddc..17762acbdfb 100644 --- a/libs/components/src/popover/popover.mdx +++ b/libs/components/src/popover/popover.mdx @@ -1,4 +1,4 @@ -import { Meta, Story, Primary, Controls } from "@storybook/addon-docs"; +import { Meta, Canvas, Primary, Controls } from "@storybook/addon-docs"; import * as stories from "./popover.stories"; @@ -66,7 +66,7 @@ not work because there is not enough space to open the Popover to the right. The The first position that "fits" is `left-start`, and therefore that is where the Popover will open. - + ### Manually Setting a Position @@ -77,7 +77,7 @@ Popover's trigger element, such as: ``` - + Note that if the user resizes the page and the Popover no longer fits in the viewport, the Popover component will fall back to the list of default positions to find the best position. diff --git a/libs/components/src/progress/progress.component.html b/libs/components/src/progress/progress.component.html index 2637f23eee8..30b68d9d645 100644 --- a/libs/components/src/progress/progress.component.html +++ b/libs/components/src/progress/progress.component.html @@ -7,13 +7,12 @@ attr.aria-valuenow="{{ barWidth }}" [ngStyle]="{ width: barWidth + '%' }" > -
- -
 
-
{{ textContent }}
-
+ @if (displayText) { +
+ +
 
+
{{ textContent }}
+
+ }
diff --git a/libs/components/src/progress/progress.mdx b/libs/components/src/progress/progress.mdx index 185d6214f1f..9a75f8ae1fa 100644 --- a/libs/components/src/progress/progress.mdx +++ b/libs/components/src/progress/progress.mdx @@ -1,4 +1,4 @@ -import { Meta, Story, Primary, Controls } from "@storybook/addon-docs"; +import { Meta, Canvas, Primary, Controls } from "@storybook/addon-docs"; import * as stories from "./progress.stories"; @@ -19,14 +19,14 @@ allows those who may not be familiar with the pattern to be able to read and dig It also allows assistive technology to accurately describe the indicator to those who may be unable to see part or all of the indicator. - + ## Text label When measuring something other than progress, such as password strength, update the label to fit the context of the implementation. - + ### Strength indicator styles diff --git a/libs/components/src/radio-button/radio-group.component.html b/libs/components/src/radio-button/radio-group.component.html index 128a723d461..b71abd9249c 100644 --- a/libs/components/src/radio-button/radio-group.component.html +++ b/libs/components/src/radio-button/radio-group.component.html @@ -1,16 +1,18 @@ - +@if (label) {
- ({{ "required" | i18n }}) + @if (required) { + ({{ "required" | i18n }}) + }
-
+} - +@if (!label) { - +}
diff --git a/libs/components/src/radio-button/radio-group.component.ts b/libs/components/src/radio-button/radio-group.component.ts index 4ab626f7964..895f769af50 100644 --- a/libs/components/src/radio-button/radio-group.component.ts +++ b/libs/components/src/radio-button/radio-group.component.ts @@ -1,6 +1,6 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { NgIf, NgTemplateOutlet } from "@angular/common"; +import { NgTemplateOutlet } from "@angular/common"; import { Component, ContentChild, HostBinding, Input, Optional, Self } from "@angular/core"; import { ControlValueAccessor, NgControl, Validators } from "@angular/forms"; @@ -14,7 +14,7 @@ let nextId = 0; selector: "bit-radio-group", templateUrl: "radio-group.component.html", standalone: true, - imports: [NgIf, NgTemplateOutlet, I18nPipe], + imports: [NgTemplateOutlet, I18nPipe], }) export class RadioGroupComponent implements ControlValueAccessor { selected: unknown; diff --git a/libs/components/src/section/section.mdx b/libs/components/src/section/section.mdx index 52672ad59fb..92798420479 100644 --- a/libs/components/src/section/section.mdx +++ b/libs/components/src/section/section.mdx @@ -1,4 +1,4 @@ -import { Meta, Story, Primary, Controls, Canvas } from "@storybook/addon-docs"; +import { Meta, Primary, Controls, Canvas } from "@storybook/addon-docs"; import * as stories from "./section.stories"; @@ -26,9 +26,7 @@ the `disableMargin` input. ``` - - - + ## Section Header @@ -61,16 +59,12 @@ padding to align the header with the border radius of the card/item. ``` - - - + If placed inside of a section without a `bit-card` or `bit-item`, or with a `bit-card`/`bit-item` that is not a descendant of the immediate next sibling, the padding is not applied. - - - + ### Section Header Content Slots @@ -89,14 +83,10 @@ Anything passed to the default slot will display as part of the title. The title Title suffixes (typically an icon or icon button) can be added as well. A gap is automatically applied between the children of the default slot. - - - + #### End slot The `end` slot will typically be used for text or an icon button. - - - + diff --git a/libs/components/src/select/select.component.html b/libs/components/src/select/select.component.html index 848692526a1..dcca7ae195e 100644 --- a/libs/components/src/select/select.component.html +++ b/libs/components/src/select/select.component.html @@ -13,7 +13,9 @@
- + @if (item.icon != null) { + + }
{{ item.label }} diff --git a/libs/components/src/select/select.component.ts b/libs/components/src/select/select.component.ts index 8f75c5be42b..a89eb87f54b 100644 --- a/libs/components/src/select/select.component.ts +++ b/libs/components/src/select/select.component.ts @@ -1,6 +1,6 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { NgIf } from "@angular/common"; + import { Component, ContentChildren, @@ -36,7 +36,7 @@ let nextId = 0; templateUrl: "select.component.html", providers: [{ provide: BitFormFieldControl, useExisting: SelectComponent }], standalone: true, - imports: [NgSelectModule, ReactiveFormsModule, FormsModule, NgIf], + imports: [NgSelectModule, ReactiveFormsModule, FormsModule], }) export class SelectComponent implements BitFormFieldControl, ControlValueAccessor { @ViewChild(NgSelectComponent) select: NgSelectComponent; diff --git a/libs/components/src/stories/colors.mdx b/libs/components/src/stories/colors.mdx index 22079dfcbf7..3a4a4f0fe3a 100644 --- a/libs/components/src/stories/colors.mdx +++ b/libs/components/src/stories/colors.mdx @@ -13,7 +13,7 @@ export const Table = (args) => ( - + @@ -119,6 +119,4 @@ Below are all the permited colors. Please consult design before considering addi
General usageGeneral usage
-
-
diff --git a/libs/components/src/stories/compact-mode.mdx b/libs/components/src/stories/compact-mode.mdx index 800bc34cf6a..3cffd45847a 100644 --- a/libs/components/src/stories/compact-mode.mdx +++ b/libs/components/src/stories/compact-mode.mdx @@ -1,4 +1,4 @@ -import { Meta, Story } from "@storybook/addon-docs"; +import { Meta, Story, Canvas } from "@storybook/addon-docs"; import * as itemStories from "../item/item.stories"; import * as popupLayoutStories from "../../../../apps/browser/src/platform/popup/layout/popup-layout.stories"; @@ -42,4 +42,4 @@ However, styling with the Tailwind variant should be used when possible as it is ### [Item](?path=/story/component-library-item--compact-mode) - + diff --git a/libs/components/src/stories/kitchen-sink/components/kitchen-sink-form.component.ts b/libs/components/src/stories/kitchen-sink/components/kitchen-sink-form.component.ts index c63b36ea89c..5fc01d37d53 100644 --- a/libs/components/src/stories/kitchen-sink/components/kitchen-sink-form.component.ts +++ b/libs/components/src/stories/kitchen-sink/components/kitchen-sink-form.component.ts @@ -49,11 +49,9 @@ import { KitchenSinkSharedModule } from "../kitchen-sink-shared.module"; Your favorite color - + @for (color of colors; track color) { + + } diff --git a/libs/components/src/stories/kitchen-sink/components/kitchen-sink-main.component.ts b/libs/components/src/stories/kitchen-sink/components/kitchen-sink-main.component.ts index 568c78566f6..fd682bd1515 100644 --- a/libs/components/src/stories/kitchen-sink/components/kitchen-sink-main.component.ts +++ b/libs/components/src/stories/kitchen-sink/components/kitchen-sink-main.component.ts @@ -36,9 +36,11 @@ class KitchenSinkDialog {

- - {{ item.name }} - + @for (item of navItems; track item) { + + {{ item.name }} + + }

@@ -54,12 +56,6 @@ class KitchenSinkDialog { isolated stories. The stories for the Kitchen Sink exist to be tested by the Chromatic UI tests.

- -

- NOTE: These stories will treat "Light & Dark" mode as "Light" mode. This is done to avoid a - bug with the way that we render the same component twice in the same iframe and how that - interacts with the router-outlet. -

diff --git a/libs/components/src/stories/kitchen-sink/components/kitchen-sink-toggle-list.component.ts b/libs/components/src/stories/kitchen-sink/components/kitchen-sink-toggle-list.component.ts index 6f0054912cf..c71140d8166 100644 --- a/libs/components/src/stories/kitchen-sink/components/kitchen-sink-toggle-list.component.ts +++ b/libs/components/src/stories/kitchen-sink/components/kitchen-sink-toggle-list.component.ts @@ -16,11 +16,15 @@ import { KitchenSinkSharedModule } from "../kitchen-sink-shared.module"; Mid-sized 1 -
    -
  • - {{ company.name }} -
  • -
+ @for (company of companyList; track company) { +
    + @if (company.size === selectedToggle || selectedToggle === "all") { +
  • + {{ company.name }} +
  • + } +
+ } `, }) export class KitchenSinkToggleList { diff --git a/libs/components/src/stories/kitchen-sink/kitchen-sink.mdx b/libs/components/src/stories/kitchen-sink/kitchen-sink.mdx index 49493f749ee..34e80081887 100644 --- a/libs/components/src/stories/kitchen-sink/kitchen-sink.mdx +++ b/libs/components/src/stories/kitchen-sink/kitchen-sink.mdx @@ -9,7 +9,3 @@ import * as stories from "./kitchen-sink.stories"; The purpose of this story is to compose together all of our components. When snapshot tests run, we'll be able to spot-check visual changes in a more app-like environment than just the isolated stories. The stories for the Kitchen Sink exist to be tested by the Chromatic UI tests. - -NOTE: These stories will treat "Light & Dark" mode as "Light" mode. This is done to avoid a bug with -the way that we render the same component twice in the same iframe and how that interacts with the -`router-outlet`. diff --git a/libs/components/src/stories/storybook-decorators.ts b/libs/components/src/stories/storybook-decorators.ts index d59f2dd1f3e..ec0df264c7e 100644 --- a/libs/components/src/stories/storybook-decorators.ts +++ b/libs/components/src/stories/storybook-decorators.ts @@ -12,7 +12,7 @@ export const positionFixedWrapperDecorator = (wrapper?: (story: string) => strin */ (story) => /* HTML */ `
${wrapper ? wrapper(story) : story}
`, diff --git a/libs/components/src/tabs/tab-group/tab-group.component.html b/libs/components/src/tabs/tab-group/tab-group.component.html index 071f5c2259f..52fa193de96 100644 --- a/libs/components/src/tabs/tab-group/tab-group.component.html +++ b/libs/components/src/tabs/tab-group/tab-group.component.html @@ -5,40 +5,41 @@ [attr.aria-label]="label" (keydown)="keyManager.onKeydown($event)" > - + + }
- - + @for (tab of tabs; track tab; let i = $index) { + + + }
diff --git a/libs/components/src/tabs/tab-group/tab-group.component.ts b/libs/components/src/tabs/tab-group/tab-group.component.ts index 54d00343b38..b525b9b6723 100644 --- a/libs/components/src/tabs/tab-group/tab-group.component.ts +++ b/libs/components/src/tabs/tab-group/tab-group.component.ts @@ -2,7 +2,7 @@ // @ts-strict-ignore import { FocusKeyManager } from "@angular/cdk/a11y"; import { coerceNumberProperty } from "@angular/cdk/coercion"; -import { CommonModule } from "@angular/common"; +import { NgTemplateOutlet } from "@angular/common"; import { AfterContentChecked, AfterContentInit, @@ -33,7 +33,7 @@ let nextId = 0; templateUrl: "./tab-group.component.html", standalone: true, imports: [ - CommonModule, + NgTemplateOutlet, TabHeaderComponent, TabListContainerDirective, TabListItemDirective, diff --git a/libs/components/src/tabs/tabs.mdx b/libs/components/src/tabs/tabs.mdx index 3be98e34257..bab5fbb52c4 100644 --- a/libs/components/src/tabs/tabs.mdx +++ b/libs/components/src/tabs/tabs.mdx @@ -1,6 +1,7 @@ -import { Meta, Story, Primary, Controls } from "@storybook/addon-docs"; +import { Meta, Canvas, Primary, Controls } from "@storybook/addon-docs"; import * as stories from "./tabs.stories"; +import * as dialogStories from "../dialog/dialog/dialog.stories"; @@ -17,17 +18,17 @@ and 1rem of padding on the left and right. ## Content Tabs - + ## Navigation Tabs - + ## Content tabs in dialogs Tabs can be used in dialogs to separate related content. - + ## Accessibility diff --git a/libs/components/src/toast/toast-container.component.html b/libs/components/src/toast/toast-container.component.html new file mode 100644 index 00000000000..8896f7e953d --- /dev/null +++ b/libs/components/src/toast/toast-container.component.html @@ -0,0 +1 @@ +
diff --git a/libs/components/src/toast/toast-container.component.ts b/libs/components/src/toast/toast-container.component.ts new file mode 100644 index 00000000000..1cd33f67ac7 --- /dev/null +++ b/libs/components/src/toast/toast-container.component.ts @@ -0,0 +1,19 @@ +import { Component, OnInit, ViewChild } from "@angular/core"; +import { ToastContainerDirective, ToastrService } from "ngx-toastr"; + +@Component({ + selector: "bit-toast-container", + templateUrl: "toast-container.component.html", + standalone: true, + imports: [ToastContainerDirective], +}) +export class ToastContainerComponent implements OnInit { + @ViewChild(ToastContainerDirective, { static: true }) + toastContainer?: ToastContainerDirective; + + constructor(private toastrService: ToastrService) {} + + ngOnInit(): void { + this.toastrService.overlayContainer = this.toastContainer; + } +} diff --git a/libs/components/src/toast/toast.component.html b/libs/components/src/toast/toast.component.html index 84154cba611..bdbc9674184 100644 --- a/libs/components/src/toast/toast.component.html +++ b/libs/components/src/toast/toast.component.html @@ -2,20 +2,20 @@ class="tw-mb-1 tw-min-w-[--bit-toast-width] tw-text-main tw-flex tw-flex-col tw-justify-between tw-rounded-md tw-pointer-events-auto tw-cursor-default tw-overflow-hidden tw-shadow-lg {{ bgColor }}" + [attr.role]="variant === 'error' ? 'alert' : null" >
{{ variant | i18n }} -

{{ title }}

-

- {{ m }} -

+ @if (title) { +

{{ title }}

+ } + @for (m of messageArray; track m) { +

+ {{ m }} +

+ }
- - diff --git a/libs/tools/generator/components/src/credential-generator-history-dialog.component.ts b/libs/tools/generator/components/src/credential-generator-history-dialog.component.ts index 7bcffd92399..58da1157f7c 100644 --- a/libs/tools/generator/components/src/credential-generator-history-dialog.component.ts +++ b/libs/tools/generator/components/src/credential-generator-history-dialog.component.ts @@ -1,6 +1,5 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { DialogRef } from "@angular/cdk/dialog"; import { CommonModule } from "@angular/common"; import { Component } from "@angular/core"; import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; @@ -35,7 +34,6 @@ export class CredentialGeneratorHistoryDialogComponent { private accountService: AccountService, private history: GeneratorHistoryService, private dialogService: DialogService, - private dialogRef: DialogRef, ) { this.accountService.activeAccount$ .pipe( @@ -54,11 +52,6 @@ export class CredentialGeneratorHistoryDialogComponent { .subscribe(this.hasHistory$); } - /** closes the dialog */ - protected close() { - this.dialogRef.close(); - } - /** Launches clear history flow */ protected async clear() { const confirmed = await this.dialogService.openSimpleDialog({ diff --git a/libs/tools/generator/components/src/generator-services.module.ts b/libs/tools/generator/components/src/generator-services.module.ts index a4e751095d4..f60f4c5b095 100644 --- a/libs/tools/generator/components/src/generator-services.module.ts +++ b/libs/tools/generator/components/src/generator-services.module.ts @@ -6,7 +6,7 @@ import { SafeInjectionToken } from "@bitwarden/angular/services/injection-tokens import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { StateProvider } from "@bitwarden/common/platform/state"; import { KeyServiceLegacyEncryptorProvider } from "@bitwarden/common/tools/cryptography/key-service-legacy-encryptor-provider"; diff --git a/libs/tools/generator/core/src/strategies/forwarder-generator-strategy.spec.ts b/libs/tools/generator/core/src/strategies/forwarder-generator-strategy.spec.ts index f57a1e5f2b6..99834a25417 100644 --- a/libs/tools/generator/core/src/strategies/forwarder-generator-strategy.spec.ts +++ b/libs/tools/generator/core/src/strategies/forwarder-generator-strategy.spec.ts @@ -5,7 +5,7 @@ import { PolicyType } from "@bitwarden/common/admin-console/enums"; // FIXME: use index.ts imports once policy abstractions and models // implement ADR-0002 import { Policy } from "@bitwarden/common/admin-console/models/domain/policy"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { RestClient } from "@bitwarden/common/tools/integration/rpc"; import { BufferedState } from "@bitwarden/common/tools/state/buffered-state"; diff --git a/libs/tools/generator/core/src/strategies/forwarder-generator-strategy.ts b/libs/tools/generator/core/src/strategies/forwarder-generator-strategy.ts index c4282173817..1914b27697b 100644 --- a/libs/tools/generator/core/src/strategies/forwarder-generator-strategy.ts +++ b/libs/tools/generator/core/src/strategies/forwarder-generator-strategy.ts @@ -4,7 +4,7 @@ import { filter, map } from "rxjs"; import { Jsonify } from "type-fest"; import { PolicyType } from "@bitwarden/common/admin-console/enums"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { SingleUserState, StateProvider } from "@bitwarden/common/platform/state"; import { UserKeyEncryptor } from "@bitwarden/common/tools/cryptography/user-key-encryptor"; diff --git a/libs/tools/generator/extensions/history/src/legacy-password-history-decryptor.ts b/libs/tools/generator/extensions/history/src/legacy-password-history-decryptor.ts index 6a27ad476ae..06113ee9b99 100644 --- a/libs/tools/generator/extensions/history/src/legacy-password-history-decryptor.ts +++ b/libs/tools/generator/extensions/history/src/legacy-password-history-decryptor.ts @@ -1,4 +1,4 @@ -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { UserId } from "@bitwarden/common/types/guid"; import { KeyService } from "@bitwarden/key-management"; diff --git a/libs/tools/generator/extensions/history/src/local-generator-history.service.spec.ts b/libs/tools/generator/extensions/history/src/local-generator-history.service.spec.ts index 3936b03acc9..b3dee69bdbf 100644 --- a/libs/tools/generator/extensions/history/src/local-generator-history.service.spec.ts +++ b/libs/tools/generator/extensions/history/src/local-generator-history.service.spec.ts @@ -1,7 +1,7 @@ import { mock } from "jest-mock-extended"; import { firstValueFrom, of } from "rxjs"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { CsprngArray } from "@bitwarden/common/types/csprng"; diff --git a/libs/tools/generator/extensions/history/src/local-generator-history.service.ts b/libs/tools/generator/extensions/history/src/local-generator-history.service.ts index 149a83db42f..cbfa55a184f 100644 --- a/libs/tools/generator/extensions/history/src/local-generator-history.service.ts +++ b/libs/tools/generator/extensions/history/src/local-generator-history.service.ts @@ -2,7 +2,7 @@ // @ts-strict-ignore import { filter, map } from "rxjs"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { SingleUserState, StateProvider } from "@bitwarden/common/platform/state"; import { UserKeyEncryptor } from "@bitwarden/common/tools/cryptography/user-key-encryptor"; import { BufferedState } from "@bitwarden/common/tools/state/buffered-state"; diff --git a/libs/tools/generator/extensions/legacy/src/create-legacy-password-generation-service.ts b/libs/tools/generator/extensions/legacy/src/create-legacy-password-generation-service.ts index ae6b74564e3..0df37617b88 100644 --- a/libs/tools/generator/extensions/legacy/src/create-legacy-password-generation-service.ts +++ b/libs/tools/generator/extensions/legacy/src/create-legacy-password-generation-service.ts @@ -2,7 +2,7 @@ // @ts-strict-ignore import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { StateProvider } from "@bitwarden/common/platform/state"; import { engine, services, strategies } from "@bitwarden/generator-core"; import { LocalGeneratorHistoryService } from "@bitwarden/generator-history"; diff --git a/libs/tools/generator/extensions/legacy/src/create-legacy-username-generation-service.ts b/libs/tools/generator/extensions/legacy/src/create-legacy-username-generation-service.ts index c995fb1bce1..36b4a20aec7 100644 --- a/libs/tools/generator/extensions/legacy/src/create-legacy-username-generation-service.ts +++ b/libs/tools/generator/extensions/legacy/src/create-legacy-username-generation-service.ts @@ -3,7 +3,7 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { StateProvider } from "@bitwarden/common/platform/state"; import { RestClient } from "@bitwarden/common/tools/integration/rpc"; diff --git a/libs/vault/src/abstractions/change-login-password.service.ts b/libs/vault/src/abstractions/change-login-password.service.ts new file mode 100644 index 00000000000..c89162d42be --- /dev/null +++ b/libs/vault/src/abstractions/change-login-password.service.ts @@ -0,0 +1,10 @@ +import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; + +export abstract class ChangeLoginPasswordService { + /** + * Attempts to find a well-known change password URL for the given cipher. Only works for Login ciphers with at + * least one http/https URL. If no well-known change password URL is found, the first URL is returned. + * Non-Login ciphers and Logins with no valid http/https URLs return null. + */ + abstract getChangePasswordUrl(cipher: CipherView): Promise; +} diff --git a/libs/vault/src/cipher-form/components/attachments/cipher-attachments.component.spec.ts b/libs/vault/src/cipher-form/components/attachments/cipher-attachments.component.spec.ts index 1ee9a985f5a..ce12ca95e1e 100644 --- a/libs/vault/src/cipher-form/components/attachments/cipher-attachments.component.spec.ts +++ b/libs/vault/src/cipher-form/components/attachments/cipher-attachments.component.spec.ts @@ -110,7 +110,7 @@ describe("CipherAttachmentsComponent", () => { it("fetches cipherView using `cipherId`", async () => { await component.ngOnInit(); - expect(cipherServiceGet).toHaveBeenCalledWith("5555-444-3333"); + expect(cipherServiceGet).toHaveBeenCalledWith("5555-444-3333", mockUserId); expect(component.cipher).toEqual(cipherView); }); diff --git a/libs/vault/src/cipher-form/components/attachments/cipher-attachments.component.ts b/libs/vault/src/cipher-form/components/attachments/cipher-attachments.component.ts index e366cdab3fe..7e26e8afae9 100644 --- a/libs/vault/src/cipher-form/components/attachments/cipher-attachments.component.ts +++ b/libs/vault/src/cipher-form/components/attachments/cipher-attachments.component.ts @@ -21,10 +21,11 @@ import { ReactiveFormsModule, Validators, } from "@angular/forms"; -import { firstValueFrom, map } from "rxjs"; +import { firstValueFrom } 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 { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { CipherId, UserId } from "@bitwarden/common/types/guid"; @@ -118,10 +119,8 @@ export class CipherAttachmentsComponent implements OnInit, AfterViewInit { } async ngOnInit(): Promise { - this.cipherDomain = await this.cipherService.get(this.cipherId); - this.activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), - ); + this.activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + this.cipherDomain = await this.cipherService.get(this.cipherId, this.activeUserId); this.cipher = await this.cipherDomain.decrypt( await this.cipherService.getKeyForCipherKeyDecryption(this.cipherDomain, this.activeUserId), ); diff --git a/libs/vault/src/cipher-form/components/attachments/delete-attachment/delete-attachment.component.spec.ts b/libs/vault/src/cipher-form/components/attachments/delete-attachment/delete-attachment.component.spec.ts index 8e0d4f7a665..4442fa6e75d 100644 --- a/libs/vault/src/cipher-form/components/attachments/delete-attachment/delete-attachment.component.spec.ts +++ b/libs/vault/src/cipher-form/components/attachments/delete-attachment/delete-attachment.component.spec.ts @@ -2,12 +2,16 @@ import { ComponentFixture, TestBed } from "@angular/core/testing"; import { By } from "@angular/platform-browser"; import { mock } from "jest-mock-extended"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; +import { UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { AttachmentView } from "@bitwarden/common/vault/models/view/attachment.view"; import { DialogService, ToastService } from "@bitwarden/components"; +import { mockAccountServiceWith } from "../../../../../../common/spec"; + import { DeleteAttachmentComponent } from "./delete-attachment.component"; describe("DeleteAttachmentComponent", () => { @@ -42,6 +46,7 @@ describe("DeleteAttachmentComponent", () => { }, { provide: I18nService, useValue: { t: (key: string) => key } }, { provide: LogService, useValue: mock() }, + { provide: AccountService, useValue: mockAccountServiceWith("UserId" as UserId) }, ], }) .overrideProvider(DialogService, { @@ -90,7 +95,11 @@ describe("DeleteAttachmentComponent", () => { }); // Called with cipher id and attachment id - expect(deleteAttachmentWithServer).toHaveBeenCalledWith("5555-444-3333", "222-3333-4444"); + expect(deleteAttachmentWithServer).toHaveBeenCalledWith( + "5555-444-3333", + "222-3333-4444", + "UserId", + ); }); it("shows toast message on successful deletion", async () => { diff --git a/libs/vault/src/cipher-form/components/attachments/delete-attachment/delete-attachment.component.ts b/libs/vault/src/cipher-form/components/attachments/delete-attachment/delete-attachment.component.ts index b1ada907b1d..d7d6b550665 100644 --- a/libs/vault/src/cipher-form/components/attachments/delete-attachment/delete-attachment.component.ts +++ b/libs/vault/src/cipher-form/components/attachments/delete-attachment/delete-attachment.component.ts @@ -1,7 +1,10 @@ import { CommonModule } from "@angular/common"; import { Component, EventEmitter, Input, Output } from "@angular/core"; +import { firstValueFrom } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { getOptionalUserId } from "@bitwarden/common/auth/services/account.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; @@ -36,6 +39,7 @@ export class DeleteAttachmentComponent { private cipherService: CipherService, private logService: LogService, private dialogService: DialogService, + private accountService: AccountService, ) {} delete = async () => { @@ -50,7 +54,19 @@ export class DeleteAttachmentComponent { } try { - await this.cipherService.deleteAttachmentWithServer(this.cipherId, this.attachment.id); + const activeUserId = await firstValueFrom( + this.accountService.activeAccount$.pipe(getOptionalUserId), + ); + + if (activeUserId == null) { + throw new Error("An active user is expected while deleting an attachment."); + } + + await this.cipherService.deleteAttachmentWithServer( + this.cipherId, + this.attachment.id, + activeUserId, + ); this.toastService.showToast({ variant: "success", diff --git a/libs/vault/src/cipher-form/components/custom-fields/custom-fields.component.spec.ts b/libs/vault/src/cipher-form/components/custom-fields/custom-fields.component.spec.ts index 945f56821d2..d84387d1564 100644 --- a/libs/vault/src/cipher-form/components/custom-fields/custom-fields.component.spec.ts +++ b/libs/vault/src/cipher-form/components/custom-fields/custom-fields.component.spec.ts @@ -17,11 +17,8 @@ import { } from "@bitwarden/common/vault/enums"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { FieldView } from "@bitwarden/common/vault/models/view/field.view"; -import { DialogService } from "@bitwarden/components"; +import { BitPasswordInputToggleDirective, DialogService } from "@bitwarden/components"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { BitPasswordInputToggleDirective } from "../../../../../components/src/form-field/password-input-toggle.directive"; import { CipherFormConfig } from "../../abstractions/cipher-form-config.service"; import { CipherFormContainer } from "../../cipher-form-container"; @@ -115,7 +112,13 @@ describe("CustomFieldsComponent", () => { value: true, newField: false, }, - { linkedId: 1, name: "linked label", type: FieldType.Linked, value: null, newField: false }, + { + linkedId: 1, + name: "linked label", + type: FieldType.Linked, + value: null, + newField: false, + }, ]); }); @@ -132,6 +135,19 @@ describe("CustomFieldsComponent", () => { expect(button).toBeFalsy(); }); + it("should disable the hidden field input when `viewPassword` is false", () => { + originalCipherView.viewPassword = false; + originalCipherView.fields = mockFieldViews; + + component.ngOnInit(); + + fixture.detectChanges(); + + const input = fixture.debugElement.query(By.css('[data-testid="custom-hidden-field"]')); + + expect(input.nativeElement.disabled).toBe(true); + }); + it("when `viewPassword` is true the user can see the view toggle option", () => { originalCipherView.viewPassword = true; originalCipherView.fields = mockFieldViews; diff --git a/libs/vault/src/cipher-form/components/custom-fields/custom-fields.component.ts b/libs/vault/src/cipher-form/components/custom-fields/custom-fields.component.ts index f17432a993b..bdb96f4327d 100644 --- a/libs/vault/src/cipher-form/components/custom-fields/custom-fields.component.ts +++ b/libs/vault/src/cipher-form/components/custom-fields/custom-fields.component.ts @@ -127,8 +127,9 @@ export class CustomFieldsComponent implements OnInit, AfterViewInit { this.destroyed$ = inject(DestroyRef); this.cipherFormContainer.registerChildForm("customFields", this.customFieldsForm); - this.customFieldsForm.valueChanges.pipe(takeUntilDestroyed()).subscribe((values) => { - this.updateCipher(values.fields); + this.customFieldsForm.valueChanges.pipe(takeUntilDestroyed()).subscribe(() => { + // getRawValue ensures disabled fields are included + this.updateCipher(this.fields.getRawValue()); }); } @@ -151,27 +152,30 @@ export class CustomFieldsComponent implements OnInit, AfterViewInit { const prefillCipher = this.cipherFormContainer.getInitialCipherView(); // When available, populate the form with the existing fields - prefillCipher.fields?.forEach((field) => { + prefillCipher?.fields?.forEach((field) => { let value: string | boolean = field.value; if (field.type === FieldType.Boolean) { value = field.value === "true" ? true : false; } - this.fields.push( - this.formBuilder.group({ - type: field.type, - name: field.name, - value: value, - linkedId: field.linkedId, - newField: false, - }), - ); - }); + const customField = this.formBuilder.group({ + type: field.type, + name: field.name, + value: value, + linkedId: field.linkedId, + newField: false, + }); - if (!this.cipherFormContainer.originalCipherView?.viewPassword) { - this.customFieldsForm.disable(); - } + if ( + field.type === FieldType.Hidden && + !this.cipherFormContainer.originalCipherView?.viewPassword + ) { + customField.controls.value.disable(); + } + + this.fields.push(customField); + }); // Disable the form if in partial-edit mode // Must happen after the initial fields are populated diff --git a/libs/vault/src/cipher-form/components/item-details/item-details-section.component.html b/libs/vault/src/cipher-form/components/item-details/item-details-section.component.html index 648539932de..9750983bba1 100644 --- a/libs/vault/src/cipher-form/components/item-details/item-details-section.component.html +++ b/libs/vault/src/cipher-form/components/item-details/item-details-section.component.html @@ -61,8 +61,8 @@ formControlName="collectionIds" [baseItems]="collectionOptions" > - - {{ "cannotRemoveViewOnlyCollections" | i18n: readOnlyCollections.join(", ") }} + + {{ "cannotRemoveViewOnlyCollections" | i18n: readOnlyCollectionsNames.join(", ") }} diff --git a/libs/vault/src/cipher-form/components/item-details/item-details-section.component.spec.ts b/libs/vault/src/cipher-form/components/item-details/item-details-section.component.spec.ts index 26f967e4a53..3995422944c 100644 --- a/libs/vault/src/cipher-form/components/item-details/item-details-section.component.spec.ts +++ b/libs/vault/src/cipher-form/components/item-details/item-details-section.component.spec.ts @@ -17,6 +17,29 @@ import { CipherFormContainer } from "../../cipher-form-container"; import { ItemDetailsSectionComponent } from "./item-details-section.component"; +const createMockCollection = ( + id: string, + name: string, + organizationId: string, + readOnly = false, + canEdit = true, +) => { + return { + id, + name, + organizationId, + externalId: "", + readOnly, + hidePasswords: false, + manage: true, + assigned: true, + canEditItems: jest.fn().mockReturnValue(canEdit), + canEdit: jest.fn(), + canDelete: jest.fn(), + canViewCollectionInfo: jest.fn(), + }; +}; + describe("ItemDetailsSectionComponent", () => { let component: ItemDetailsSectionComponent; let fixture: ComponentFixture; @@ -94,13 +117,7 @@ describe("ItemDetailsSectionComponent", () => { component.config.allowPersonalOwnership = true; component.config.organizations = [{ id: "org1" } as Organization]; component.config.collections = [ - { - id: "col1", - name: "Collection 1", - organizationId: "org1", - assigned: true, - readOnly: false, - } as CollectionView, + createMockCollection("col1", "Collection 1", "org1") as CollectionView, ]; getInitialCipherView.mockReturnValueOnce({ @@ -343,8 +360,8 @@ describe("ItemDetailsSectionComponent", () => { component.config.allowPersonalOwnership = true; component.config.organizations = [{ id: "org1" } as Organization]; component.config.collections = [ - { id: "col1", name: "Collection 1", organizationId: "org1" } as CollectionView, - { id: "col2", name: "Collection 2", organizationId: "org1" } as CollectionView, + createMockCollection("col1", "Collection 1", "org1") as CollectionView, + createMockCollection("col2", "Collection 2", "org1") as CollectionView, ]; fixture.detectChanges(); @@ -374,27 +391,9 @@ describe("ItemDetailsSectionComponent", () => { }); component.config.organizations = [{ id: "org1" } as Organization]; component.config.collections = [ - { - id: "col1", - name: "Collection 1", - organizationId: "org1", - assigned: true, - readOnly: false, - } as CollectionView, - { - id: "col2", - name: "Collection 2", - organizationId: "org1", - assigned: true, - readOnly: false, - } as CollectionView, - { - id: "col3", - name: "Collection 3", - organizationId: "org1", - assigned: true, - readOnly: false, - } as CollectionView, + createMockCollection("col1", "Collection 1", "org1") as CollectionView, + createMockCollection("col2", "Collection 2", "org1") as CollectionView, + createMockCollection("col3", "Collection 3", "org1") as CollectionView, ]; fixture.detectChanges(); @@ -412,13 +411,7 @@ describe("ItemDetailsSectionComponent", () => { component.config.allowPersonalOwnership = true; component.config.organizations = [{ id: "org1" } as Organization]; component.config.collections = [ - { - id: "col1", - name: "Collection 1", - organizationId: "org1", - assigned: true, - readOnly: false, - } as CollectionView, + createMockCollection("col1", "Collection 1", "org1") as CollectionView, ]; fixture.detectChanges(); @@ -452,27 +445,9 @@ describe("ItemDetailsSectionComponent", () => { } as CipherView; component.config.organizations = [{ id: "org1" } as Organization]; component.config.collections = [ - { - id: "col1", - name: "Collection 1", - organizationId: "org1", - assigned: true, - readOnly: false, - } as CollectionView, - { - id: "col2", - name: "Collection 2", - organizationId: "org1", - assigned: true, - readOnly: false, - } as CollectionView, - { - id: "col3", - name: "Collection 3", - organizationId: "org1", - readOnly: true, - assigned: true, - } as CollectionView, + createMockCollection("col1", "Collection 1", "org1", true, false) as CollectionView, + createMockCollection("col2", "Collection 2", "org1", true, false) as CollectionView, + createMockCollection("col3", "Collection 3", "org1", true) as CollectionView, ]; await component.ngOnInit(); @@ -490,27 +465,9 @@ describe("ItemDetailsSectionComponent", () => { component.config.allowPersonalOwnership = true; component.config.organizations = [{ id: "org1" } as Organization]; component.config.collections = [ - { - id: "col1", - name: "Collection 1", - organizationId: "org1", - readOnly: true, - assigned: false, - } as CollectionView, - { - id: "col2", - name: "Collection 2", - organizationId: "org1", - readOnly: true, - assigned: false, - } as CollectionView, - { - id: "col3", - name: "Collection 3", - organizationId: "org1", - readOnly: false, - assigned: true, - } as CollectionView, + createMockCollection("col1", "Collection 1", "org1", true, false) as CollectionView, + createMockCollection("col2", "Collection 2", "org1", true, false) as CollectionView, + createMockCollection("col3", "Collection 3", "org1", false, false) as CollectionView, ]; fixture.detectChanges(); @@ -527,26 +484,9 @@ describe("ItemDetailsSectionComponent", () => { component.config.mode = "edit"; component.config.admin = true; component.config.collections = [ - { - id: "col1", - name: "Collection 1", - organizationId: "org1", - readOnly: true, - assigned: false, - } as CollectionView, - { - id: "col2", - name: "Collection 2", - organizationId: "org1", - assigned: false, - } as CollectionView, - { - id: "col3", - name: "Collection 3", - organizationId: "org1", - readOnly: true, - assigned: false, - } as CollectionView, + createMockCollection("col1", "Collection 1", "org1", true, false) as CollectionView, + createMockCollection("col2", "Collection 2", "org1", false, true) as CollectionView, + createMockCollection("col3", "Collection 3", "org1", true, false) as CollectionView, ]; component.originalCipherView = { name: "cipher1", @@ -562,6 +502,7 @@ describe("ItemDetailsSectionComponent", () => { }); it("should not show collections as readonly when `config.admin` is true", async () => { + component.config.isAdminConsole = true; await component.ngOnInit(); fixture.detectChanges(); @@ -573,8 +514,7 @@ describe("ItemDetailsSectionComponent", () => { await component.ngOnInit(); fixture.detectChanges(); - - expect(component["readOnlyCollections"]).toEqual(["Collection 1", "Collection 3"]); + expect(component["readOnlyCollectionsNames"]).toEqual(["Collection 1", "Collection 3"]); }); }); }); diff --git a/libs/vault/src/cipher-form/components/item-details/item-details-section.component.ts b/libs/vault/src/cipher-form/components/item-details/item-details-section.component.ts index e6799c54cb0..50bafd48b41 100644 --- a/libs/vault/src/cipher-form/components/item-details/item-details-section.component.ts +++ b/libs/vault/src/cipher-form/components/item-details/item-details-section.component.ts @@ -1,6 +1,6 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { CommonModule, NgClass } from "@angular/common"; +import { CommonModule } from "@angular/common"; import { Component, DestroyRef, Input, OnInit } from "@angular/core"; import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; import { FormBuilder, FormControl, ReactiveFormsModule, Validators } from "@angular/forms"; @@ -8,6 +8,7 @@ import { concatMap, map } from "rxjs"; import { CollectionView } from "@bitwarden/admin-console/common"; import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { OrganizationUserType } from "@bitwarden/common/admin-console/enums"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; @@ -43,7 +44,6 @@ import { CipherFormContainer } from "../../cipher-form-container"; SelectModule, SectionHeaderComponent, IconButtonModule, - NgClass, JslibModule, CommonModule, ], @@ -67,7 +67,7 @@ export class ItemDetailsSectionComponent implements OnInit { * Collections that are already assigned to the cipher and are read-only. These cannot be removed. * @protected */ - protected readOnlyCollections: string[] = []; + protected readOnlyCollections: CollectionView[] = []; protected showCollectionsControl: boolean; @@ -79,6 +79,10 @@ export class ItemDetailsSectionComponent implements OnInit { @Input() originalCipherView: CipherView; + + get readOnlyCollectionsNames(): string[] { + return this.readOnlyCollections.map((c) => c.name); + } /** * Whether the form is in partial edit mode. Only the folder and favorite controls are available. */ @@ -133,7 +137,10 @@ export class ItemDetailsSectionComponent implements OnInit { name: value.name, organizationId: value.organizationId, folderId: value.folderId, - collectionIds: value.collectionIds?.map((c) => c.id) || [], + collectionIds: [ + ...(value.collectionIds?.map((c) => c.id) || []), + ...this.readOnlyCollections.map((c) => c.id), + ], favorite: value.favorite, } as CipherView); return cipher; @@ -151,7 +158,7 @@ export class ItemDetailsSectionComponent implements OnInit { get allowOwnershipChange() { // Do not allow ownership change in edit mode and the cipher is owned by an organization - if (this.config.mode === "edit" && this.originalCipherView.organizationId != null) { + if (this.config.mode === "edit" && this.originalCipherView?.organizationId != null) { return false; } @@ -223,6 +230,8 @@ export class ItemDetailsSectionComponent implements OnInit { favorite: prefillCipher.favorite, }); + const orgId = this.itemDetailsForm.controls.organizationId.value as OrganizationId; + const organization = this.organizations.find((o) => o.id === orgId); const initializedWithCachedCipher = this.cipherFormContainer.initializedWithCachedCipher(); // Configure form for clone mode. @@ -244,20 +253,36 @@ export class ItemDetailsSectionComponent implements OnInit { await this.updateCollectionOptions(prefillCollections); + if (!organization?.canEditAllCiphers && !prefillCipher.canAssignToCollections) { + this.itemDetailsForm.controls.collectionIds.disable(); + } + if (this.partialEdit) { this.itemDetailsForm.disable(); this.itemDetailsForm.controls.favorite.enable(); this.itemDetailsForm.controls.folderId.enable(); } else if (this.config.mode === "edit") { - this.readOnlyCollections = this.collections - .filter( + if (!this.config.isAdminConsole || !this.config.admin) { + this.readOnlyCollections = this.collections.filter( // When the configuration is set up for admins, they can alter read only collections (c) => + c.organizationId === orgId && c.readOnly && - !this.config.admin && this.originalCipherView.collectionIds.includes(c.id as CollectionId), - ) - .map((c) => c.name); + ); + + // When Owners/Admins access setting is turned on. + // Disable Collections Options if Owner/Admin does not have Edit/Manage permissions on item + // Disable Collections Options if Custom user does not have Edit/Manage permissions on item + if ( + (organization?.allowAdminAccessToAllCollectionItems && + (!this.originalCipherView.viewPassword || !this.originalCipherView.edit)) || + (organization?.type === OrganizationUserType.Custom && + !this.originalCipherView.viewPassword) + ) { + this.itemDetailsForm.controls.collectionIds.disable(); + } + } } } diff --git a/libs/vault/src/cipher-form/components/login-details-section/login-details-section.component.spec.ts b/libs/vault/src/cipher-form/components/login-details-section/login-details-section.component.spec.ts index 453b0dce42d..199354124ff 100644 --- a/libs/vault/src/cipher-form/components/login-details-section/login-details-section.component.spec.ts +++ b/libs/vault/src/cipher-form/components/login-details-section/login-details-section.component.spec.ts @@ -13,10 +13,7 @@ import { Cipher } from "@bitwarden/common/vault/models/domain/cipher"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { Fido2CredentialView } from "@bitwarden/common/vault/models/view/fido2-credential.view"; import { LoginView } from "@bitwarden/common/vault/models/view/login.view"; -import { ToastService } from "@bitwarden/components"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { BitPasswordInputToggleDirective } from "@bitwarden/components/src/form-field/password-input-toggle.directive"; +import { BitPasswordInputToggleDirective, ToastService } from "@bitwarden/components"; import { CipherFormGenerationService } from "../../abstractions/cipher-form-generation.service"; import { TotpCaptureService } from "../../abstractions/totp-capture.service"; diff --git a/libs/vault/src/cipher-form/services/default-cipher-form-config.service.ts b/libs/vault/src/cipher-form/services/default-cipher-form-config.service.ts index 28b13b51c61..b9add41c222 100644 --- a/libs/vault/src/cipher-form/services/default-cipher-form-config.service.ts +++ b/libs/vault/src/cipher-form/services/default-cipher-form-config.service.ts @@ -8,6 +8,7 @@ import { OrganizationService } from "@bitwarden/common/admin-console/abstraction import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { OrganizationUserStatusType, PolicyType } from "@bitwarden/common/admin-console/enums"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { CipherId, UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; @@ -34,14 +35,12 @@ export class DefaultCipherFormConfigService implements CipherFormConfigService { private collectionService: CollectionService = inject(CollectionService); private accountService = inject(AccountService); - private activeUserId$ = this.accountService.activeAccount$.pipe(map((a) => a?.id)); - async buildConfig( mode: CipherFormMode, cipherId?: CipherId, cipherType?: CipherType, ): Promise { - const activeUserId = await firstValueFrom(this.activeUserId$); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); const [organizations, collections, allowPersonalOwnership, folders, cipher] = await firstValueFrom( @@ -62,7 +61,7 @@ export class DefaultCipherFormConfigService implements CipherFormConfigService { ), ), ), - this.getCipher(cipherId), + this.getCipher(activeUserId, cipherId), ]), ); @@ -94,10 +93,10 @@ export class DefaultCipherFormConfigService implements CipherFormConfigService { .policyAppliesToActiveUser$(PolicyType.PersonalOwnership) .pipe(map((p) => !p)); - private getCipher(id?: CipherId): Promise { + private getCipher(userId: UserId, id?: CipherId): Promise { if (id == null) { return Promise.resolve(null); } - return this.cipherService.get(id); + return this.cipherService.get(id, userId); } } diff --git a/libs/vault/src/cipher-form/services/default-cipher-form.service.ts b/libs/vault/src/cipher-form/services/default-cipher-form.service.ts index 059214cc185..98286e4bbb2 100644 --- a/libs/vault/src/cipher-form/services/default-cipher-form.service.ts +++ b/libs/vault/src/cipher-form/services/default-cipher-form.service.ts @@ -1,10 +1,11 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore import { inject, Injectable } from "@angular/core"; -import { firstValueFrom, map } from "rxjs"; +import { firstValueFrom } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { Cipher } from "@bitwarden/common/vault/models/domain/cipher"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; @@ -23,9 +24,7 @@ export class DefaultCipherFormService implements CipherFormService { private apiService: ApiService = inject(ApiService); async decryptCipher(cipher: Cipher): Promise { - const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), - ); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); return await cipher.decrypt( await this.cipherService.getKeyForCipherKeyDecryption(cipher, activeUserId), ); @@ -33,9 +32,7 @@ export class DefaultCipherFormService implements CipherFormService { async saveCipher(cipher: CipherView, config: CipherFormConfig): Promise { // Passing the original cipher is important here as it is responsible for appending to password history - const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), - ); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); const encryptedCipher = await this.cipherService.encrypt( cipher, activeUserId, @@ -90,7 +87,10 @@ export class DefaultCipherFormService implements CipherFormService { // When using an admin config or the cipher was unassigned, update collections as an admin savedCipher = await this.cipherService.saveCollectionsWithServerAdmin(encryptedCipher); } else { - savedCipher = await this.cipherService.saveCollectionsWithServer(encryptedCipher); + savedCipher = await this.cipherService.saveCollectionsWithServer( + encryptedCipher, + activeUserId, + ); } } diff --git a/libs/vault/src/cipher-view/autofill-options/autofill-options-view.component.ts b/libs/vault/src/cipher-view/autofill-options/autofill-options-view.component.ts index e7deb78c868..9b12139b00e 100644 --- a/libs/vault/src/cipher-view/autofill-options/autofill-options-view.component.ts +++ b/libs/vault/src/cipher-view/autofill-options/autofill-options-view.component.ts @@ -2,8 +2,11 @@ // @ts-strict-ignore import { CommonModule } from "@angular/common"; import { Component, Input } from "@angular/core"; +import { firstValueFrom } 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 { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { LoginUriView } from "@bitwarden/common/vault/models/view/login-uri.view"; @@ -38,10 +41,12 @@ export class AutofillOptionsViewComponent { constructor( private platformUtilsService: PlatformUtilsService, private cipherService: CipherService, + private accountService: AccountService, ) {} async openWebsite(selectedUri: string) { - await this.cipherService.updateLastLaunchedDate(this.cipherId); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + await this.cipherService.updateLastLaunchedDate(this.cipherId, activeUserId); this.platformUtilsService.launchUri(selectedUri); } } diff --git a/libs/vault/src/cipher-view/item-history/item-history-v2.component.html b/libs/vault/src/cipher-view/item-history/item-history-v2.component.html index a207b8fa1ca..19d1cfe1744 100644 --- a/libs/vault/src/cipher-view/item-history/item-history-v2.component.html +++ b/libs/vault/src/cipher-view/item-history/item-history-v2.component.html @@ -10,15 +10,15 @@

{{ "dateCreated" | i18n }}: {{ cipher.creationDate | date: "medium" }}

@@ -26,7 +26,7 @@ {{ cipher.passwordRevisionDisplayDate | date: "medium" }}

diff --git a/libs/vault/src/cipher-view/login-credentials/login-credentials-view.component.spec.ts b/libs/vault/src/cipher-view/login-credentials/login-credentials-view.component.spec.ts index 39fcc39bf58..3a2fb74feb8 100644 --- a/libs/vault/src/cipher-view/login-credentials/login-credentials-view.component.spec.ts +++ b/libs/vault/src/cipher-view/login-credentials/login-credentials-view.component.spec.ts @@ -16,13 +16,13 @@ import { CipherType } from "@bitwarden/common/vault/enums"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { Fido2CredentialView } from "@bitwarden/common/vault/models/view/fido2-credential.view"; import { LoginView } from "@bitwarden/common/vault/models/view/login.view"; -import { CopyClickDirective, BitFormFieldComponent, ToastService } from "@bitwarden/components"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { ColorPasswordComponent } from "@bitwarden/components/src/color-password/color-password.component"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { BitPasswordInputToggleDirective } from "@bitwarden/components/src/form-field/password-input-toggle.directive"; +import { + BitFormFieldComponent, + BitPasswordInputToggleDirective, + ColorPasswordComponent, + CopyClickDirective, + ToastService, +} from "@bitwarden/components"; import { LoginCredentialsViewComponent } from "./login-credentials-view.component"; diff --git a/libs/vault/src/cipher-view/login-credentials/login-credentials-view.component.ts b/libs/vault/src/cipher-view/login-credentials/login-credentials-view.component.ts index 281e187f78b..c95b2040fd2 100644 --- a/libs/vault/src/cipher-view/login-credentials/login-credentials-view.component.ts +++ b/libs/vault/src/cipher-view/login-credentials/login-credentials-view.component.ts @@ -2,15 +2,7 @@ // @ts-strict-ignore import { CommonModule, DatePipe } from "@angular/common"; import { Component, inject, Input } from "@angular/core"; -import { - BehaviorSubject, - combineLatest, - filter, - map, - Observable, - shareReplay, - switchMap, -} from "rxjs"; +import { Observable, switchMap } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service"; @@ -18,20 +10,18 @@ import { AccountService } from "@bitwarden/common/auth/abstractions/account.serv import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions"; import { EventType } from "@bitwarden/common/enums"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { PremiumUpgradePromptService } from "@bitwarden/common/vault/abstractions/premium-upgrade-prompt.service"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { - BadgeModule, - ColorPasswordModule, FormFieldModule, - IconButtonModule, SectionComponent, SectionHeaderComponent, TypographyModule, + IconButtonModule, + BadgeModule, + ColorPasswordModule, } from "@bitwarden/components"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { PremiumUpgradePromptService } from "../../../../../libs/common/src/vault/abstractions/premium-upgrade-prompt.service"; import { BitTotpCountdownComponent } from "../../components/totp-countdown/totp-countdown.component"; import { ReadOnlyCipherCardComponent } from "../read-only-cipher-card/read-only-cipher-card.component"; @@ -59,31 +49,13 @@ type TotpCodeValues = { ], }) export class LoginCredentialsViewComponent { - @Input() - get cipher(): CipherView { - return this._cipher$.value; - } - set cipher(value: CipherView) { - this._cipher$.next(value); - } - private _cipher$ = new BehaviorSubject(null); + @Input() cipher: CipherView; - private _userHasPremium$: Observable = this.accountService.activeAccount$.pipe( + isPremium$: Observable = this.accountService.activeAccount$.pipe( switchMap((account) => this.billingAccountProfileStateService.hasPremiumFromAnySource$(account.id), ), ); - - allowTotpGeneration$: Observable = combineLatest([ - this._userHasPremium$, - this._cipher$.pipe(filter((c) => c != null)), - ]).pipe( - map(([userHasPremium, cipher]) => { - // User premium status only applies to personal ciphers, organizationUseTotp applies to organization ciphers - return (userHasPremium && cipher.organizationId == null) || cipher.organizationUseTotp; - }), - shareReplay({ refCount: true, bufferSize: 1 }), - ); showPasswordCount: boolean = false; passwordRevealed: boolean = false; totpCodeCopyObj: TotpCodeValues; diff --git a/libs/vault/src/cipher-view/view-identity-sections/view-identity-sections.component.spec.ts b/libs/vault/src/cipher-view/view-identity-sections/view-identity-sections.component.spec.ts index 21f82234b2c..5228124871f 100644 --- a/libs/vault/src/cipher-view/view-identity-sections/view-identity-sections.component.spec.ts +++ b/libs/vault/src/cipher-view/view-identity-sections/view-identity-sections.component.spec.ts @@ -6,11 +6,7 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { IdentityView } from "@bitwarden/common/vault/models/view/identity.view"; -import { SectionHeaderComponent } from "@bitwarden/components"; - -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { BitInputDirective } from "../../../../components/src/input/input.directive"; +import { BitInputDirective, SectionHeaderComponent } from "@bitwarden/components"; import { ViewIdentitySectionsComponent } from "./view-identity-sections.component"; diff --git a/apps/browser/src/vault/popup/components/vault-v2/add-edit-folder-dialog/add-edit-folder-dialog.component.html b/libs/vault/src/components/add-edit-folder-dialog/add-edit-folder-dialog.component.html similarity index 96% rename from apps/browser/src/vault/popup/components/vault-v2/add-edit-folder-dialog/add-edit-folder-dialog.component.html rename to libs/vault/src/components/add-edit-folder-dialog/add-edit-folder-dialog.component.html index 0e6dbf24427..4869714332c 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/add-edit-folder-dialog/add-edit-folder-dialog.component.html +++ b/libs/vault/src/components/add-edit-folder-dialog/add-edit-folder-dialog.component.html @@ -31,7 +31,7 @@ *ngIf="variant === 'edit'" type="button" buttonType="danger" - class="tw-border-0 tw-ml-auto" + class="tw-ml-auto" bitIconButton="bwi-trash" [appA11yTitle]="'deleteFolder' | i18n" [bitAction]="deleteFolder" diff --git a/apps/browser/src/vault/popup/components/vault-v2/add-edit-folder-dialog/add-edit-folder-dialog.component.spec.ts b/libs/vault/src/components/add-edit-folder-dialog/add-edit-folder-dialog.component.spec.ts similarity index 95% rename from apps/browser/src/vault/popup/components/vault-v2/add-edit-folder-dialog/add-edit-folder-dialog.component.spec.ts rename to libs/vault/src/components/add-edit-folder-dialog/add-edit-folder-dialog.component.spec.ts index cbec7903031..93db390d141 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/add-edit-folder-dialog/add-edit-folder-dialog.component.spec.ts +++ b/libs/vault/src/components/add-edit-folder-dialog/add-edit-folder-dialog.component.spec.ts @@ -17,6 +17,7 @@ import { KeyService } from "@bitwarden/key-management"; import { AddEditFolderDialogComponent, AddEditFolderDialogData, + AddEditFolderDialogResult, } from "./add-edit-folder-dialog.component"; describe("AddEditFolderDialogComponent", () => { @@ -115,7 +116,7 @@ describe("AddEditFolderDialogComponent", () => { expect(showToast).toHaveBeenCalledWith({ message: "editedFolder", - title: null, + title: "", variant: "success", }); }); @@ -125,7 +126,7 @@ describe("AddEditFolderDialogComponent", () => { await component.submit(); - expect(close).toHaveBeenCalled(); + expect(close).toHaveBeenCalledWith(AddEditFolderDialogResult.Created); }); it("logs error if saving fails", async () => { @@ -161,7 +162,7 @@ describe("AddEditFolderDialogComponent", () => { expect(encrypt).toHaveBeenCalledWith( { - ...dialogData.editFolderConfig.folder, + ...dialogData.editFolderConfig!.folder, name: "Edited Folder", }, "", @@ -174,9 +175,10 @@ describe("AddEditFolderDialogComponent", () => { expect(deleteFolder).toHaveBeenCalledWith(folderView.id, ""); expect(showToast).toHaveBeenCalledWith({ variant: "success", - title: null, + title: "", message: "deletedFolder", }); + expect(close).toHaveBeenCalledWith(AddEditFolderDialogResult.Deleted); }); }); }); diff --git a/apps/browser/src/vault/popup/components/vault-v2/add-edit-folder-dialog/add-edit-folder-dialog.component.ts b/libs/vault/src/components/add-edit-folder-dialog/add-edit-folder-dialog.component.ts similarity index 78% rename from apps/browser/src/vault/popup/components/vault-v2/add-edit-folder-dialog/add-edit-folder-dialog.component.ts rename to libs/vault/src/components/add-edit-folder-dialog/add-edit-folder-dialog.component.ts index a50403cea2d..362063ff345 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/add-edit-folder-dialog/add-edit-folder-dialog.component.ts +++ b/libs/vault/src/components/add-edit-folder-dialog/add-edit-folder-dialog.component.ts @@ -1,5 +1,3 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore import { DIALOG_DATA, DialogRef } from "@angular/cdk/dialog"; import { CommonModule } from "@angular/common"; import { @@ -35,6 +33,11 @@ import { } from "@bitwarden/components"; import { KeyService } from "@bitwarden/key-management"; +export enum AddEditFolderDialogResult { + Created = "created", + Deleted = "deleted", +} + export type AddEditFolderDialogData = { /** When provided, dialog will display edit folder variant */ editFolderConfig?: { folder: FolderView }; @@ -56,12 +59,12 @@ export type AddEditFolderDialogData = { ], }) export class AddEditFolderDialogComponent implements AfterViewInit, OnInit { - @ViewChild(BitSubmitDirective) private bitSubmit: BitSubmitDirective; - @ViewChild("submitBtn") private submitBtn: ButtonComponent; + @ViewChild(BitSubmitDirective) private bitSubmit?: BitSubmitDirective; + @ViewChild("submitBtn") private submitBtn?: ButtonComponent; - folder: FolderView; + folder: FolderView = new FolderView(); - variant: "add" | "edit"; + variant: "add" | "edit" = "add"; folderForm = this.formBuilder.group({ name: ["", Validators.required], @@ -80,14 +83,13 @@ export class AddEditFolderDialogComponent implements AfterViewInit, OnInit { private i18nService: I18nService, private logService: LogService, private dialogService: DialogService, - private dialogRef: DialogRef, + private dialogRef: DialogRef, @Inject(DIALOG_DATA) private data?: AddEditFolderDialogData, ) {} ngOnInit(): void { - this.variant = this.data?.editFolderConfig ? "edit" : "add"; - - if (this.variant === "edit") { + if (this.data?.editFolderConfig) { + this.variant = "edit"; this.folderForm.controls.name.setValue(this.data.editFolderConfig.folder.name); this.folder = this.data.editFolderConfig.folder; } else { @@ -97,7 +99,7 @@ export class AddEditFolderDialogComponent implements AfterViewInit, OnInit { } ngAfterViewInit(): void { - this.bitSubmit.loading$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((loading) => { + this.bitSubmit?.loading$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((loading) => { if (!this.submitBtn) { return; } @@ -112,21 +114,21 @@ export class AddEditFolderDialogComponent implements AfterViewInit, OnInit { return; } - this.folder.name = this.folderForm.controls.name.value; + this.folder.name = this.folderForm.controls.name.value ?? ""; try { const activeUserId = await firstValueFrom(this.activeUserId$); - const userKey = await this.keyService.getUserKeyWithLegacySupport(activeUserId); + const userKey = await this.keyService.getUserKeyWithLegacySupport(activeUserId!); const folder = await this.folderService.encrypt(this.folder, userKey); - await this.folderApiService.save(folder, activeUserId); + await this.folderApiService.save(folder, activeUserId!); this.toastService.showToast({ variant: "success", - title: null, + title: "", message: this.i18nService.t("editedFolder"), }); - this.close(); + this.close(AddEditFolderDialogResult.Created); } catch (e) { this.logService.error(e); } @@ -146,21 +148,28 @@ export class AddEditFolderDialogComponent implements AfterViewInit, OnInit { try { const activeUserId = await firstValueFrom(this.activeUserId$); - await this.folderApiService.delete(this.folder.id, activeUserId); + await this.folderApiService.delete(this.folder.id, activeUserId!); this.toastService.showToast({ variant: "success", - title: null, + title: "", message: this.i18nService.t("deletedFolder"), }); } catch (e) { this.logService.error(e); } - this.close(); + this.close(AddEditFolderDialogResult.Deleted); }; /** Close the dialog */ - private close() { - this.dialogRef.close(); + private close(result: AddEditFolderDialogResult) { + this.dialogRef.close(result); + } + + static open(dialogService: DialogService, data?: AddEditFolderDialogData) { + return dialogService.open( + AddEditFolderDialogComponent, + { data }, + ); } } diff --git a/libs/vault/src/components/assign-collections.component.ts b/libs/vault/src/components/assign-collections.component.ts index c950187edb8..76a6a1b10a6 100644 --- a/libs/vault/src/components/assign-collections.component.ts +++ b/libs/vault/src/components/assign-collections.component.ts @@ -179,7 +179,6 @@ export class AssignCollectionsComponent implements OnInit, OnDestroy, AfterViewI private get selectedOrgId(): OrganizationId { return this.formGroup.getRawValue().selectedOrg || this.params.organizationId; } - private activeUserId: UserId; private destroy$ = new Subject(); constructor( @@ -193,10 +192,6 @@ export class AssignCollectionsComponent implements OnInit, OnDestroy, AfterViewI ) {} async ngOnInit() { - this.activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), - ); - const onlyPersonalItems = this.params.ciphers.every((c) => c.organizationId == null); if (this.selectedOrgId === MY_VAULT_ID || onlyPersonalItems) { @@ -206,7 +201,7 @@ export class AssignCollectionsComponent implements OnInit, OnDestroy, AfterViewI await this.initializeItems(this.selectedOrgId); if (this.selectedOrgId && this.selectedOrgId !== MY_VAULT_ID) { - await this.handleOrganizationCiphers(); + await this.handleOrganizationCiphers(this.selectedOrgId); } this.setupFormSubscriptions(); @@ -253,12 +248,15 @@ export class AssignCollectionsComponent implements OnInit, OnDestroy, AfterViewI .filter((i) => i.organizationId) .map((i) => i.id as CipherId); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + // Move personal items to the organization if (this.personalItemsCount > 0) { await this.moveToOrganization( this.selectedOrgId, this.params.ciphers.filter((c) => c.organizationId == null), this.formGroup.controls.collections.value.map((i) => i.id as CollectionId), + activeUserId, ); } @@ -267,8 +265,8 @@ export class AssignCollectionsComponent implements OnInit, OnDestroy, AfterViewI // Update assigned collections for single org cipher or bulk update collections for multiple org ciphers await (isSingleOrgCipher - ? this.updateAssignedCollections(this.editableItems[0]) - : this.bulkUpdateCollections(cipherIds)); + ? this.updateAssignedCollections(this.editableItems[0], activeUserId) + : this.bulkUpdateCollections(cipherIds, activeUserId)); this.toastService.showToast({ variant: "success", @@ -283,7 +281,7 @@ export class AssignCollectionsComponent implements OnInit, OnDestroy, AfterViewI private sortItems = (a: SelectItemView, b: SelectItemView) => this.i18nService.collator.compare(a.labelName, b.labelName); - private async handleOrganizationCiphers() { + private async handleOrganizationCiphers(organizationId: OrganizationId) { // If no ciphers are editable, cancel the operation if (this.editableItemCount == 0) { this.toastService.showToast({ @@ -296,12 +294,21 @@ export class AssignCollectionsComponent implements OnInit, OnDestroy, AfterViewI return; } - this.availableCollections = this.params.availableCollections.map((c) => ({ - icon: "bwi-collection", - id: c.id, - labelName: c.name, - listName: c.name, - })); + const userId = await firstValueFrom(getUserId(this.accountService.activeAccount$)); + const org = await firstValueFrom( + this.organizationService.organizations$(userId).pipe(getOrganizationById(organizationId)), + ); + + this.availableCollections = this.params.availableCollections + .filter((collection) => { + return collection.canEditItems(org); + }) + .map((c) => ({ + icon: "bwi-collection", + id: c.id, + labelName: c.name, + listName: c.name, + })); // Select assigned collections for a single cipher. this.selectCollectionsAssignedToSingleCipher(); @@ -438,12 +445,13 @@ export class AssignCollectionsComponent implements OnInit, OnDestroy, AfterViewI organizationId: OrganizationId, shareableCiphers: CipherView[], selectedCollectionIds: CollectionId[], + userId: UserId, ) { await this.cipherService.shareManyWithServer( shareableCiphers, organizationId, selectedCollectionIds, - this.activeUserId, + userId, ); this.toastService.showToast({ @@ -456,10 +464,11 @@ export class AssignCollectionsComponent implements OnInit, OnDestroy, AfterViewI }); } - private async bulkUpdateCollections(cipherIds: CipherId[]) { + private async bulkUpdateCollections(cipherIds: CipherId[], userId: UserId) { if (this.formGroup.controls.collections.value.length > 0) { await this.cipherService.bulkUpdateCollectionsWithServer( this.selectedOrgId, + userId, cipherIds, this.formGroup.controls.collections.value.map((i) => i.id as CollectionId), false, @@ -474,6 +483,7 @@ export class AssignCollectionsComponent implements OnInit, OnDestroy, AfterViewI ) { await this.cipherService.bulkUpdateCollectionsWithServer( this.selectedOrgId, + userId, cipherIds, [this.params.activeCollection.id as CollectionId], true, @@ -481,14 +491,14 @@ export class AssignCollectionsComponent implements OnInit, OnDestroy, AfterViewI } } - private async updateAssignedCollections(cipherView: CipherView) { + private async updateAssignedCollections(cipherView: CipherView, userId: UserId) { const { collections } = this.formGroup.getRawValue(); cipherView.collectionIds = collections.map((i) => i.id as CollectionId); - const cipher = await this.cipherService.encrypt(cipherView, this.activeUserId); + const cipher = await this.cipherService.encrypt(cipherView, userId); if (this.params.isSingleCipherAdmin) { await this.cipherService.saveCollectionsWithServerAdmin(cipher); } else { - await this.cipherService.saveCollectionsWithServer(cipher); + await this.cipherService.saveCollectionsWithServer(cipher, userId); } } } diff --git a/libs/vault/src/components/download-attachment/download-attachment.component.spec.ts b/libs/vault/src/components/download-attachment/download-attachment.component.spec.ts index dc6ca16ddd6..f621ca63101 100644 --- a/libs/vault/src/components/download-attachment/download-attachment.component.spec.ts +++ b/libs/vault/src/components/download-attachment/download-attachment.component.spec.ts @@ -4,8 +4,8 @@ import { mock } from "jest-mock-extended"; import { BehaviorSubject } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { ErrorResponse } from "@bitwarden/common/models/response/error.response"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { EncArrayBuffer } from "@bitwarden/common/platform/models/domain/enc-array-buffer"; diff --git a/libs/vault/src/components/download-attachment/download-attachment.component.ts b/libs/vault/src/components/download-attachment/download-attachment.component.ts index a47cdc8d1d5..1445ca557cf 100644 --- a/libs/vault/src/components/download-attachment/download-attachment.component.ts +++ b/libs/vault/src/components/download-attachment/download-attachment.component.ts @@ -7,8 +7,8 @@ import { NEVER, switchMap } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { ErrorResponse } from "@bitwarden/common/models/response/error.response"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { EncArrayBuffer } from "@bitwarden/common/platform/models/domain/enc-array-buffer"; diff --git a/libs/vault/src/components/password-history-view/password-history-view.component.spec.ts b/libs/vault/src/components/password-history-view/password-history-view.component.spec.ts index fb90df4d6ac..b9f83ea2176 100644 --- a/libs/vault/src/components/password-history-view/password-history-view.component.spec.ts +++ b/libs/vault/src/components/password-history-view/password-history-view.component.spec.ts @@ -9,10 +9,7 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CipherType } from "@bitwarden/common/vault/enums"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; -import { ColorPasswordModule, ItemModule } from "@bitwarden/components"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { ColorPasswordComponent } from "@bitwarden/components/src/color-password/color-password.component"; +import { ColorPasswordComponent, ColorPasswordModule, ItemModule } from "@bitwarden/components"; import { PasswordHistoryViewComponent } from "./password-history-view.component"; diff --git a/libs/vault/src/index.ts b/libs/vault/src/index.ts index 23143fa2309..ac905c1f5ef 100644 --- a/libs/vault/src/index.ts +++ b/libs/vault/src/index.ts @@ -1,9 +1,12 @@ export { PasswordRepromptService } from "./services/password-reprompt.service"; +export { NewDeviceVerificationNoticeService } from "./services/new-device-verification-notice.service"; export { CopyCipherFieldService, CopyAction } from "./services/copy-cipher-field.service"; export { CopyCipherFieldDirective } from "./components/copy-cipher-field.directive"; export { OrgIconDirective } from "./components/org-icon.directive"; export { CanDeleteCipherDirective } from "./components/can-delete-cipher.directive"; +export * from "./utils/observable-utilities"; + export * from "./cipher-view"; export * from "./cipher-form"; export { @@ -17,7 +20,11 @@ export { PasswordHistoryViewComponent } from "./components/password-history-view export { NewDeviceVerificationNoticePageOneComponent } from "./components/new-device-verification-notice/new-device-verification-notice-page-one.component"; export { NewDeviceVerificationNoticePageTwoComponent } from "./components/new-device-verification-notice/new-device-verification-notice-page-two.component"; export { DecryptionFailureDialogComponent } from "./components/decryption-failure-dialog/decryption-failure-dialog.component"; +export * from "./components/add-edit-folder-dialog/add-edit-folder-dialog.component"; export * as VaultIcons from "./icons"; export * from "./tasks"; + +export * from "./abstractions/change-login-password.service"; +export * from "./services/default-change-login-password.service"; diff --git a/libs/vault/src/services/default-change-login-password.service.spec.ts b/libs/vault/src/services/default-change-login-password.service.spec.ts new file mode 100644 index 00000000000..4805f298797 --- /dev/null +++ b/libs/vault/src/services/default-change-login-password.service.spec.ts @@ -0,0 +1,157 @@ +/** + * Jest needs to run in custom environment to mock Request/Response objects + * @jest-environment ../../libs/shared/test.environment.ts + */ + +import { mock } from "jest-mock-extended"; + +import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { CipherType } from "@bitwarden/common/vault/enums"; +import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; +import { LoginUriView } from "@bitwarden/common/vault/models/view/login-uri.view"; +import { LoginView } from "@bitwarden/common/vault/models/view/login.view"; + +import { DefaultChangeLoginPasswordService } from "./default-change-login-password.service"; + +describe("DefaultChangeLoginPasswordService", () => { + let service: DefaultChangeLoginPasswordService; + + let mockShouldNotExistResponse: Response; + let mockWellKnownResponse: Response; + + const mockApiService = mock(); + + beforeEach(() => { + mockApiService.nativeFetch.mockClear(); + + // Default responses to success state + mockShouldNotExistResponse = new Response("Not Found", { status: 404 }); + mockWellKnownResponse = new Response("OK", { status: 200 }); + + mockApiService.nativeFetch.mockImplementation((request) => { + if ( + request.url.endsWith("resource-that-should-not-exist-whose-status-code-should-not-be-200") + ) { + return Promise.resolve(mockShouldNotExistResponse); + } + + if (request.url.endsWith(".well-known/change-password")) { + return Promise.resolve(mockWellKnownResponse); + } + + throw new Error("Unexpected request"); + }); + service = new DefaultChangeLoginPasswordService(mockApiService); + }); + + it("should return null for non-login ciphers", async () => { + const cipher = { + type: CipherType.Card, + } as CipherView; + + const url = await service.getChangePasswordUrl(cipher); + + expect(url).toBeNull(); + }); + + it("should return null for logins with no URIs", async () => { + const cipher = { + type: CipherType.Login, + login: Object.assign(new LoginView(), { uris: [] as LoginUriView[] }), + } as CipherView; + + const url = await service.getChangePasswordUrl(cipher); + + expect(url).toBeNull(); + }); + + it("should return null for logins with no valid HTTP/HTTPS URIs", async () => { + const cipher = { + type: CipherType.Login, + login: Object.assign(new LoginView(), { + uris: [{ uri: "ftp://example.com" }], + }), + } as CipherView; + + const url = await service.getChangePasswordUrl(cipher); + + expect(url).toBeNull(); + }); + + it("should check the origin for a reliable status code", async () => { + const cipher = { + type: CipherType.Login, + login: Object.assign(new LoginView(), { + uris: [{ uri: "https://example.com" }], + }), + } as CipherView; + + await service.getChangePasswordUrl(cipher); + + expect(mockApiService.nativeFetch).toHaveBeenCalledWith( + expect.objectContaining({ + url: "https://example.com/.well-known/resource-that-should-not-exist-whose-status-code-should-not-be-200", + }), + ); + }); + + it("should attempt to fetch the well-known change password URL", async () => { + const cipher = { + type: CipherType.Login, + login: Object.assign(new LoginView(), { + uris: [{ uri: "https://example.com" }], + }), + } as CipherView; + + await service.getChangePasswordUrl(cipher); + + expect(mockApiService.nativeFetch).toHaveBeenCalledWith( + expect.objectContaining({ + url: "https://example.com/.well-known/change-password", + }), + ); + }); + + it("should return the well-known change password URL when successful at verifying the response", async () => { + const cipher = { + type: CipherType.Login, + login: Object.assign(new LoginView(), { + uris: [{ uri: "https://example.com" }], + }), + } as CipherView; + + const url = await service.getChangePasswordUrl(cipher); + + expect(url).toBe("https://example.com/.well-known/change-password"); + }); + + it("should return the original URI when unable to verify the response", async () => { + mockShouldNotExistResponse = new Response("Ok", { status: 200 }); + + const cipher = { + type: CipherType.Login, + login: Object.assign(new LoginView(), { + uris: [{ uri: "https://example.com" }], + }), + } as CipherView; + + const url = await service.getChangePasswordUrl(cipher); + + expect(url).toBe("https://example.com"); + }); + + it("should return the original URI when the well-known URL is not found", async () => { + mockWellKnownResponse = new Response("Not Found", { status: 404 }); + + const cipher = { + type: CipherType.Login, + login: Object.assign(new LoginView(), { + uris: [{ uri: "https://example.com" }], + }), + } as CipherView; + + const url = await service.getChangePasswordUrl(cipher); + + expect(url).toBe("https://example.com"); + }); +}); diff --git a/libs/vault/src/services/default-change-login-password.service.ts b/libs/vault/src/services/default-change-login-password.service.ts new file mode 100644 index 00000000000..25648318c14 --- /dev/null +++ b/libs/vault/src/services/default-change-login-password.service.ts @@ -0,0 +1,96 @@ +import { Injectable } from "@angular/core"; + +import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { Utils } from "@bitwarden/common/platform/misc/utils"; +import { CipherType } from "@bitwarden/common/vault/enums"; +import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; + +import { ChangeLoginPasswordService } from "../abstractions/change-login-password.service"; + +@Injectable() +export class DefaultChangeLoginPasswordService implements ChangeLoginPasswordService { + constructor(private apiService: ApiService) {} + + /** + * @inheritDoc + */ + async getChangePasswordUrl(cipher: CipherView): Promise { + // Ensure we have a cipher with at least one URI + if (cipher.type !== CipherType.Login || cipher.login == null || !cipher.login.hasUris) { + return null; + } + + // Find the first valid URL that is an HTTP or HTTPS URL + const url = cipher.login.uris + .map((m) => Utils.getUrl(m.uri)) + .find((m) => m != null && (m.protocol === "http:" || m.protocol === "https:")); + + if (url == null) { + return null; + } + + const [reliable, wellKnownChangeUrl] = await Promise.all([ + this.hasReliableHttpStatusCode(url.origin), + this.getWellKnownChangePasswordUrl(url.origin), + ]); + + if (!reliable || wellKnownChangeUrl == null) { + return cipher.login.uri; + } + + return wellKnownChangeUrl; + } + + /** + * Checks if the server returns a non-200 status code for a resource that should not exist. + * See https://w3c.github.io/webappsec-change-password-url/response-code-reliability.html#semantics + * @param urlOrigin The origin of the URL to check + */ + private async hasReliableHttpStatusCode(urlOrigin: string): Promise { + try { + const url = new URL( + "./.well-known/resource-that-should-not-exist-whose-status-code-should-not-be-200", + urlOrigin, + ); + + const request = new Request(url, { + method: "GET", + mode: "same-origin", + credentials: "omit", + cache: "no-store", + redirect: "follow", + }); + + const response = await this.apiService.nativeFetch(request); + return !response.ok; + } catch { + return false; + } + } + + /** + * Builds a well-known change password URL for the given origin. Attempts to fetch the URL to ensure a valid response + * is returned. Returns null if the request throws or the response is not 200 OK. + * See https://w3c.github.io/webappsec-change-password-url/ + * @param urlOrigin The origin of the URL to check + */ + private async getWellKnownChangePasswordUrl(urlOrigin: string): Promise { + try { + const url = new URL("./.well-known/change-password", urlOrigin); + + const request = new Request(url, { + method: "GET", + mode: "same-origin", + credentials: "omit", + cache: "no-store", + redirect: "follow", + }); + + const response = await this.apiService.nativeFetch(request); + + return response.ok ? url.toString() : null; + } catch { + return null; + } + } +} diff --git a/libs/vault/src/services/password-reprompt.service.spec.ts b/libs/vault/src/services/password-reprompt.service.spec.ts index 7d0a834b2d6..b437e21e98e 100644 --- a/libs/vault/src/services/password-reprompt.service.spec.ts +++ b/libs/vault/src/services/password-reprompt.service.spec.ts @@ -1,8 +1,6 @@ import { MockProxy, mock } from "jest-mock-extended"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { UserVerificationService } from "@bitwarden/common/src/auth/abstractions/user-verification/user-verification.service.abstraction"; +import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { DialogService } from "@bitwarden/components"; import { PasswordRepromptService } from "./password-reprompt.service"; diff --git a/libs/vault/src/tasks/models/index.ts b/libs/vault/src/tasks/models/index.ts index 7e31c136629..e9b6e3352af 100644 --- a/libs/vault/src/tasks/models/index.ts +++ b/libs/vault/src/tasks/models/index.ts @@ -1 +1,3 @@ export * from "./security-task"; +export * from "./security-task.data"; +export * from "./security-task.response"; diff --git a/libs/vault/src/tasks/services/default-task.service.spec.ts b/libs/vault/src/tasks/services/default-task.service.spec.ts index 26b1a79ca2e..c6b74f82909 100644 --- a/libs/vault/src/tasks/services/default-task.service.spec.ts +++ b/libs/vault/src/tasks/services/default-task.service.spec.ts @@ -4,6 +4,7 @@ import { BehaviorSubject, firstValueFrom } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { StateProvider } from "@bitwarden/common/platform/state"; import { SecurityTaskId, UserId } from "@bitwarden/common/types/guid"; import { DefaultTaskService, SecurityTaskStatus } from "@bitwarden/vault"; @@ -18,18 +19,26 @@ describe("Default task service", () => { const mockApiSend = jest.fn(); const mockGetAllOrgs$ = jest.fn(); + const mockGetFeatureFlag$ = jest.fn(); let testBed: TestBed; beforeEach(async () => { mockApiSend.mockClear(); mockGetAllOrgs$.mockClear(); + mockGetFeatureFlag$.mockClear(); fakeStateProvider = new FakeStateProvider(mockAccountServiceWith("user-id" as UserId)); testBed = TestBed.configureTestingModule({ imports: [], providers: [ DefaultTaskService, + { + provide: ConfigService, + useValue: { + getFeatureFlag$: mockGetFeatureFlag$, + }, + }, { provide: StateProvider, useValue: fakeStateProvider, @@ -52,6 +61,7 @@ describe("Default task service", () => { describe("tasksEnabled$", () => { it("should emit true if any organization uses risk insights", async () => { + mockGetFeatureFlag$.mockReturnValue(new BehaviorSubject(true)); mockGetAllOrgs$.mockReturnValue( new BehaviorSubject([ { @@ -71,6 +81,7 @@ describe("Default task service", () => { }); it("should emit false if no organization uses risk insights", async () => { + mockGetFeatureFlag$.mockReturnValue(new BehaviorSubject(true)); mockGetAllOrgs$.mockReturnValue( new BehaviorSubject([ { @@ -88,6 +99,23 @@ describe("Default task service", () => { expect(result).toBe(false); }); + + it("should emit false if the feature flag is off", async () => { + mockGetFeatureFlag$.mockReturnValue(new BehaviorSubject(false)); + mockGetAllOrgs$.mockReturnValue( + new BehaviorSubject([ + { + useRiskInsights: true, + }, + ] as Organization[]), + ); + + const { tasksEnabled$ } = testBed.inject(DefaultTaskService); + + const result = await firstValueFrom(tasksEnabled$("user-id" as UserId)); + + expect(result).toBe(false); + }); }); describe("tasks$", () => { @@ -100,7 +128,7 @@ describe("Default task service", () => { ] as SecurityTaskResponse[], }); - fakeStateProvider.singleUser.mockFor("user-id" as UserId, SECURITY_TASKS, null); + fakeStateProvider.singleUser.mockFor("user-id" as UserId, SECURITY_TASKS, null as any); const { tasks$ } = testBed.inject(DefaultTaskService); @@ -183,7 +211,11 @@ describe("Default task service", () => { ] as SecurityTaskResponse[], }); - const mock = fakeStateProvider.singleUser.mockFor("user-id" as UserId, SECURITY_TASKS, null); + const mock = fakeStateProvider.singleUser.mockFor( + "user-id" as UserId, + SECURITY_TASKS, + null as any, + ); const service = testBed.inject(DefaultTaskService); diff --git a/libs/vault/src/tasks/services/default-task.service.ts b/libs/vault/src/tasks/services/default-task.service.ts index f5c1d95af08..b6d0ff77e9d 100644 --- a/libs/vault/src/tasks/services/default-task.service.ts +++ b/libs/vault/src/tasks/services/default-task.service.ts @@ -1,9 +1,11 @@ import { Injectable } from "@angular/core"; -import { map, switchMap } from "rxjs"; +import { combineLatest, map, switchMap } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; +import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ListResponse } from "@bitwarden/common/models/response/list.response"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { StateProvider } from "@bitwarden/common/platform/state"; import { SecurityTaskId, UserId } from "@bitwarden/common/types/guid"; import { SecurityTask, SecurityTaskStatus, TaskService } from "@bitwarden/vault"; @@ -19,12 +21,16 @@ export class DefaultTaskService implements TaskService { private stateProvider: StateProvider, private apiService: ApiService, private organizationService: OrganizationService, + private configService: ConfigService, ) {} tasksEnabled$ = perUserCache$((userId) => { - return this.organizationService - .organizations$(userId) - .pipe(map((orgs) => orgs.some((o) => o.useRiskInsights))); + return combineLatest([ + this.organizationService + .organizations$(userId) + .pipe(map((orgs) => orgs.some((o) => o.useRiskInsights))), + this.configService.getFeatureFlag$(FeatureFlag.SecurityTasks), + ]).pipe(map(([atLeastOneOrgEnabled, flagEnabled]) => atLeastOneOrgEnabled && flagEnabled)); }); tasks$ = perUserCache$((userId) => { @@ -87,7 +93,10 @@ export class DefaultTaskService implements TaskService { * @param tasks * @private */ - private updateTaskState(userId: UserId, tasks: SecurityTaskData[]): Promise { + private updateTaskState( + userId: UserId, + tasks: SecurityTaskData[], + ): Promise { return this.taskState(userId).update(() => tasks); } } diff --git a/package-lock.json b/package-lock.json index b2b803065ba..ed037d0ff5e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,17 +36,17 @@ "argon2-browser": "1.18.0", "big-integer": "1.6.52", "bootstrap": "4.6.0", - "braintree-web-drop-in": "1.43.0", + "braintree-web-drop-in": "1.44.0", "buffer": "6.0.3", "bufferutil": "4.0.9", "chalk": "4.1.2", "commander": "11.1.0", - "core-js": "3.39.0", + "core-js": "3.40.0", "form-data": "4.0.1", "https-proxy-agent": "7.0.5", "inquirer": "8.2.6", "jquery": "3.7.1", - "jsdom": "25.0.1", + "jsdom": "26.0.0", "jszip": "3.10.1", "koa": "2.15.3", "koa-bodyparser": "4.4.1", @@ -61,7 +61,7 @@ "nord": "0.2.1", "oidc-client-ts": "2.4.1", "open": "8.4.2", - "papaparse": "5.4.1", + "papaparse": "5.5.2", "patch-package": "8.0.0", "popper.js": "1.16.1", "proper-lockfile": "4.1.2", @@ -117,6 +117,8 @@ "@types/proper-lockfile": "4.1.4", "@types/retry": "0.12.5", "@types/zxcvbn": "4.4.5", + "@typescript-eslint/rule-tester": "8.22.0", + "@typescript-eslint/utils": "8.22.0", "@webcomponents/custom-elements": "1.6.0", "@yao-pkg/pkg": "5.16.1", "angular-eslint": "18.4.3", @@ -124,7 +126,7 @@ "babel-loader": "9.2.1", "base64-loader": "1.0.0", "browserslist": "4.23.2", - "chromatic": "11.20.2", + "chromatic": "11.25.2", "concurrently": "9.1.2", "copy-webpack-plugin": "12.0.2", "cross-env": "7.0.3", @@ -154,7 +156,7 @@ "lint-staged": "15.4.1", "mini-css-extract-plugin": "2.9.2", "node-ipc": "9.2.1", - "postcss": "8.4.49", + "postcss": "8.5.1", "postcss-loader": "8.1.1", "prettier": "3.4.2", "prettier-plugin-tailwindcss": "0.6.10", @@ -167,12 +169,12 @@ "style-loader": "4.0.0", "tailwindcss": "3.4.17", "ts-jest": "29.2.2", - "ts-loader": "9.5.1", + "ts-loader": "9.5.2", "tsconfig-paths-webpack-plugin": "4.2.0", "type-fest": "2.19.0", "typescript": "5.4.2", "typescript-eslint": "8.20.0", - "typescript-strict-plugin": "^2.4.4", + "typescript-strict-plugin": "2.4.4", "url": "0.11.4", "util": "0.12.5", "wait-on": "8.0.2", @@ -188,11 +190,11 @@ }, "apps/browser": { "name": "@bitwarden/browser", - "version": "2025.1.4" + "version": "2025.2.1" }, "apps/cli": { "name": "@bitwarden/cli", - "version": "2025.1.3", + "version": "2025.2.0", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@koa/multer": "3.0.2", @@ -205,7 +207,7 @@ "form-data": "4.0.1", "https-proxy-agent": "7.0.5", "inquirer": "8.2.6", - "jsdom": "25.0.1", + "jsdom": "26.0.0", "jszip": "3.10.1", "koa": "2.15.3", "koa-bodyparser": "4.4.1", @@ -216,7 +218,7 @@ "node-fetch": "2.6.12", "node-forge": "1.3.1", "open": "8.4.2", - "papaparse": "5.4.1", + "papaparse": "5.5.2", "proper-lockfile": "4.1.2", "rxjs": "7.8.1", "tldts": "6.1.74", @@ -228,7 +230,7 @@ }, "apps/desktop": { "name": "@bitwarden/desktop", - "version": "2025.1.4", + "version": "2025.2.2", "hasInstallScript": true, "license": "GPL-3.0" }, @@ -242,7 +244,7 @@ }, "apps/web": { "name": "@bitwarden/web-vault", - "version": "2025.1.2" + "version": "2025.2.1" }, "libs/admin-console": { "name": "@bitwarden/admin-console", @@ -367,14 +369,12 @@ } }, "node_modules/@angular-devkit/architect": { - "version": "0.1901.5", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1901.5.tgz", - "integrity": "sha512-zlRudZx34FkFZnSdaQCjxDleHwbQYNLdBFcLi+FBwt0UXqxmhbEIasK3l/3kCOC3QledrjUzVXgouji+OZ/WGQ==", + "version": "0.1802.12", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.12.tgz", + "integrity": "sha512-bepVb2/GtJppYKaeW8yTGE6egmoWZ7zagFDsmBdbF+BYp+HmeoPsclARcdryBPVq68zedyTRdvhWSUTbw1AYuw==", "dev": true, - "license": "MIT", - "peer": true, "dependencies": { - "@angular-devkit/core": "19.1.5", + "@angular-devkit/core": "18.2.12", "rxjs": "7.8.1" }, "engines": { @@ -388,7 +388,6 @@ "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-18.2.12.tgz", "integrity": "sha512-quVUi7eqTq9OHumQFNl9Y8t2opm8miu4rlYnuF6rbujmmBDvdUvR6trFChueRczl2p5HWqTOr6NPoDGQm8AyNw==", "dev": true, - "license": "MIT", "dependencies": { "@ampproject/remapping": "2.3.0", "@angular-devkit/architect": "0.1802.12", @@ -512,56 +511,11 @@ } } }, - "node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/architect": { - "version": "0.1802.12", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.12.tgz", - "integrity": "sha512-bepVb2/GtJppYKaeW8yTGE6egmoWZ7zagFDsmBdbF+BYp+HmeoPsclARcdryBPVq68zedyTRdvhWSUTbw1AYuw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/core": "18.2.12", - "rxjs": "7.8.1" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/core": { - "version": "18.2.12", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.12.tgz", - "integrity": "sha512-NtB6ypsaDyPE6/fqWOdfTmACs+yK5RqfH5tStEzWFeeDsIEDYKsJ06ypuRep7qTjYus5Rmttk0Ds+cFgz8JdUQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "8.17.1", - "ajv-formats": "3.0.1", - "jsonc-parser": "3.3.1", - "picomatch": "4.0.2", - "rxjs": "7.8.1", - "source-map": "0.7.4" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^3.5.2" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, "node_modules/@angular-devkit/build-angular/node_modules/@babel/core": { "version": "7.25.2", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", "dev": true, - "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.24.7", @@ -602,7 +556,6 @@ "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.3.tgz", "integrity": "sha512-QsYW7UeAaXvLPX9tdVliMJE7MD7M6MLYVTovRTIwhoYQVFHR1rM4wO8wqAezYi3/BpSD+NzVCZ69R6smWiIi8g==", "dev": true, - "license": "MIT", "dependencies": { "@babel/compat-data": "^7.25.2", "@babel/helper-compilation-targets": "^7.25.2", @@ -700,35 +653,17 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" } }, - "node_modules/@angular-devkit/build-angular/node_modules/@types/express": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "node_modules/@angular-devkit/build-angular/node_modules/@discoveryjs/json-ext": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.1.tgz", + "integrity": "sha512-boghen8F0Q8D+0/Q1/1r6DUEieUJ8w2a1gIknExMSHBsJFOr2+0KUfHiVYBvucPwl3+RU5PFBK833FjFCh3BhA==", "dev": true, - "license": "MIT", - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/@types/express-serve-static-core": { - "version": "4.19.6", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", - "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" + "engines": { + "node": ">=14.17.0" } }, "node_modules/@angular-devkit/build-angular/node_modules/babel-loader": { @@ -749,31 +684,6 @@ "webpack": ">=5" } }, - "node_modules/@angular-devkit/build-angular/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, "node_modules/@angular-devkit/build-angular/node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -786,7 +696,6 @@ "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -818,58 +727,30 @@ "node": ">=4.0" } }, - "node_modules/@angular-devkit/build-angular/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "node_modules/@angular-devkit/build-angular/node_modules/http-proxy-middleware": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.3.tgz", + "integrity": "sha512-usY0HG5nyDUwtqpiZdETNbmKtw3QQ1jwYFZ9wi5iHzX2BcILwQKtYDJPo7XHTsu5Z0B2Hj3W9NNnbd+AjFWjqg==", "dev": true, - "license": "ISC", "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" + "@types/http-proxy": "^1.17.15", + "debug": "^4.3.6", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.3", + "is-plain-object": "^5.0.0", + "micromatch": "^4.0.8" }, "engines": { - "node": ">= 6" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@angular-devkit/build-angular/node_modules/immutable": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", - "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==", + "node_modules/@angular-devkit/build-angular/node_modules/ipaddr.js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", "dev": true, - "license": "MIT" - }, - "node_modules/@angular-devkit/build-angular/node_modules/is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", - "dev": true, - "license": "MIT", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 10" } }, "node_modules/@angular-devkit/build-angular/node_modules/is-wsl": { @@ -877,7 +758,6 @@ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", "dev": true, - "license": "MIT", "dependencies": { "is-inside-container": "^1.0.0" }, @@ -888,20 +768,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@angular-devkit/build-angular/node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "node_modules/@angular-devkit/build-angular/node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", "dev": true, - "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/cliui": "^8.0.2" + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" + "engines": { + "node": ">=10" } }, "node_modules/@angular-devkit/build-angular/node_modules/json-parse-even-better-errors": { @@ -911,26 +791,30 @@ "dev": true, "license": "MIT" }, - "node_modules/@angular-devkit/build-angular/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "node_modules/@angular-devkit/build-angular/node_modules/memfs": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.14.1.tgz", + "integrity": "sha512-Fq5CMEth+2iprLJ5mNizRcWuiwRZYjNkUD0zKk224jZunE9CRacTRDK8QLALbMBlNX2y3nY6lKZbesCwDwacig==", "dev": true, - "license": "MIT" - }, - "node_modules/@angular-devkit/build-angular/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" + "dependencies": { + "@jsonjoy.com/json-pack": "^1.0.3", + "@jsonjoy.com/util": "^1.3.0", + "tree-dump": "^1.0.1", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">= 4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + } }, "node_modules/@angular-devkit/build-angular/node_modules/mini-css-extract-plugin": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.0.tgz", "integrity": "sha512-Zs1YsZVfemekSZG+44vBsYTLQORkPMwnlv+aehcxK/NLKC+EGhDB39/YePYYqx/sTk6NnYpuqikhSn7+JIevTA==", "dev": true, - "license": "MIT", "dependencies": { "schema-utils": "^4.0.0", "tapable": "^2.2.1" @@ -951,7 +835,6 @@ "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==", "dev": true, - "license": "MIT", "dependencies": { "default-browser": "^5.2.1", "define-lazy-prop": "^3.0.0", @@ -965,23 +848,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@angular-devkit/build-angular/node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@angular-devkit/build-angular/node_modules/postcss": { "version": "8.4.41", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz", @@ -1001,7 +867,6 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.0.1", @@ -1011,38 +876,11 @@ "node": "^10 || ^12 || >=14" } }, - "node_modules/@angular-devkit/build-angular/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/readdirp/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/@angular-devkit/build-angular/node_modules/rimraf": { "version": "5.0.10", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", "dev": true, - "license": "ISC", "dependencies": { "glob": "^10.3.7" }, @@ -1058,7 +896,6 @@ "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.6.tgz", "integrity": "sha512-ByXE1oLD79GVq9Ht1PeHWCPMPB8XHpBuz1r85oByKHjZY6qV6rWnQovQzXJXuQ/XyE1Oj3iPk3lo28uzaRA2/Q==", "dev": true, - "license": "MIT", "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -1076,7 +913,6 @@ "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-16.0.0.tgz", "integrity": "sha512-n13Z+3rU9A177dk4888czcVFiC8CL9dii4qpXWUg3YIIgZEvi9TCFKjOQcbK0kJM7DJu9VucrZFddvNfYCPwtw==", "dev": true, - "license": "MIT", "dependencies": { "neo-async": "^2.6.2" }, @@ -1159,12 +995,40 @@ } } }, + "node_modules/@angular-devkit/build-angular/node_modules/webpack-dev-middleware": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz", + "integrity": "sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==", + "dev": true, + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^4.6.0", + "mime-types": "^2.1.31", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + } + } + }, "node_modules/@angular-devkit/build-angular/node_modules/webpack-dev-server": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.0.4.tgz", "integrity": "sha512-dljXhUgx3HqKP2d8J/fUMvhxGhzjeNVarDLcbO/EWMSgRizDkxHQDZQaLFL5VJY9tRBj2Gz+rvCEYYvhbqPHNA==", "dev": true, - "license": "MIT", "dependencies": { "@types/bonjour": "^3.5.13", "@types/connect-history-api-fallback": "^1.5.4", @@ -1224,7 +1088,6 @@ "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", "dev": true, - "license": "MIT", "dependencies": { "@types/http-proxy": "^1.17.8", "http-proxy": "^1.18.1", @@ -1271,6 +1134,13 @@ "ajv": "^6.9.1" } }, + "node_modules/@angular-devkit/build-angular/node_modules/webpack/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, "node_modules/@angular-devkit/build-angular/node_modules/webpack/node_modules/schema-utils": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", @@ -1290,12 +1160,25 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/@angular-devkit/build-angular/node_modules/webpack/node_modules/watchpack": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/@angular-devkit/build-webpack": { "version": "0.1802.12", "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1802.12.tgz", "integrity": "sha512-0Z3fdbZVRnjYWE2/VYyfy+uieY+6YZyEp4ylzklVkc+fmLNsnz4Zw6cK1LzzcBqAwKIyh1IdW20Cg7o8b0sONA==", "dev": true, - "license": "MIT", "dependencies": { "@angular-devkit/architect": "0.1802.12", "rxjs": "7.8.1" @@ -1310,28 +1193,11 @@ "webpack-dev-server": "^5.0.2" } }, - "node_modules/@angular-devkit/build-webpack/node_modules/@angular-devkit/architect": { - "version": "0.1802.12", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.12.tgz", - "integrity": "sha512-bepVb2/GtJppYKaeW8yTGE6egmoWZ7zagFDsmBdbF+BYp+HmeoPsclARcdryBPVq68zedyTRdvhWSUTbw1AYuw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/core": "18.2.12", - "rxjs": "7.8.1" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@angular-devkit/build-webpack/node_modules/@angular-devkit/core": { + "node_modules/@angular-devkit/core": { "version": "18.2.12", "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.12.tgz", "integrity": "sha512-NtB6ypsaDyPE6/fqWOdfTmACs+yK5RqfH5tStEzWFeeDsIEDYKsJ06ypuRep7qTjYus5Rmttk0Ds+cFgz8JdUQ==", "dev": true, - "license": "MIT", "dependencies": { "ajv": "8.17.1", "ajv-formats": "3.0.1", @@ -1354,115 +1220,13 @@ } } }, - "node_modules/@angular-devkit/build-webpack/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/@angular-devkit/build-webpack/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "optional": true, - "peer": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@angular-devkit/build-webpack/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/@angular-devkit/build-webpack/node_modules/readdirp/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/@angular-devkit/core": { - "version": "19.1.5", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.1.5.tgz", - "integrity": "sha512-wGKV+i5mCM/Hd/3CsdrIYcVi5G2Wg/D5941bUDXivrbsqHfKVINxAkI3OI1eaD90VnAL8ICrQEoAhh6ni2Umkg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "ajv": "8.17.1", - "ajv-formats": "3.0.1", - "jsonc-parser": "3.3.1", - "picomatch": "4.0.2", - "rxjs": "7.8.1", - "source-map": "0.7.4" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^4.0.0" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, "node_modules/@angular-devkit/schematics": { - "version": "18.2.14", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-18.2.14.tgz", - "integrity": "sha512-mukjZIHHB7gWratq8fZwUq5WZ+1bF4feG/idXr1wgQ+/FqWjs2PP7HDesHVcPymmRulpTyCpB7TNB1O1fgnCpA==", + "version": "18.2.12", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-18.2.12.tgz", + "integrity": "sha512-mMea9txHbnCX5lXLHlo0RAgfhFHDio45/jMsREM2PA8UtVf2S8ltXz7ZwUrUyMQRv8vaSfn4ijDstF4hDMnRgQ==", "dev": true, - "license": "MIT", "dependencies": { - "@angular-devkit/core": "18.2.14", + "@angular-devkit/core": "18.2.12", "jsonc-parser": "3.3.1", "magic-string": "0.30.11", "ora": "5.4.1", @@ -1474,112 +1238,11 @@ "yarn": ">= 1.13.0" } }, - "node_modules/@angular-devkit/schematics/node_modules/@angular-devkit/core": { - "version": "18.2.14", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.14.tgz", - "integrity": "sha512-UGIGOjXuOyCW+5S4tINu7e6LOu738CmTw3h7Ui1I8OzdTIYJcYJrei8sgrwDwOYADRal+p0MeMlnykH3TM5XBA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "8.17.1", - "ajv-formats": "3.0.1", - "jsonc-parser": "3.3.1", - "picomatch": "4.0.2", - "rxjs": "7.8.1", - "source-map": "0.7.4" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^3.5.2" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/@angular-devkit/schematics/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/@angular-devkit/schematics/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "optional": true, - "peer": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@angular-devkit/schematics/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/@angular-devkit/schematics/node_modules/readdirp/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/@angular-eslint/builder": { "version": "18.4.3", "resolved": "https://registry.npmjs.org/@angular-eslint/builder/-/builder-18.4.3.tgz", "integrity": "sha512-NzmrXlr7GFE+cjwipY/CxBscZXNqnuK0us1mO6Z2T6MeH6m+rRcdlY/rZyKoRniyNNvuzl6vpEsfMIMmnfebrA==", "dev": true, - "license": "MIT", "dependencies": { "@angular-devkit/architect": ">= 0.1800.0 < 0.1900.0", "@angular-devkit/core": ">= 18.0.0 < 19.0.0" @@ -1589,135 +1252,17 @@ "typescript": "*" } }, - "node_modules/@angular-eslint/builder/node_modules/@angular-devkit/architect": { - "version": "0.1802.14", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.14.tgz", - "integrity": "sha512-eplaGCXSlPwf1f4XwyzsYTd8/lJ0/Adm6XsODsBxvkZlIpLcps80/h2lH5MVJpoDREzIFu1BweDpYCoNK5yYZg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/core": "18.2.14", - "rxjs": "7.8.1" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@angular-eslint/builder/node_modules/@angular-devkit/core": { - "version": "18.2.14", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.14.tgz", - "integrity": "sha512-UGIGOjXuOyCW+5S4tINu7e6LOu738CmTw3h7Ui1I8OzdTIYJcYJrei8sgrwDwOYADRal+p0MeMlnykH3TM5XBA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "8.17.1", - "ajv-formats": "3.0.1", - "jsonc-parser": "3.3.1", - "picomatch": "4.0.2", - "rxjs": "7.8.1", - "source-map": "0.7.4" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^3.5.2" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/@angular-eslint/builder/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/@angular-eslint/builder/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "optional": true, - "peer": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@angular-eslint/builder/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/@angular-eslint/builder/node_modules/readdirp/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/@angular-eslint/bundled-angular-compiler": { "version": "18.4.3", "resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-18.4.3.tgz", "integrity": "sha512-zdrA8mR98X+U4YgHzUKmivRU+PxzwOL/j8G7eTOvBuq8GPzsP+hvak+tyxlgeGm9HsvpFj9ERHLtJ0xDUPs8fg==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/@angular-eslint/eslint-plugin": { "version": "18.4.3", "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin/-/eslint-plugin-18.4.3.tgz", "integrity": "sha512-AyJbupiwTBR81P6T59v+aULEnPpZBCBxL2S5QFWfAhNCwWhcof4GihvdK2Z87yhvzDGeAzUFSWl/beJfeFa+PA==", "dev": true, - "license": "MIT", "dependencies": { "@angular-eslint/bundled-angular-compiler": "18.4.3", "@angular-eslint/utils": "18.4.3" @@ -1733,7 +1278,6 @@ "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-18.4.3.tgz", "integrity": "sha512-ijGlX2N01ayMXTpeQivOA31AszO8OEbu9ZQUCxnu9AyMMhxyi2q50bujRChAvN9YXQfdQtbxuajxV6+aiWb5BQ==", "dev": true, - "license": "MIT", "dependencies": { "@angular-eslint/bundled-angular-compiler": "18.4.3", "@angular-eslint/utils": "18.4.3", @@ -1747,12 +1291,20 @@ "typescript": "*" } }, + "node_modules/@angular-eslint/eslint-plugin-template/node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/@angular-eslint/schematics": { "version": "18.4.3", "resolved": "https://registry.npmjs.org/@angular-eslint/schematics/-/schematics-18.4.3.tgz", "integrity": "sha512-D5maKn5e6n58+8n7jLFLD4g+RGPOPeDSsvPc1sqial5tEKLxAJQJS9WZ28oef3bhkob6C60D+1H0mMmEEVvyVA==", "dev": true, - "license": "MIT", "dependencies": { "@angular-devkit/core": ">= 18.0.0 < 19.0.0", "@angular-devkit/schematics": ">= 18.0.0 < 19.0.0", @@ -1763,104 +1315,13 @@ "strip-json-comments": "3.1.1" } }, - "node_modules/@angular-eslint/schematics/node_modules/@angular-devkit/core": { - "version": "18.2.14", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.14.tgz", - "integrity": "sha512-UGIGOjXuOyCW+5S4tINu7e6LOu738CmTw3h7Ui1I8OzdTIYJcYJrei8sgrwDwOYADRal+p0MeMlnykH3TM5XBA==", + "node_modules/@angular-eslint/schematics/node_modules/ignore": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-6.0.2.tgz", + "integrity": "sha512-InwqeHHN2XpumIkMvpl/DCJVrAHgCsG5+cn1XlnLWGwtZBm8QJfSusItfrwx81CTp5agNZqpKU2J/ccC5nGT4A==", "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "8.17.1", - "ajv-formats": "3.0.1", - "jsonc-parser": "3.3.1", - "picomatch": "4.0.2", - "rxjs": "7.8.1", - "source-map": "0.7.4" - }, "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^3.5.2" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/@angular-eslint/schematics/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/@angular-eslint/schematics/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "optional": true, - "peer": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@angular-eslint/schematics/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/@angular-eslint/schematics/node_modules/readdirp/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "node": ">= 4" } }, "node_modules/@angular-eslint/template-parser": { @@ -1868,7 +1329,6 @@ "resolved": "https://registry.npmjs.org/@angular-eslint/template-parser/-/template-parser-18.4.3.tgz", "integrity": "sha512-JZMPtEB8yNip3kg4WDEWQyObSo2Hwf+opq2ElYuwe85GQkGhfJSJ2CQYo4FSwd+c5MUQAqESNRg9QqGYauDsiw==", "dev": true, - "license": "MIT", "dependencies": { "@angular-eslint/bundled-angular-compiler": "18.4.3", "eslint-scope": "^8.0.2" @@ -1883,7 +1343,6 @@ "resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-18.4.3.tgz", "integrity": "sha512-w0bJ9+ELAEiPBSTPPm9bvDngfu1d8JbzUhvs2vU+z7sIz/HMwUZT5S4naypj2kNN0gZYGYrW0lt+HIbW87zTAQ==", "dev": true, - "license": "MIT", "dependencies": { "@angular-eslint/bundled-angular-compiler": "18.4.3" }, @@ -1897,7 +1356,6 @@ "version": "18.2.13", "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-18.2.13.tgz", "integrity": "sha512-rG5J5Ek5Hg+Tz2NjkNOaG6PupiNK/lPfophXpsR1t/nWujqnMWX2krahD/i6kgD+jNWNKCJCYSOVvCx/BHOtKA==", - "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -1913,7 +1371,6 @@ "resolved": "https://registry.npmjs.org/@angular/build/-/build-18.2.12.tgz", "integrity": "sha512-4Ohz+OSILoL+cCAQ4UTiCT5v6pctu3fXNoNpTEUK46OmxELk9jDITO5rNyNS7TxBn9wY69kjX5VcDf7MenquFQ==", "dev": true, - "license": "MIT", "dependencies": { "@ampproject/remapping": "2.3.0", "@angular-devkit/architect": "0.1802.12", @@ -1977,56 +1434,11 @@ } } }, - "node_modules/@angular/build/node_modules/@angular-devkit/architect": { - "version": "0.1802.12", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.12.tgz", - "integrity": "sha512-bepVb2/GtJppYKaeW8yTGE6egmoWZ7zagFDsmBdbF+BYp+HmeoPsclARcdryBPVq68zedyTRdvhWSUTbw1AYuw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/core": "18.2.12", - "rxjs": "7.8.1" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@angular/build/node_modules/@angular-devkit/core": { - "version": "18.2.12", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.12.tgz", - "integrity": "sha512-NtB6ypsaDyPE6/fqWOdfTmACs+yK5RqfH5tStEzWFeeDsIEDYKsJ06ypuRep7qTjYus5Rmttk0Ds+cFgz8JdUQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "8.17.1", - "ajv-formats": "3.0.1", - "jsonc-parser": "3.3.1", - "picomatch": "4.0.2", - "rxjs": "7.8.1", - "source-map": "0.7.4" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^3.5.2" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, "node_modules/@angular/build/node_modules/@babel/core": { "version": "7.25.2", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", "dev": true, - "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.24.7", @@ -2057,87 +1469,359 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" } }, - "node_modules/@angular/build/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "node_modules/@angular/build/node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz", + "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==", "dev": true, - "license": "MIT", "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { - "node": ">= 8.10.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz", + "integrity": "sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-android-arm64": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz", + "integrity": "sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz", + "integrity": "sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-darwin-x64": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz", + "integrity": "sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz", + "integrity": "sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz", + "integrity": "sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz", + "integrity": "sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz", + "integrity": "sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz", + "integrity": "sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz", + "integrity": "sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz", + "integrity": "sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz", + "integrity": "sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz", + "integrity": "sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz", + "integrity": "sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz", + "integrity": "sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz", + "integrity": "sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@angular/build/node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@angular/build/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "engines": { + "node": ">=12" }, "funding": { - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@angular/build/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@angular/build/node_modules/cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "dev": true, + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@angular/build/node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, - "license": "MIT" + "dev": true }, - "node_modules/@angular/build/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/@angular/build/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true + }, + "node_modules/@angular/build/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true + }, + "node_modules/@angular/build/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, "engines": { - "node": ">= 6" - } - }, - "node_modules/@angular/build/node_modules/immutable": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", - "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@angular/build/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/@angular/build/node_modules/readdirp/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@angular/build/node_modules/listr2": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.4.tgz", + "integrity": "sha512-opevsywziHd3zHCVQGAj8zu+Z3yHNkkoYhWIGnq54RrCVwLz0MozotJEDnKsIBLvkfLGN6BLOyAeRrYI0pKA4g==", + "dev": true, + "dependencies": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@angular/build/node_modules/rollup": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.4.tgz", + "integrity": "sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.22.4", + "@rollup/rollup-android-arm64": "4.22.4", + "@rollup/rollup-darwin-arm64": "4.22.4", + "@rollup/rollup-darwin-x64": "4.22.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.22.4", + "@rollup/rollup-linux-arm-musleabihf": "4.22.4", + "@rollup/rollup-linux-arm64-gnu": "4.22.4", + "@rollup/rollup-linux-arm64-musl": "4.22.4", + "@rollup/rollup-linux-powerpc64le-gnu": "4.22.4", + "@rollup/rollup-linux-riscv64-gnu": "4.22.4", + "@rollup/rollup-linux-s390x-gnu": "4.22.4", + "@rollup/rollup-linux-x64-gnu": "4.22.4", + "@rollup/rollup-linux-x64-musl": "4.22.4", + "@rollup/rollup-win32-arm64-msvc": "4.22.4", + "@rollup/rollup-win32-ia32-msvc": "4.22.4", + "@rollup/rollup-win32-x64-msvc": "4.22.4", + "fsevents": "~2.3.2" } }, "node_modules/@angular/build/node_modules/sass": { @@ -2145,7 +1829,6 @@ "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.6.tgz", "integrity": "sha512-ByXE1oLD79GVq9Ht1PeHWCPMPB8XHpBuz1r85oByKHjZY6qV6rWnQovQzXJXuQ/XyE1Oj3iPk3lo28uzaRA2/Q==", "dev": true, - "license": "MIT", "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -2158,11 +1841,75 @@ "node": ">=14.0.0" } }, + "node_modules/@angular/build/node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/@angular/build/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@angular/build/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@angular/build/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/@angular/cdk": { "version": "18.2.14", "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-18.2.14.tgz", "integrity": "sha512-vDyOh1lwjfVk9OqoroZAP8pf3xxKUvyl+TVR8nJxL4c5fOfUFkD7l94HaanqKSRwJcI2xiztuu92IVoHn8T33Q==", - "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -2180,7 +1927,6 @@ "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-18.2.12.tgz", "integrity": "sha512-xhuZ/b7IhqNw1MgXf+arWf4x+GfUSt/IwbdWU4+CO8A7h0Y46zQywouP/KUK3cMQZfVdHdciTBvlpF3vFacA6Q==", "dev": true, - "license": "MIT", "dependencies": { "@angular-devkit/architect": "0.1802.12", "@angular-devkit/core": "18.2.12", @@ -2209,146 +1955,156 @@ "yarn": ">= 1.13.0" } }, - "node_modules/@angular/cli/node_modules/@angular-devkit/architect": { - "version": "0.1802.12", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.12.tgz", - "integrity": "sha512-bepVb2/GtJppYKaeW8yTGE6egmoWZ7zagFDsmBdbF+BYp+HmeoPsclARcdryBPVq68zedyTRdvhWSUTbw1AYuw==", + "node_modules/@angular/cli/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "dev": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/core": "18.2.12", - "rxjs": "7.8.1" - }, "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@angular/cli/node_modules/@angular-devkit/core": { - "version": "18.2.12", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.12.tgz", - "integrity": "sha512-NtB6ypsaDyPE6/fqWOdfTmACs+yK5RqfH5tStEzWFeeDsIEDYKsJ06ypuRep7qTjYus5Rmttk0Ds+cFgz8JdUQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "8.17.1", - "ajv-formats": "3.0.1", - "jsonc-parser": "3.3.1", - "picomatch": "4.0.2", - "rxjs": "7.8.1", - "source-map": "0.7.4" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^3.5.2" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/@angular/cli/node_modules/@angular-devkit/schematics": { - "version": "18.2.12", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-18.2.12.tgz", - "integrity": "sha512-mMea9txHbnCX5lXLHlo0RAgfhFHDio45/jMsREM2PA8UtVf2S8ltXz7ZwUrUyMQRv8vaSfn4ijDstF4hDMnRgQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/core": "18.2.12", - "jsonc-parser": "3.3.1", - "magic-string": "0.30.11", - "ora": "5.4.1", - "rxjs": "7.8.1" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@angular/cli/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" + "node": ">=12" }, "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/@angular/cli/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/@angular/cli/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, - "license": "ISC", - "optional": true, - "peer": true, - "dependencies": { - "is-glob": "^4.0.1" - }, "engines": { - "node": ">= 6" - } - }, - "node_modules/@angular/cli/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/@angular/cli/node_modules/readdirp/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=8.6" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@angular/cli/node_modules/cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "dev": true, + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@angular/cli/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true + }, + "node_modules/@angular/cli/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true + }, + "node_modules/@angular/cli/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@angular/cli/node_modules/listr2": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.4.tgz", + "integrity": "sha512-opevsywziHd3zHCVQGAj8zu+Z3yHNkkoYhWIGnq54RrCVwLz0MozotJEDnKsIBLvkfLGN6BLOyAeRrYI0pKA4g==", + "dev": true, + "dependencies": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@angular/cli/node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/@angular/cli/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@angular/cli/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@angular/cli/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/@angular/common": { "version": "18.2.13", "resolved": "https://registry.npmjs.org/@angular/common/-/common-18.2.13.tgz", "integrity": "sha512-4ZqrNp1PoZo7VNvW+sbSc2CB2axP1sCH2wXl8B0wdjsj8JY1hF1OhuugwhpAHtGxqewed2kCXayE+ZJqSTV4jw==", - "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -2364,7 +2120,6 @@ "version": "18.2.13", "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-18.2.13.tgz", "integrity": "sha512-TzWcrkopyjFF+WeDr2cRe8CcHjU72KfYV3Sm2TkBkcXrkYX5sDjGWrBGrG3hRB4e4okqchrOCvm1MiTdy2vKMA==", - "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -2385,7 +2140,6 @@ "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-18.2.13.tgz", "integrity": "sha512-DBSh4AQwkiJDSiVvJATRmjxf6wyUs9pwQLgaFdSlfuTRO+sdb0J2z1r3BYm8t0IqdoyXzdZq2YCH43EmyvD71g==", "dev": true, - "license": "MIT", "dependencies": { "@babel/core": "7.25.2", "@jridgewell/sourcemap-codec": "^1.4.14", @@ -2414,7 +2168,6 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", "dev": true, - "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.24.7", @@ -2444,24 +2197,49 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/@angular/compiler-cli/node_modules/@babel/core/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" } }, + "node_modules/@angular/compiler-cli/node_modules/chokidar": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", + "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", + "dev": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular/compiler-cli/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@angular/core": { "version": "18.2.13", "resolved": "https://registry.npmjs.org/@angular/core/-/core-18.2.13.tgz", "integrity": "sha512-8mbWHMgO95OuFV1Ejy4oKmbe9NOJ3WazQf/f7wks8Bck7pcihd0IKhlPBNjFllbF5o+04EYSwFhEtvEgjMDClA==", - "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -2477,7 +2255,6 @@ "version": "18.2.13", "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-18.2.13.tgz", "integrity": "sha512-A67D867fu3DSBhdLWWZl/F5pr7v2+dRM2u3U7ZJ0ewh4a+sv+0yqWdJW+a8xIoiHxS+btGEJL2qAKJiH+MCFfg==", - "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -2495,7 +2272,6 @@ "version": "18.2.13", "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-18.2.13.tgz", "integrity": "sha512-tu7ZzY6qD3ATdWFzcTcsAKe7M6cJeWbT/4/bF9unyGO3XBPcNYDKoiz10+7ap2PUd0fmPwvuvTvSNJiFEBnB8Q==", - "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -2517,7 +2293,6 @@ "version": "18.2.13", "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-18.2.13.tgz", "integrity": "sha512-kbQCf9+8EpuJC7buBxhSiwBtXvjAwAKh6MznD6zd2pyCYqfY6gfRCZQRtK59IfgVtKmEONWI9grEyNIRoTmqJg==", - "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -2535,7 +2310,6 @@ "version": "18.2.13", "resolved": "https://registry.npmjs.org/@angular/router/-/router-18.2.13.tgz", "integrity": "sha512-VKmfgi/r/CkyBq9nChQ/ptmfu0JT/8ONnLVJ5H+SkFLRYJcIRyHLKjRihMCyVm6xM5yktOdCaW73NTQrFz7+bg==", - "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -2550,23 +2324,26 @@ } }, "node_modules/@asamuzakjp/css-color": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-2.8.3.tgz", - "integrity": "sha512-GIc76d9UI1hCvOATjZPyHFmE5qhRccp3/zGfMPapK3jBi+yocEzp6BBB0UnfRYP9NP4FANqUZYb0hnfs3TM3hw==", + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-2.8.2.tgz", + "integrity": "sha512-RtWv9jFN2/bLExuZgFFZ0I3pWWeezAHGgrmjqGGWclATl1aDe3yhCUaI0Ilkp6OCk9zX7+FjvDasEX8Q9Rxc5w==", "license": "MIT", "dependencies": { "@csstools/css-calc": "^2.1.1", "@csstools/css-color-parser": "^3.0.7", "@csstools/css-parser-algorithms": "^3.0.4", "@csstools/css-tokenizer": "^3.0.3", - "lru-cache": "^10.4.3" + "lru-cache": "^11.0.2" } }, "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "license": "ISC" + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.2.tgz", + "integrity": "sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==", + "license": "ISC", + "engines": { + "node": "20 || >=22" + } }, "node_modules/@babel/code-frame": { "version": "7.26.2", @@ -2583,9 +2360,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.5.tgz", - "integrity": "sha512-XvcZi1KWf88RVbF9wn8MN6tYFloU5qX8KjuF3E1PVBmJ9eypXfs4GRiJwLuTZL0iSnJUKn1BFPa5BPZZJyFzPg==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.2.tgz", + "integrity": "sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -2621,12 +2398,40 @@ "url": "https://opencollective.com/babel" } }, + "node_modules/@babel/core/node_modules/@babel/generator": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", + "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.26.2", + "@babel/types": "^7.26.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/core/node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "license": "MIT" }, + "node_modules/@babel/core/node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/@babel/core/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -2640,7 +2445,7 @@ "version": "7.25.0", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.0.tgz", "integrity": "sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==", - "license": "MIT", + "dev": true, "dependencies": { "@babel/types": "^7.25.0", "@jridgewell/gen-mapping": "^0.3.5", @@ -2656,7 +2461,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/types": "^7.24.7" }, @@ -2664,13 +2468,27 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz", - "integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==", + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.25.9.tgz", + "integrity": "sha512-C47lC7LIDCnz0h4vai/tpNOI95tCd5ZT3iBt/DBH5lXKHZsyNQv18yf1wIIg2ntiQNgmAvA+DgZ82iW8Qdym8g==", + "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.26.5", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.25.9", "@babel/helper-validator-option": "^7.25.9", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", @@ -2681,9 +2499,9 @@ } }, "node_modules/@babel/helper-compilation-targets/node_modules/browserslist": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", - "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", "funding": [ { "type": "opencollective", @@ -2700,9 +2518,9 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001688", - "electron-to-chromium": "^1.5.73", - "node-releases": "^2.0.19", + "caniuse-lite": "^1.0.30001669", + "electron-to-chromium": "^1.5.41", + "node-releases": "^2.0.18", "update-browserslist-db": "^1.1.1" }, "bin": { @@ -2767,14 +2585,14 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz", - "integrity": "sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.9.tgz", + "integrity": "sha512-ORPNZ3h6ZRkOyAa/SaHU+XsLZr0UQzRwuDQ0cczIA17nAzZ+85G5cVkOJIj7QavLZGSe8QXUmNFxSZzjcZF9bw==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.9", - "regexpu-core": "^6.2.0", + "regexpu-core": "^6.1.1", "semver": "^6.3.1" }, "engines": { @@ -2922,15 +2740,15 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.26.5.tgz", - "integrity": "sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.9.tgz", + "integrity": "sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-member-expression-to-functions": "^7.25.9", "@babel/helper-optimise-call-expression": "^7.25.9", - "@babel/traverse": "^7.26.5" + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2939,6 +2757,19 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@babel/helper-simple-access": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.9.tgz", + "integrity": "sha512-c6WHXuiaRsJTyHYLJV75t9IqsmTbItYfdj99PnzYGQZkYKvan5/2jKJ7gu31J3/BJ/A18grImSPModuyG/Eo0Q==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", @@ -2958,7 +2789,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/types": "^7.24.7" }, @@ -3009,25 +2839,25 @@ } }, "node_modules/@babel/helpers": { - "version": "7.26.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.7.tgz", - "integrity": "sha512-8NHiL98vsi0mbPQmYAGWwfcFaOy4j2HY49fXJCfuDcdE7fMIsH9a7GdaeXpIBsbT7307WU8KCMp5pUVDNL4f9A==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", "license": "MIT", "dependencies": { "@babel/template": "^7.25.9", - "@babel/types": "^7.26.7" + "@babel/types": "^7.26.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.26.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.7.tgz", - "integrity": "sha512-kEvgGGgEjRUutvdVvZhbn/BxVt+5VSpwXz1j3WYXQbXDo8KzFOPNG2GQbdAiNq8g6wn1yKk7C/qrke03a84V+w==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", "license": "MIT", "dependencies": { - "@babel/types": "^7.26.7" + "@babel/types": "^7.26.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -3248,13 +3078,13 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz", - "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", + "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -3471,7 +3301,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.0.tgz", "integrity": "sha512-uaIi2FdqzjpAMvVqvB51S42oC2JEVgh0LDsGfZVDysWE8LrJtQC2jvKmOqEYThKyB7bDEb7BP1GYWDm7tABA0Q==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.8", "@babel/helper-remap-async-to-generator": "^7.25.0", @@ -3490,7 +3319,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz", "integrity": "sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.24.7", "@babel/helper-plugin-utils": "^7.24.7", @@ -3504,13 +3332,13 @@ } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.26.5.tgz", - "integrity": "sha512-chuTSY+hq09+/f5lMj8ZSYgCFpppV2CbYrhNFJ1BFoXpiWPnnAb7R0MqrafCpN8E1+YRrtM1MXZHJdIx8B6rMQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.9.tgz", + "integrity": "sha512-toHc9fzab0ZfenFpsyYinOX0J/5dgJVA2fm64xPewu7CoYHWEivIWKxkK2rMi4r3yQqLnVmheMXRdG+k239CgA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.26.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -3703,12 +3531,13 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz", - "integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.25.9.tgz", + "integrity": "sha512-KRhdhlVk2nObA5AYa7QMgTMTVJdfHprfpAk4DjZVtllqRg9qarilstTKEhpVjyt+Npi8ThRyiV8176Am3CodPA==", "dev": true, "license": "MIT", "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { @@ -3851,13 +3680,14 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz", - "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.25.9.tgz", + "integrity": "sha512-dwh2Ol1jWwL2MgkCzUSOvfmKElqQcuswAZypBSUsScMXvgdT8Ekq5YA6TtqpTVWH+4903NmboMuH1o9i8Rxlyg==", "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.26.0", - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-simple-access": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -3936,13 +3766,13 @@ } }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.26.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.26.6.tgz", - "integrity": "sha512-CKW8Vu+uUZneQCPtXmSBUC6NCAUdya26hWCElAWh5mVSlSRsmiCPUUDKb3Z0szng1hiAJa098Hkhg9o4SE35Qw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.9.tgz", + "integrity": "sha512-ENfftpLZw5EItALAD4WsY/KUWvhUlZndm5GC7G3evUsVeSJB6p0pBeLQUnRnBCBx7zV0RKQjR9kCuwrsIrjWog==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.26.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -4153,7 +3983,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.7.tgz", "integrity": "sha512-YqXjrk4C+a1kZjewqt+Mmu2UuV1s07y8kqcUf4qYLnoqemhR4gRQikhdAhSVJioMjVTu6Mo6pAbaypEA3jY6fw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.24.7", "@babel/helper-plugin-utils": "^7.24.7", @@ -4174,7 +4003,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -4245,13 +4073,13 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.26.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.26.7.tgz", - "integrity": "sha512-jfoTXXZTgGg36BmhqT3cAYK5qkmqvJpvNrPhaK/52Vgjhw4Rq29s9UqpWWV0D6yuRmgiFH/BUVlkl96zJWqnaw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz", + "integrity": "sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.26.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -4423,6 +4251,42 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/preset-env/node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz", + "integrity": "sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz", + "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/preset-env/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -4452,7 +4316,6 @@ "version": "7.25.0", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz", "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==", - "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -4475,16 +4338,16 @@ } }, "node_modules/@babel/traverse": { - "version": "7.26.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.7.tgz", - "integrity": "sha512-1x1sgeyRLC3r5fQOM0/xtQKsYjyxmFjaOrLJNtZ81inNjyJHGIolTULPiSc/2qe1/qfpFLisLQYFnnZl7QoedA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", + "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.5", - "@babel/parser": "^7.26.7", + "@babel/code-frame": "^7.25.9", + "@babel/generator": "^7.25.9", + "@babel/parser": "^7.25.9", "@babel/template": "^7.25.9", - "@babel/types": "^7.26.7", + "@babel/types": "^7.25.9", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -4493,13 +4356,13 @@ } }, "node_modules/@babel/traverse/node_modules/@babel/generator": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.5.tgz", - "integrity": "sha512-2caSP6fN9I7HOe6nqhtft7V4g7/V/gfDsC3Ag4W7kEzzvRGKqiv0pu0HogPiZ3KaVSoNDhUws6IJjDjpfmYIXw==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", + "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.26.5", - "@babel/types": "^7.26.5", + "@babel/parser": "^7.26.2", + "@babel/types": "^7.26.0", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" @@ -4509,9 +4372,9 @@ } }, "node_modules/@babel/traverse/node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", "license": "MIT", "bin": { "jsesc": "bin/jsesc" @@ -4521,9 +4384,9 @@ } }, "node_modules/@babel/types": { - "version": "7.26.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.7.tgz", - "integrity": "sha512-t8kDRGrKXyp6+tjUh7hw2RLyclsW4TRoRvRHtSyAX9Bb5ldlFh+90YAYY6awRXrlB4G5G2izNeGySpATlFzmOg==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", + "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.25.9", @@ -4842,14 +4705,14 @@ } }, "node_modules/@compodoc/compodoc/node_modules/@babel/generator": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.5.tgz", - "integrity": "sha512-2caSP6fN9I7HOe6nqhtft7V4g7/V/gfDsC3Ag4W7kEzzvRGKqiv0pu0HogPiZ3KaVSoNDhUws6IJjDjpfmYIXw==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", + "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.26.5", - "@babel/types": "^7.26.5", + "@babel/parser": "^7.26.2", + "@babel/types": "^7.26.0", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" @@ -4858,22 +4721,6 @@ "node": ">=6.9.0" } }, - "node_modules/@compodoc/compodoc/node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", - "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@compodoc/compodoc/node_modules/@babel/plugin-transform-async-generator-functions": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz", @@ -5020,6 +4867,58 @@ "semver": "bin/semver.js" } }, + "node_modules/@compodoc/compodoc/node_modules/cheerio": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", + "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "htmlparser2": "^8.0.1", + "parse5": "^7.0.0", + "parse5-htmlparser2-tree-adapter": "^7.0.0" + }, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/@compodoc/compodoc/node_modules/chokidar": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", + "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@compodoc/compodoc/node_modules/chokidar/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@compodoc/compodoc/node_modules/commander": { "version": "12.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", @@ -5037,25 +4936,50 @@ "dev": true, "license": "MIT" }, - "node_modules/@compodoc/compodoc/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/@compodoc/compodoc/node_modules/glob": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz", + "integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==", "dev": true, "license": "ISC", - "optional": true, - "peer": true, "dependencies": { - "is-glob": "^4.0.1" + "foreground-child": "^3.1.0", + "jackspeak": "^4.0.1", + "minimatch": "^10.0.0", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" }, "engines": { - "node": ">= 6" + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@compodoc/compodoc/node_modules/jackspeak": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.2.tgz", + "integrity": "sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@compodoc/compodoc/node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", "dev": true, "license": "MIT", "bin": { @@ -5065,34 +4989,61 @@ "node": ">=6" } }, - "node_modules/@compodoc/compodoc/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "node_modules/@compodoc/compodoc/node_modules/lru-cache": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.2.tgz", + "integrity": "sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==", "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "picomatch": "^2.2.1" - }, + "license": "ISC", "engines": { - "node": ">=8.10.0" + "node": "20 || >=22" } }, - "node_modules/@compodoc/compodoc/node_modules/readdirp/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "node_modules/@compodoc/compodoc/node_modules/minimatch": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", + "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", "dev": true, - "license": "MIT", - "optional": true, - "peer": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, "engines": { - "node": ">=8.6" + "node": "20 || >=22" }, "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@compodoc/compodoc/node_modules/path-scurry": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", + "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@compodoc/compodoc/node_modules/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" } }, "node_modules/@compodoc/live-server": { @@ -5124,44 +5075,6 @@ "node": ">=0.10.0" } }, - "node_modules/@compodoc/live-server/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/@compodoc/live-server/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/@compodoc/live-server/node_modules/open": { "version": "8.4.0", "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz", @@ -5180,32 +5093,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@compodoc/live-server/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/@compodoc/live-server/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, "node_modules/@compodoc/ngd-core": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/@compodoc/ngd-core/-/ngd-core-2.1.1.tgz", @@ -5399,20 +5286,10 @@ "dev": true, "license": "MIT" }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.1.tgz", - "integrity": "sha512-boghen8F0Q8D+0/Q1/1r6DUEieUJ8w2a1gIknExMSHBsJFOr2+0KUfHiVYBvucPwl3+RU5PFBK833FjFCh3BhA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.17.0" - } - }, "node_modules/@electron/asar": { - "version": "3.2.18", - "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.2.18.tgz", - "integrity": "sha512-2XyvMe3N3Nrs8cV39IKELRHTYUWFKrmqqSY1U+GMlc0jvqjIVnoxhNd2H4JolWQncbJi1DCvb5TNxZuI2fEjWg==", + "version": "3.2.15", + "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.2.15.tgz", + "integrity": "sha512-AerUbRZpkDVRs58WP32t4U2bx85sfwRkQI8RMIEi6s2NBE++sgjsgAAMtXvnfTISKUkXo386pxFW7sa7WtMCrw==", "dev": true, "license": "MIT", "dependencies": { @@ -5948,74 +5825,6 @@ "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", "license": "MIT" }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.0.tgz", - "integrity": "sha512-3sG8Zwa5fMcA9bgqB8AfWPQ+HFke6uD3h1s3RIwUNK8EG7a4buxvuFTs3j1IMs2NXAk9F30C/FF4vxRgQCcmoQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.0.tgz", - "integrity": "sha512-+KuOHTKKyIKgEEqKbGTK8W7mPp+hKinbMBeEnNzjJGyFcWsfrXjSTNluJHCY1RqhxFurdD8uNXQDei7qDlR6+g==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.0.tgz", - "integrity": "sha512-EuHFUYkAVfU4qBdyivULuu03FhJO4IJN9PGuABGrFy4vUuzk91P2d+npxHcFdpUnfYKy0PuV+n6bKIpHOB3prQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.0.tgz", - "integrity": "sha512-WRrmKidLoKDl56LsbBMhzTTBxrsVwTKdNbKDalbEZr0tcsBgCLbEtoNthOW6PX942YiYq8HzEnb4yWQMLQuipQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, "node_modules/@esbuild/darwin-arm64": { "version": "0.23.0", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.0.tgz", @@ -6024,7 +5833,6 @@ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "darwin" @@ -6033,329 +5841,6 @@ "node": ">=18" } }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.0.tgz", - "integrity": "sha512-IMQ6eme4AfznElesHUPDZ+teuGwoRmVuuixu7sv92ZkdQcPbsNHzutd+rAfaBKo8YK3IrBEi9SLLKWJdEvJniQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.0.tgz", - "integrity": "sha512-0muYWCng5vqaxobq6LB3YNtevDFSAZGlgtLoAc81PjUfiFz36n4KMpwhtAd4he8ToSI3TGyuhyx5xmiWNYZFyw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.0.tgz", - "integrity": "sha512-XKDVu8IsD0/q3foBzsXGt/KjD/yTKBCIwOHE1XwiXmrRwrX6Hbnd5Eqn/WvDekddK21tfszBSrE/WMaZh+1buQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.0.tgz", - "integrity": "sha512-SEELSTEtOFu5LPykzA395Mc+54RMg1EUgXP+iw2SJ72+ooMwVsgfuwXo5Fn0wXNgWZsTVHwY2cg4Vi/bOD88qw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.0.tgz", - "integrity": "sha512-j1t5iG8jE7BhonbsEg5d9qOYcVZv/Rv6tghaXM/Ug9xahM0nX/H2gfu6X6z11QRTMT6+aywOMA8TDkhPo8aCGw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.0.tgz", - "integrity": "sha512-P7O5Tkh2NbgIm2R6x1zGJJsnacDzTFcRWZyTTMgFdVit6E98LTxO+v8LCCLWRvPrjdzXHx9FEOA8oAZPyApWUA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.0.tgz", - "integrity": "sha512-InQwepswq6urikQiIC/kkx412fqUZudBO4SYKu0N+tGhXRWUqAx+Q+341tFV6QdBifpjYgUndV1hhMq3WeJi7A==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.0.tgz", - "integrity": "sha512-J9rflLtqdYrxHv2FqXE2i1ELgNjT+JFURt/uDMoPQLcjWQA5wDKgQA4t/dTqGa88ZVECKaD0TctwsUfHbVoi4w==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.0.tgz", - "integrity": "sha512-cShCXtEOVc5GxU0fM+dsFD10qZ5UpcQ8AM22bYj0u/yaAykWnqXJDpd77ublcX6vdDsWLuweeuSNZk4yUxZwtw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.0.tgz", - "integrity": "sha512-HEtaN7Y5UB4tZPeQmgz/UhzoEyYftbMXrBCUjINGjh3uil+rB/QzzpMshz3cNUxqXN7Vr93zzVtpIDL99t9aRw==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.0.tgz", - "integrity": "sha512-WDi3+NVAuyjg/Wxi+o5KPqRbZY0QhI9TjrEEm+8dmpY9Xir8+HE/HNx2JoLckhKbFopW0RdO2D72w8trZOV+Wg==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.0.tgz", - "integrity": "sha512-a3pMQhUEJkITgAw6e0bWA+F+vFtCciMjW/LPtoj99MhVt+Mfb6bbL9hu2wmTZgNd994qTAEw+U/r6k3qHWWaOQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.0.tgz", - "integrity": "sha512-cRK+YDem7lFTs2Q5nEv/HHc4LnrfBCbH5+JHu6wm2eP+d8OZNoSMYgPZJq78vqQ9g+9+nMuIsAO7skzphRXHyw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.0.tgz", - "integrity": "sha512-suXjq53gERueVWu0OKxzWqk7NxiUWSUlrxoZK7usiF50C6ipColGR5qie2496iKGYNLhDZkPxBI3erbnYkU0rQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.0.tgz", - "integrity": "sha512-6p3nHpby0DM/v15IFKMjAaayFhqnXV52aEmv1whZHX56pdkK+MEaLoQWj+H42ssFarP1PcomVhbsR4pkz09qBg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.0.tgz", - "integrity": "sha512-BFelBGfrBwk6LVrmFzCq1u1dZbG4zy/Kp93w2+y83Q5UGYF1d8sCzeLI9NXjKyujjBBniQa8R8PzLFAUrSM9OA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.0.tgz", - "integrity": "sha512-lY6AC8p4Cnb7xYHuIxQ6iYPe6MfO2CC43XXKo9nBXDb35krYt7KGhQnOkRGar5psxYkircpCqfbNDB4uJbS2jQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.0.tgz", - "integrity": "sha512-7L1bHlOTcO4ByvI7OXVI5pNN6HSu6pUQq9yodga8izeuB1KcT2UkHaH6118QJwopExPn0rMHIseCTx1CRo/uNA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.0.tgz", - "integrity": "sha512-Arm+WgUFLUATuoxCJcahGuk6Yj9Pzxd6l11Zb/2aAuv5kWWvvfhLFo2fni4uSK5vzlUdCGZ/BdV5tH8klj8p8g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", @@ -6426,6 +5911,13 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -6453,14 +5945,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@eslint/eslintrc/node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "license": "MIT", - "engines": { - "node": ">= 4" + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { @@ -6671,7 +6166,6 @@ "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-2.5.0.tgz", "integrity": "sha512-sMgdETOfi2dUHT8r7TT1BTKOwNvdDGFDXYWtQ2J69SvlYNntk9I/gJe7r5yvMwwsuKnYbuRs3pNhx4tgNck5aA==", "dev": true, - "license": "MIT", "dependencies": { "@inquirer/core": "^9.1.0", "@inquirer/figures": "^1.0.5", @@ -6688,7 +6182,6 @@ "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-3.1.22.tgz", "integrity": "sha512-gsAKIOWBm2Q87CDfs9fEo7wJT3fwWIJfnDGMn9Qy74gBnNFOACDNfhUzovubbJjWnKLGBln7/NcSmZwj5DuEXg==", "dev": true, - "license": "MIT", "dependencies": { "@inquirer/core": "^9.0.10", "@inquirer/type": "^1.5.2" @@ -6702,7 +6195,6 @@ "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-9.2.1.tgz", "integrity": "sha512-F2VBt7W/mwqEU4bL0RnHNZmC/OxzNx9cOYxHqnXX3MP6ruYvZUZAW9imgN9+h/uBT/oP8Gh888J2OZSbjSeWcg==", "dev": true, - "license": "MIT", "dependencies": { "@inquirer/figures": "^1.0.6", "@inquirer/type": "^2.0.0", @@ -6726,7 +6218,6 @@ "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-2.0.0.tgz", "integrity": "sha512-XvJRx+2KR3YXyYtPUUy+qd9i7p+GO9Ko6VIIpWlBrpWwXDv8WLFeHTxz35CfQFUiBMLXlGHhGzys7lqit9gWag==", "dev": true, - "license": "MIT", "dependencies": { "mute-stream": "^1.0.0" }, @@ -6734,12 +6225,29 @@ "node": ">=18" } }, + "node_modules/@inquirer/core/node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@inquirer/core/node_modules/mute-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", + "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/@inquirer/editor": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-2.2.0.tgz", "integrity": "sha512-9KHOpJ+dIL5SZli8lJ6xdaYLPPzB8xB9GZItg39MBybzhxA16vxmszmQFrRwbOA918WA2rvu8xhDEg/p6LXKbw==", "dev": true, - "license": "MIT", "dependencies": { "@inquirer/core": "^9.1.0", "@inquirer/type": "^1.5.3", @@ -6754,7 +6262,6 @@ "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-2.3.0.tgz", "integrity": "sha512-qnJsUcOGCSG1e5DTOErmv2BPQqrtT6uzqn1vI/aYGiPKq+FgslGZmtdnXbhuI7IlT7OByDoEEqdnhUnVR2hhLw==", "dev": true, - "license": "MIT", "dependencies": { "@inquirer/core": "^9.1.0", "@inquirer/type": "^1.5.3", @@ -6765,11 +6272,10 @@ } }, "node_modules/@inquirer/figures": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.10.tgz", - "integrity": "sha512-Ey6176gZmeqZuY/W/nZiUyvmb1/qInjcpiZjXWi6nON+nxJpD1bxtSoBxNliGISae32n6OwbY+TSXPZ1CfS4bw==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.8.tgz", + "integrity": "sha512-tKd+jsmhq21AP1LhexC0pPwsCxEhGgAkg28byjJAd+xhmIs8LUX8JbUc3vBf3PhLxWiB5EvyBE5X7JSPAqMAqg==", "dev": true, - "license": "MIT", "engines": { "node": ">=18" } @@ -6779,7 +6285,6 @@ "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-2.3.0.tgz", "integrity": "sha512-XfnpCStx2xgh1LIRqPXrTNEEByqQWoxsWYzNRSEUxJ5c6EQlhMogJ3vHKu8aXuTacebtaZzMAHwEL0kAflKOBw==", "dev": true, - "license": "MIT", "dependencies": { "@inquirer/core": "^9.1.0", "@inquirer/type": "^1.5.3" @@ -6793,7 +6298,6 @@ "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-1.1.0.tgz", "integrity": "sha512-ilUnia/GZUtfSZy3YEErXLJ2Sljo/mf9fiKc08n18DdwdmDbOzRcTv65H1jjDvlsAuvdFXf4Sa/aL7iw/NanVA==", "dev": true, - "license": "MIT", "dependencies": { "@inquirer/core": "^9.1.0", "@inquirer/type": "^1.5.3" @@ -6807,7 +6311,6 @@ "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-2.2.0.tgz", "integrity": "sha512-5otqIpgsPYIshqhgtEwSspBQE40etouR8VIxzpJkv9i0dVHIpyhiivbkH9/dGiMLdyamT54YRdGJLfl8TFnLHg==", "dev": true, - "license": "MIT", "dependencies": { "@inquirer/core": "^9.1.0", "@inquirer/type": "^1.5.3", @@ -6822,7 +6325,6 @@ "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-5.3.8.tgz", "integrity": "sha512-b2BudQY/Si4Y2a0PdZZL6BeJtl8llgeZa7U2j47aaJSCeAl1e4UI7y8a9bSkO3o/ZbZrgT5muy/34JbsjfIWxA==", "dev": true, - "license": "MIT", "dependencies": { "@inquirer/checkbox": "^2.4.7", "@inquirer/confirm": "^3.1.22", @@ -6844,7 +6346,6 @@ "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-2.3.0.tgz", "integrity": "sha512-zzfNuINhFF7OLAtGHfhwOW2TlYJyli7lOUoJUXw/uyklcwalV6WRXBXtFIicN8rTRK1XTiPWB4UY+YuW8dsnLQ==", "dev": true, - "license": "MIT", "dependencies": { "@inquirer/core": "^9.1.0", "@inquirer/type": "^1.5.3", @@ -6859,7 +6360,6 @@ "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-1.1.0.tgz", "integrity": "sha512-h+/5LSj51dx7hp5xOn4QFnUaKeARwUCLs6mIhtkJ0JYPBLmEYjdHSYh7I6GrLg9LwpJ3xeX0FZgAG1q0QdCpVQ==", "dev": true, - "license": "MIT", "dependencies": { "@inquirer/core": "^9.1.0", "@inquirer/figures": "^1.0.5", @@ -6875,7 +6375,6 @@ "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-2.5.0.tgz", "integrity": "sha512-YmDobTItPP3WcEI86GvPo+T2sRHkxxOq/kXmsBjHS5BVXUgvgZ5AfJjkvQvZr03T81NnI3KrrRuMzeuYUQRFOA==", "dev": true, - "license": "MIT", "dependencies": { "@inquirer/core": "^9.1.0", "@inquirer/figures": "^1.0.5", @@ -6892,7 +6391,6 @@ "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-1.5.5.tgz", "integrity": "sha512-MzICLu4yS7V8AA61sANROZ9vT1H3ooca5dSmI1FjZkzq7o/koMsRfQSzRtFo+F3Ao4Sf1C0bpLKejpKB/+j6MA==", "dev": true, - "license": "MIT", "dependencies": { "mute-stream": "^1.0.0" }, @@ -6900,6 +6398,15 @@ "node": ">=18" } }, + "node_modules/@inquirer/type/node_modules/mute-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", + "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -7021,17 +6528,6 @@ "node": ">=8" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -7047,21 +6543,6 @@ "node": ">=8" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -7107,25 +6588,6 @@ "node": ">=8" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true, - "license": "BSD-3-Clause", - "peer": true - }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", @@ -7155,17 +6617,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/console/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/core": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", @@ -7253,17 +6704,6 @@ "license": "MIT", "peer": true }, - "node_modules/@jest/core/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/environment": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", @@ -7423,6 +6863,24 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/@jest/reporters/node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@jest/reporters/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -7437,17 +6895,6 @@ "node": "*" } }, - "node_modules/@jest/reporters/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", @@ -7511,17 +6958,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/test-sequencer/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/transform": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", @@ -7558,17 +6994,6 @@ "license": "MIT", "peer": true }, - "node_modules/@jest/transform/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/types": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", @@ -7588,9 +7013,9 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", - "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.2.1", @@ -7664,9 +7089,9 @@ } }, "node_modules/@jsonjoy.com/json-pack": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.1.1.tgz", - "integrity": "sha512-osjeBqMJ2lb/j/M8NCPjs1ylqWIcTRTycIhVB5pt6LgzgeRSb0YRZ7j9RfA8wIUrsr/medIuhVyonXRZWLyfdw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.1.0.tgz", + "integrity": "sha512-zlQONA+msXPPwHWZMKFVS78ewFczIll5lXiVPwFPCZUsrOKdxc2AvxU1HoNBmMRhqDZUR9HkC3UOm+6pME6Xsg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -7744,7 +7169,6 @@ "resolved": "https://registry.npmjs.org/@listr2/prompt-adapter-inquirer/-/prompt-adapter-inquirer-2.0.15.tgz", "integrity": "sha512-MZrGem/Ujjd4cPTLYDfCZK2iKKeiO/8OX13S6jqxldLs0Prf2aGqVlJ77nMBqMv7fzqgXEgjrNHLXcKR8l9lOg==", "dev": true, - "license": "MIT", "dependencies": { "@inquirer/type": "^1.5.1" }, @@ -7763,9 +7187,9 @@ "license": "BSD-3-Clause" }, "node_modules/@lit-labs/ssr-dom-shim": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.3.0.tgz", - "integrity": "sha512-nQIWonJ6eFAvUUrSlwyHDm/aE8PBDu5kRpL0vHMg6K8fK3Diq1xdPjTnsJSwxABhaZ+5eBi1btQB5ShUTKo4nQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.2.1.tgz", + "integrity": "sha512-wx4aBmgeGvFmOKucFKY+8VFJSYZxs9poN3SDNQFF6lT6NrQUnHiPB2PWz2sc4ieEcAaYYzN+1uWahEeTq2aRIQ==", "license": "BSD-3-Clause" }, "node_modules/@lit/reactive-element": { @@ -7785,7 +7209,6 @@ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "darwin" @@ -7799,7 +7222,6 @@ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "darwin" @@ -7813,7 +7235,6 @@ "arm" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" @@ -7827,7 +7248,6 @@ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" @@ -7841,7 +7261,6 @@ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" @@ -7855,7 +7274,6 @@ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "win32" @@ -8010,7 +7428,6 @@ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "darwin" @@ -8024,7 +7441,6 @@ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "darwin" @@ -8038,7 +7454,6 @@ "arm" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" @@ -8052,7 +7467,6 @@ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" @@ -8066,7 +7480,6 @@ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" @@ -8080,7 +7493,6 @@ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "win32" @@ -8107,7 +7519,6 @@ "version": "13.9.1", "resolved": "https://registry.npmjs.org/@ng-select/ng-select/-/ng-select-13.9.1.tgz", "integrity": "sha512-+DzQkQp8coGWZREflJM/qx7BXipV6HEVpZCXoa6fJJRHJfmUMsxa5uV6kUVmClUE98Rkffk9CPHt6kZcj8PuqQ==", - "license": "MIT", "dependencies": { "tslib": "^2.3.1" }, @@ -8126,7 +7537,6 @@ "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-18.2.12.tgz", "integrity": "sha512-FFJAwtWbtpncMOVNuULPBwFJB7GSjiUwO93eGTzRp8O4EPQ8lCQeFbezQm/NP34+T0+GBLGzPSuQT+muob8YKw==", "dev": true, - "license": "MIT", "engines": { "node": "^18.19.1 || ^20.11.1 || >=22.0.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", @@ -8191,7 +7601,6 @@ "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-2.2.2.tgz", "integrity": "sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og==", "dev": true, - "license": "ISC", "dependencies": { "agent-base": "^7.1.0", "http-proxy-agent": "^7.0.0", @@ -8204,11 +7613,13 @@ } }, "node_modules/@npmcli/agent/node_modules/agent-base": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", - "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dev": true, - "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, "engines": { "node": ">= 14" } @@ -8218,7 +7629,6 @@ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dev": true, - "license": "MIT", "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" @@ -8231,17 +7641,15 @@ "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/@npmcli/agent/node_modules/socks-proxy-agent": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", - "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz", + "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==", "dev": true, - "license": "MIT", "dependencies": { - "agent-base": "^7.1.2", + "agent-base": "^7.1.1", "debug": "^4.3.4", "socks": "^2.8.3" }, @@ -8268,7 +7676,6 @@ "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-5.0.8.tgz", "integrity": "sha512-liASfw5cqhjNW9UFd+ruwwdEf/lbOAQjLL2XY2dFW/bkJheXDYZgOyul/4gVvEV4BWkTXjYGmDqMw9uegdbJNQ==", "dev": true, - "license": "ISC", "dependencies": { "@npmcli/promise-spawn": "^7.0.0", "ini": "^4.1.3", @@ -8289,7 +7696,6 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", "dev": true, - "license": "ISC", "engines": { "node": ">=16" } @@ -8298,15 +7704,13 @@ "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/@npmcli/git/node_modules/proc-log": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", "dev": true, - "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -8316,7 +7720,6 @@ "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", "dev": true, - "license": "ISC", "dependencies": { "isexe": "^3.1.1" }, @@ -8332,7 +7735,6 @@ "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-2.1.0.tgz", "integrity": "sha512-c8UuGLeZpm69BryRykLuKRyKFZYJsZSCT4aVY5ds4omyZqJ172ApzgfKJ5eV/r3HgLdUYgFVe54KSFVjKoe27w==", "dev": true, - "license": "ISC", "dependencies": { "npm-bundled": "^3.0.0", "npm-normalize-package-bin": "^3.0.0" @@ -8427,7 +7829,6 @@ "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz", "integrity": "sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA==", "dev": true, - "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -8437,7 +7838,6 @@ "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-5.2.1.tgz", "integrity": "sha512-f7zYC6kQautXHvNbLEWgD/uGu1+xCn9izgqBfgItWSx22U0ZDekxN08A1vM8cTxj/cRVe0Q94Ode+tdoYmIOOQ==", "dev": true, - "license": "ISC", "dependencies": { "@npmcli/git": "^5.0.0", "glob": "^10.2.2", @@ -8451,33 +7851,11 @@ "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@npmcli/package-json/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@npmcli/package-json/node_modules/hosted-git-info": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", "dev": true, - "license": "ISC", "dependencies": { "lru-cache": "^10.0.1" }, @@ -8485,52 +7863,17 @@ "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@npmcli/package-json/node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, "node_modules/@npmcli/package-json/node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/@npmcli/package-json/node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } + "dev": true }, "node_modules/@npmcli/package-json/node_modules/proc-log": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", "dev": true, - "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -8540,7 +7883,6 @@ "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-7.0.2.tgz", "integrity": "sha512-xhfYPXoV5Dy4UkY0D+v2KkwvnDfiA/8Mt3sWCGI/hM03NsYIH8ZaG6QzS9x7pje5vHZBZJ2v6VRFVTWACnqcmQ==", "dev": true, - "license": "ISC", "dependencies": { "which": "^4.0.0" }, @@ -8553,7 +7895,6 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", "dev": true, - "license": "ISC", "engines": { "node": ">=16" } @@ -8563,7 +7904,6 @@ "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", "dev": true, - "license": "ISC", "dependencies": { "isexe": "^3.1.1" }, @@ -8579,7 +7919,6 @@ "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-2.0.1.tgz", "integrity": "sha512-YgsR5jCQZhVmTJvjduTOIHph0L73pK8xwMVaDY0PatySqVM9AZj93jpoXYSJqfHFxFkN9dmqTw6OiqExsS3LPw==", "dev": true, - "license": "ISC", "engines": { "node": "^16.14.0 || >=18.0.0" } @@ -8589,7 +7928,6 @@ "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-8.1.0.tgz", "integrity": "sha512-y7efHHwghQfk28G2z3tlZ67pLG0XdfYbcVG26r7YIXALRsrVQcTq4/tdenSmdOrEsNahIYA/eh8aEVROWGFUDg==", "dev": true, - "license": "ISC", "dependencies": { "@npmcli/node-gyp": "^3.0.0", "@npmcli/package-json": "^5.0.0", @@ -8607,7 +7945,6 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", "dev": true, - "license": "ISC", "engines": { "node": ">=16" } @@ -8617,7 +7954,6 @@ "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", "dev": true, - "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -8627,7 +7963,6 @@ "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", "dev": true, - "license": "ISC", "dependencies": { "isexe": "^3.1.1" }, @@ -8639,9 +7974,9 @@ } }, "node_modules/@parcel/watcher": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", - "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.0.tgz", + "integrity": "sha512-i0GV1yJnm2n3Yq1qw6QrUrd/LI9bE8WEBOTtOkpCXHHdyN3TAGgqAK/DAT05z4fq2x04cARXt2pDmjWjL92iTQ==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -8660,46 +7995,25 @@ "url": "https://opencollective.com/parcel" }, "optionalDependencies": { - "@parcel/watcher-android-arm64": "2.5.1", - "@parcel/watcher-darwin-arm64": "2.5.1", - "@parcel/watcher-darwin-x64": "2.5.1", - "@parcel/watcher-freebsd-x64": "2.5.1", - "@parcel/watcher-linux-arm-glibc": "2.5.1", - "@parcel/watcher-linux-arm-musl": "2.5.1", - "@parcel/watcher-linux-arm64-glibc": "2.5.1", - "@parcel/watcher-linux-arm64-musl": "2.5.1", - "@parcel/watcher-linux-x64-glibc": "2.5.1", - "@parcel/watcher-linux-x64-musl": "2.5.1", - "@parcel/watcher-win32-arm64": "2.5.1", - "@parcel/watcher-win32-ia32": "2.5.1", - "@parcel/watcher-win32-x64": "2.5.1" - } - }, - "node_modules/@parcel/watcher-android-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", - "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "@parcel/watcher-android-arm64": "2.5.0", + "@parcel/watcher-darwin-arm64": "2.5.0", + "@parcel/watcher-darwin-x64": "2.5.0", + "@parcel/watcher-freebsd-x64": "2.5.0", + "@parcel/watcher-linux-arm-glibc": "2.5.0", + "@parcel/watcher-linux-arm-musl": "2.5.0", + "@parcel/watcher-linux-arm64-glibc": "2.5.0", + "@parcel/watcher-linux-arm64-musl": "2.5.0", + "@parcel/watcher-linux-x64-glibc": "2.5.0", + "@parcel/watcher-linux-x64-musl": "2.5.0", + "@parcel/watcher-win32-arm64": "2.5.0", + "@parcel/watcher-win32-ia32": "2.5.0", + "@parcel/watcher-win32-x64": "2.5.0" } }, "node_modules/@parcel/watcher-darwin-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", - "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.0.tgz", + "integrity": "sha512-hyZ3TANnzGfLpRA2s/4U1kbw2ZI4qGxaRJbBH2DCSREFfubMswheh8TeiC1sGZ3z2jUf3s37P0BBlrD3sjVTUw==", "cpu": [ "arm64" ], @@ -8717,237 +8031,6 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/@parcel/watcher-darwin-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", - "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-freebsd-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", - "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", - "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", - "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm64-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", - "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm64-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", - "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-x64-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", - "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-x64-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", - "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", - "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-ia32": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", - "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", - "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, "node_modules/@parcel/watcher/node_modules/detect-libc": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", @@ -8970,6 +8053,36 @@ "license": "MIT", "optional": true }, + "node_modules/@paypal/accelerated-checkout-loader": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@paypal/accelerated-checkout-loader/-/accelerated-checkout-loader-1.1.0.tgz", + "integrity": "sha512-S2KkIpq15VnxYyI0tycvfYiNsqdsg2a92El2huYUVLsWnBbubl8toYK8khaP5nnxZ0MGl9mEB9Y9axmfOw2Yvg==", + "license": "MIT", + "dependencies": { + "@braintree/asset-loader": "2.0.0", + "envify": "^4.1.0", + "typescript": "^4.6.4" + } + }, + "node_modules/@paypal/accelerated-checkout-loader/node_modules/@braintree/asset-loader": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@braintree/asset-loader/-/asset-loader-2.0.0.tgz", + "integrity": "sha512-7Zs3/g3lPTfkdtWr7cKh3tk1pDruXR++TXwGKkx7BPuTjjLNFul2JSfI+ScHzNU4u/gZNPNQagsSTlYxIhBgMA==", + "license": "MIT" + }, + "node_modules/@paypal/accelerated-checkout-loader/node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, "node_modules/@phc/format": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@phc/format/-/format-1.0.0.tgz", @@ -8990,38 +8103,10 @@ "node": ">=14" } }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz", - "integrity": "sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz", - "integrity": "sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz", - "integrity": "sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q==", + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.4.tgz", + "integrity": "sha512-GmU/QgGtBTeraKyldC7cDVVvAJEOr3dFLKneez/n7BvX57UdhOqDsVwzU7UOnYA7AAOt+Xb26lk79PldDHgMIQ==", "cpu": [ "arm64" ], @@ -9032,188 +8117,6 @@ "darwin" ] }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz", - "integrity": "sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz", - "integrity": "sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz", - "integrity": "sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz", - "integrity": "sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz", - "integrity": "sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz", - "integrity": "sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz", - "integrity": "sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz", - "integrity": "sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz", - "integrity": "sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz", - "integrity": "sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz", - "integrity": "sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz", - "integrity": "sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz", - "integrity": "sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/@rtsao/scc": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", @@ -9226,7 +8129,6 @@ "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-18.2.12.tgz", "integrity": "sha512-sIoeipsisK5eTLW3XuNZYcal83AfslBbgI7LnV+3VrXwpasKPGHwo2ZdwhCd2IXAkuJ02Iyu7MyV0aQRM9i/3g==", "dev": true, - "license": "MIT", "dependencies": { "@angular-devkit/core": "18.2.12", "@angular-devkit/schematics": "18.2.12", @@ -9238,125 +8140,6 @@ "yarn": ">= 1.13.0" } }, - "node_modules/@schematics/angular/node_modules/@angular-devkit/core": { - "version": "18.2.12", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.12.tgz", - "integrity": "sha512-NtB6ypsaDyPE6/fqWOdfTmACs+yK5RqfH5tStEzWFeeDsIEDYKsJ06ypuRep7qTjYus5Rmttk0Ds+cFgz8JdUQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "8.17.1", - "ajv-formats": "3.0.1", - "jsonc-parser": "3.3.1", - "picomatch": "4.0.2", - "rxjs": "7.8.1", - "source-map": "0.7.4" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^3.5.2" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/@schematics/angular/node_modules/@angular-devkit/schematics": { - "version": "18.2.12", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-18.2.12.tgz", - "integrity": "sha512-mMea9txHbnCX5lXLHlo0RAgfhFHDio45/jMsREM2PA8UtVf2S8ltXz7ZwUrUyMQRv8vaSfn4ijDstF4hDMnRgQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/core": "18.2.12", - "jsonc-parser": "3.3.1", - "magic-string": "0.30.11", - "ora": "5.4.1", - "rxjs": "7.8.1" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@schematics/angular/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/@schematics/angular/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "optional": true, - "peer": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@schematics/angular/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/@schematics/angular/node_modules/readdirp/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/@sideway/address": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", @@ -9386,7 +8169,6 @@ "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-2.3.2.tgz", "integrity": "sha512-wueKWDk70QixNLB363yHc2D2ItTgYiMTdPwK8D9dKQMR3ZQ0c35IxP5xnwQ8cNLoCgCRcHf14kE+CLIvNX1zmA==", "dev": true, - "license": "Apache-2.0", "dependencies": { "@sigstore/protobuf-specs": "^0.3.2" }, @@ -9399,19 +8181,17 @@ "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-1.1.0.tgz", "integrity": "sha512-JzBqdVIyqm2FRQCulY6nbQzMpJJpSiJ8XXWMhtOX9eKgaXXpfNOF53lzQEjIydlStnd/eFtuC1dW4VYdD93oRg==", "dev": true, - "license": "Apache-2.0", "engines": { "node": "^16.14.0 || >=18.0.0" } }, "node_modules/@sigstore/protobuf-specs": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.3.3.tgz", - "integrity": "sha512-RpacQhBlwpBWd7KEJsRKcBQalbV28fvkxwTOJIqhIuDysMMaJW47V4OqW30iJB9uRpqOSxxEAQFdr8tTattReQ==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.3.2.tgz", + "integrity": "sha512-c6B0ehIWxMI8wiS/bj6rHMPqeFvngFV7cDU/MY+B16P9Z3Mp9k8L93eYZ7BYzSickzuqAQqAq0V956b3Ju6mLw==", "dev": true, - "license": "Apache-2.0", "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^16.14.0 || >=18.0.0" } }, "node_modules/@sigstore/sign": { @@ -9419,7 +8199,6 @@ "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-2.3.2.tgz", "integrity": "sha512-5Vz5dPVuunIIvC5vBb0APwo7qKA4G9yM48kPWJT+OEERs40md5GoUR1yedwpekWZ4m0Hhw44m6zU+ObsON+iDA==", "dev": true, - "license": "Apache-2.0", "dependencies": { "@sigstore/bundle": "^2.3.2", "@sigstore/core": "^1.0.0", @@ -9437,7 +8216,6 @@ "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz", "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==", "dev": true, - "license": "ISC", "dependencies": { "semver": "^7.3.5" }, @@ -9450,7 +8228,6 @@ "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.4.tgz", "integrity": "sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==", "dev": true, - "license": "ISC", "dependencies": { "@npmcli/fs": "^3.1.0", "fs-minipass": "^3.0.0", @@ -9474,7 +8251,6 @@ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -9482,56 +8258,17 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@sigstore/sign/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@sigstore/sign/node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, "node_modules/@sigstore/sign/node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/@sigstore/sign/node_modules/make-fetch-happen": { "version": "13.0.1", "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.1.tgz", "integrity": "sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==", "dev": true, - "license": "ISC", "dependencies": { "@npmcli/agent": "^2.0.0", "cacache": "^18.0.0", @@ -9555,7 +8292,6 @@ "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -9568,7 +8304,6 @@ "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", "dev": true, - "license": "MIT", "dependencies": { "minipass": "^7.0.3", "minipass-sized": "^1.0.3", @@ -9581,29 +8316,11 @@ "encoding": "^0.1.13" } }, - "node_modules/@sigstore/sign/node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@sigstore/sign/node_modules/proc-log": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", "dev": true, - "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -9613,7 +8330,6 @@ "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -9626,7 +8342,6 @@ "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", "dev": true, - "license": "ISC", "dependencies": { "unique-slug": "^4.0.0" }, @@ -9639,7 +8354,6 @@ "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", "dev": true, - "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4" }, @@ -9652,7 +8366,6 @@ "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-2.3.4.tgz", "integrity": "sha512-44vtsveTPUpqhm9NCrbU8CWLe3Vck2HO1PNLw7RIajbB7xhtn5RBPm1VNSCMwqGYHhDsBJG8gDF0q4lgydsJvw==", "dev": true, - "license": "Apache-2.0", "dependencies": { "@sigstore/protobuf-specs": "^0.3.2", "tuf-js": "^2.2.1" @@ -9666,7 +8379,6 @@ "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-1.2.1.tgz", "integrity": "sha512-8iKx79/F73DKbGfRf7+t4dqrc0bRr0thdPrxAtCKWRm/F0tG71i6O1rvlnScncJLLBZHn3h8M3c1BSUAb9yu8g==", "dev": true, - "license": "Apache-2.0", "dependencies": { "@sigstore/bundle": "^2.3.2", "@sigstore/core": "^1.1.0", @@ -9719,6 +8431,16 @@ "type-detect": "4.0.8" } }, + "node_modules/@sinonjs/commons/node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/@sinonjs/fake-timers": { "version": "10.3.0", "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", @@ -9770,20 +8492,6 @@ "storybook": "^8.5.2" } }, - "node_modules/@storybook/addon-actions/node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "dev": true, - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/@storybook/addon-backgrounds": { "version": "8.5.2", "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-8.5.2.tgz", @@ -10219,35 +8927,6 @@ "webpack": "^5.0.0" } }, - "node_modules/@storybook/builder-webpack5/node_modules/webpack-dev-middleware": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-6.1.3.tgz", - "integrity": "sha512-A4ChP0Qj8oGociTs6UdlRUGANIGrCDL3y+pmQMc+dSsraXHCatFpmMey4mYELA+juqwUqwQsUgJJISXl1KWmiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "colorette": "^2.0.10", - "memfs": "^3.4.12", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - } - } - }, "node_modules/@storybook/components": { "version": "8.5.2", "resolved": "https://registry.npmjs.org/@storybook/components/-/components-8.5.2.tgz", @@ -10346,17 +9025,17 @@ "license": "MIT" }, "node_modules/@storybook/icons": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@storybook/icons/-/icons-1.3.2.tgz", - "integrity": "sha512-t3xcbCKkPvqyef8urBM0j/nP6sKtnlRkVgC+8JTbTAZQjaTmOjes3byEgzs89p4B/K6cJsg9wLW2k3SknLtYJw==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@storybook/icons/-/icons-1.2.12.tgz", + "integrity": "sha512-UxgyK5W3/UV4VrI3dl6ajGfHM4aOqMAkFLWe2KibeQudLf6NJpDrDMSHwZj+3iKC4jFU7dkKbbtH2h/al4sW3Q==", "dev": true, "license": "MIT", "engines": { "node": ">=14.0.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "node_modules/@storybook/instrumenter": { @@ -10541,16 +9220,6 @@ "node": ">=18" } }, - "node_modules/@testing-library/dom/node_modules/aria-query": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", - "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "dequal": "^2.0.3" - } - }, "node_modules/@testing-library/jest-dom": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.5.0.tgz", @@ -10618,24 +9287,10 @@ "pnpm": ">=8.6.0" } }, - "node_modules/@thednp/position-observer": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@thednp/position-observer/-/position-observer-1.0.7.tgz", - "integrity": "sha512-MkUAMMgqZPxy71hpcrKr9ZtedMk+oIFbFs5B8uKD857iuYKRJxgJtC1Itus14EEM4qMyeN0x47AUZJmZJQyXbQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@thednp/shorty": "^2.0.10" - }, - "engines": { - "node": ">=16", - "pnpm": ">=8.6.0" - } - }, "node_modules/@thednp/shorty": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@thednp/shorty/-/shorty-2.0.10.tgz", - "integrity": "sha512-H+hs1lw3Yc1NfwG0b7F7YmVjxQZ31NO2+6zx+I+9XabHxdwPKjvYJnkKKXr7bSItgm2AFrfOn5+3veB6W4iauw==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@thednp/shorty/-/shorty-2.0.7.tgz", + "integrity": "sha512-PQ388ZznrgnkikwkDCqqFfkGAYWXS2ijFmXD63Ej47Md6VrV5WJqhgQilhu3tSkzddtbDJlz4tQTj4RYVrWUoA==", "dev": true, "license": "MIT", "engines": { @@ -10670,7 +9325,6 @@ "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==", "dev": true, - "license": "MIT", "engines": { "node": "^16.14.0 || >=18.0.0" } @@ -10680,7 +9334,6 @@ "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-2.0.1.tgz", "integrity": "sha512-92F7/SFyufn4DXsha9+QfKnN03JGqtMFMXgSHbZOo8JG59WkTni7UzAouNQDf7AuP9OAMxVOPQcqG3sB7w+kkg==", "dev": true, - "license": "MIT", "dependencies": { "@tufjs/canonical-json": "2.0.0", "minimatch": "^9.0.4" @@ -10881,29 +9534,29 @@ } }, "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "dev": true, "license": "MIT" }, "node_modules/@types/express": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.0.tgz", - "integrity": "sha512-DvZriSMehGHL1ZNLzi6MidnsDhUZM/x2pRdDIKdwbUNqqwHxMlRdkxtn6/EPKyqKpHqTl/4nRZsRNLpZxZRpPQ==", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", "dev": true, "license": "MIT", "dependencies": { "@types/body-parser": "*", - "@types/express-serve-static-core": "^5.0.0", + "@types/express-serve-static-core": "^4.17.33", "@types/qs": "*", "@types/serve-static": "*" } }, "node_modules/@types/express-serve-static-core": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.6.tgz", - "integrity": "sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA==", + "version": "4.19.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", + "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", "dev": true, "license": "MIT", "dependencies": { @@ -11208,9 +9861,9 @@ } }, "node_modules/@types/lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-w/P33JFeySuhN6JLkysYUK2gEmy9kHHFN7E8ro0tkfmlDOgxBDzWEZ/J8cWA+fHqFevpswDTFZnDx+R9lbL6xw==", + "version": "4.17.13", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.13.tgz", + "integrity": "sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==", "dev": true, "license": "MIT" }, @@ -11256,9 +9909,9 @@ "license": "MIT" }, "node_modules/@types/ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", - "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", "dev": true, "license": "MIT" }, @@ -11267,7 +9920,6 @@ "resolved": "https://registry.npmjs.org/@types/mute-stream/-/mute-stream-0.0.4.tgz", "integrity": "sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*" } @@ -11328,6 +9980,13 @@ "@types/node": "*" } }, + "node_modules/@types/node/node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/papaparse": { "version": "5.3.15", "resolved": "https://registry.npmjs.org/@types/papaparse/-/papaparse-5.3.15.tgz", @@ -11374,9 +10033,9 @@ } }, "node_modules/@types/qs": { - "version": "6.9.18", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.18.tgz", - "integrity": "sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==", + "version": "6.9.16", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.16.tgz", + "integrity": "sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==", "dev": true, "license": "MIT" }, @@ -11399,13 +10058,13 @@ } }, "node_modules/@types/react-dom": { - "version": "18.3.5", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.5.tgz", - "integrity": "sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==", "dev": true, "license": "MIT", - "peerDependencies": { - "@types/react": "^18.0.0" + "dependencies": { + "@types/react": "*" } }, "node_modules/@types/responselike": { @@ -11535,9 +10194,9 @@ "optional": true }, "node_modules/@types/webpack-env": { - "version": "1.18.8", - "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.18.8.tgz", - "integrity": "sha512-G9eAoJRMLjcvN4I08wB5I7YofOb/kaJNd5uoCMX+LbKXTPCF+ZIHuqTnFaK9Jz1rgs035f9JUPUhNFtqgucy/A==", + "version": "1.18.5", + "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.18.5.tgz", + "integrity": "sha512-wz7kjjRRj8/Lty4B+Kr0LN6Ypc/3SymeCCGSbaXp2leH0ZVg/PriNiOwNj4bD4uphI7A8NXS4b6Gl373sfO5mA==", "dev": true, "license": "MIT" }, @@ -11545,13 +10204,12 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/wrap-ansi/-/wrap-ansi-3.0.0.tgz", "integrity": "sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/@types/ws": { - "version": "8.5.14", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.14.tgz", - "integrity": "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw==", + "version": "8.5.13", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz", + "integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==", "dev": true, "license": "MIT", "dependencies": { @@ -11598,7 +10256,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.20.0.tgz", "integrity": "sha512-naduuphVw5StFfqp4Gq4WhIBE2gN1GEmMUExpJYknZJdRnc+2gDzB8Z3+5+/Kv33hPQRDGzQO/0opHE72lZZ6A==", "dev": true, - "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.20.0", @@ -11623,71 +10280,11 @@ "typescript": ">=4.8.4 <5.8.0" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.20.0.tgz", - "integrity": "sha512-J7+VkpeGzhOt3FeG1+SzhiMj9NzGD/M6KoGn9f4dbz3YzK9hvbhVTmLj/HiTp9DazIzJ8B4XcM80LrR9Dm1rJw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.20.0", - "@typescript-eslint/visitor-keys": "8.20.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.20.0.tgz", - "integrity": "sha512-cqaMiY72CkP+2xZRrFt3ExRBu0WmVitN/rYPZErA80mHjHx/Svgp8yfbzkJmDoQ/whcytOPO9/IZXnOc+wigRA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.20.0.tgz", - "integrity": "sha512-Y7ncuy78bJqHI35NwzWol8E0X7XkRVS4K4P4TCyzWkOJih5NDvtoRDW4Ba9YJJoB2igm9yXDdYI/+fkiiAxPzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.20.0", - "@typescript-eslint/visitor-keys": "8.20.0", - "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^2.0.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <5.8.0" - } - }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { "version": "8.20.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.20.0.tgz", "integrity": "sha512-dq70RUw6UK9ei7vxc4KQtBRk7qkHZv447OUZ6RPQMQl71I3NZxQJX/f32Smr+iqWrB02pHKn2yAdHBb0KNrRMA==", "dev": true, - "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@typescript-eslint/scope-manager": "8.20.0", @@ -11706,47 +10303,6 @@ "typescript": ">=4.8.4 <5.8.0" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.20.0.tgz", - "integrity": "sha512-v/BpkeeYAsPkKCkR8BDwcno0llhzWVqPOamQrAEMdpZav2Y9OVjd9dwJyBLJWwf335B5DmlifECIkZRJCaGaHA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.20.0", - "eslint-visitor-keys": "^4.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, "node_modules/@typescript-eslint/experimental-utils": { "version": "5.62.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.62.0.tgz", @@ -11896,53 +10452,11 @@ "node": ">=4.0" } }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/@typescript-eslint/parser": { "version": "8.20.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.20.0.tgz", "integrity": "sha512-gKXG7A5HMyjDIedBi6bUrDcun8GIjnI8qOwVLiY3rx6T/sHP/19XLJOnIq/FgQvWLHja5JN/LSE7eklNBr612g==", "dev": true, - "license": "MIT", "dependencies": { "@typescript-eslint/scope-manager": "8.20.0", "@typescript-eslint/types": "8.20.0", @@ -11962,47 +10476,51 @@ "typescript": ">=4.8.4 <5.8.0" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.20.0.tgz", - "integrity": "sha512-J7+VkpeGzhOt3FeG1+SzhiMj9NzGD/M6KoGn9f4dbz3YzK9hvbhVTmLj/HiTp9DazIzJ8B4XcM80LrR9Dm1rJw==", + "node_modules/@typescript-eslint/rule-tester": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/rule-tester/-/rule-tester-8.22.0.tgz", + "integrity": "sha512-krTIaDM08bSQ9sIpqDTP0aX4P0Ck/WQpj+7uMIeNqzzWEWmoJFyle12B0Na15KwBLPV2MJPmaZUn+v2qenXjaw==", "dev": true, - "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.20.0", - "@typescript-eslint/visitor-keys": "8.20.0" + "@typescript-eslint/typescript-estree": "8.22.0", + "@typescript-eslint/utils": "8.22.0", + "ajv": "^6.12.6", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "4.6.2", + "semver": "^7.6.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + } + }, + "node_modules/@typescript-eslint/rule-tester/node_modules/@typescript-eslint/types": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.22.0.tgz", + "integrity": "sha512-0S4M4baNzp612zwpD4YOieP3VowOARgK2EkN/GBn95hpyF8E2fbMT55sRHWBq+Huaqk3b3XK+rxxlM8sPgGM6A==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.20.0.tgz", - "integrity": "sha512-cqaMiY72CkP+2xZRrFt3ExRBu0WmVitN/rYPZErA80mHjHx/Svgp8yfbzkJmDoQ/whcytOPO9/IZXnOc+wigRA==", + "node_modules/@typescript-eslint/rule-tester/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.22.0.tgz", + "integrity": "sha512-SJX99NAS2ugGOzpyhMza/tX+zDwjvwAtQFLsBo3GQxiGcvaKlqGBkmZ+Y1IdiSi9h4Q0Lr5ey+Cp9CGWNY/F/w==", "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.20.0.tgz", - "integrity": "sha512-Y7ncuy78bJqHI35NwzWol8E0X7XkRVS4K4P4TCyzWkOJih5NDvtoRDW4Ba9YJJoB2igm9yXDdYI/+fkiiAxPzA==", - "dev": true, - "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.20.0", - "@typescript-eslint/visitor-keys": "8.20.0", + "@typescript-eslint/types": "8.22.0", + "@typescript-eslint/visitor-keys": "8.22.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -12021,14 +10539,13 @@ "typescript": ">=4.8.4 <5.8.0" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.20.0.tgz", - "integrity": "sha512-v/BpkeeYAsPkKCkR8BDwcno0llhzWVqPOamQrAEMdpZav2Y9OVjd9dwJyBLJWwf335B5DmlifECIkZRJCaGaHA==", + "node_modules/@typescript-eslint/rule-tester/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.22.0.tgz", + "integrity": "sha512-AWpYAXnUgvLNabGTy3uBylkgZoosva/miNd1I8Bz3SjotmQPbVqhO4Cczo8AsZ44XVErEBPr/CRSgaj8sG7g0w==", "dev": true, - "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.20.0", + "@typescript-eslint/types": "8.22.0", "eslint-visitor-keys": "^4.2.0" }, "engines": { @@ -12039,12 +10556,27 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys": { + "node_modules/@typescript-eslint/rule-tester/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@typescript-eslint/rule-tester/node_modules/eslint-visitor-keys": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "dev": true, - "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -12052,15 +10584,21 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@typescript-eslint/rule-tester/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.22.0.tgz", - "integrity": "sha512-/lwVV0UYgkj7wPSw0o8URy6YI64QmcOdwHuGuxWIYznO6d45ER0wXUbksr9pYdViAofpUCNJx/tAzNukgvaaiQ==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.20.0.tgz", + "integrity": "sha512-J7+VkpeGzhOt3FeG1+SzhiMj9NzGD/M6KoGn9f4dbz3YzK9hvbhVTmLj/HiTp9DazIzJ8B4XcM80LrR9Dm1rJw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.22.0", - "@typescript-eslint/visitor-keys": "8.22.0" + "@typescript-eslint/types": "8.20.0", + "@typescript-eslint/visitor-keys": "8.20.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -12075,7 +10613,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.20.0.tgz", "integrity": "sha512-bPC+j71GGvA7rVNAHAtOjbVXbLN5PkwqMvy1cwGeaxUoRQXVuKCebRoLzm+IPW/NtFFpstn1ummSIasD5t60GA==", "dev": true, - "license": "MIT", "dependencies": { "@typescript-eslint/typescript-estree": "8.20.0", "@typescript-eslint/utils": "8.20.0", @@ -12094,71 +10631,11 @@ "typescript": ">=4.8.4 <5.8.0" } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.20.0.tgz", - "integrity": "sha512-J7+VkpeGzhOt3FeG1+SzhiMj9NzGD/M6KoGn9f4dbz3YzK9hvbhVTmLj/HiTp9DazIzJ8B4XcM80LrR9Dm1rJw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.20.0", - "@typescript-eslint/visitor-keys": "8.20.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.20.0.tgz", - "integrity": "sha512-cqaMiY72CkP+2xZRrFt3ExRBu0WmVitN/rYPZErA80mHjHx/Svgp8yfbzkJmDoQ/whcytOPO9/IZXnOc+wigRA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.20.0.tgz", - "integrity": "sha512-Y7ncuy78bJqHI35NwzWol8E0X7XkRVS4K4P4TCyzWkOJih5NDvtoRDW4Ba9YJJoB2igm9yXDdYI/+fkiiAxPzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.20.0", - "@typescript-eslint/visitor-keys": "8.20.0", - "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^2.0.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <5.8.0" - } - }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": { "version": "8.20.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.20.0.tgz", "integrity": "sha512-dq70RUw6UK9ei7vxc4KQtBRk7qkHZv447OUZ6RPQMQl71I3NZxQJX/f32Smr+iqWrB02pHKn2yAdHBb0KNrRMA==", "dev": true, - "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@typescript-eslint/scope-manager": "8.20.0", @@ -12177,41 +10654,10 @@ "typescript": ">=4.8.4 <5.8.0" } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.20.0.tgz", - "integrity": "sha512-v/BpkeeYAsPkKCkR8BDwcno0llhzWVqPOamQrAEMdpZav2Y9OVjd9dwJyBLJWwf335B5DmlifECIkZRJCaGaHA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.20.0", - "eslint-visitor-keys": "^4.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, "node_modules/@typescript-eslint/types": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.22.0.tgz", - "integrity": "sha512-0S4M4baNzp612zwpD4YOieP3VowOARgK2EkN/GBn95hpyF8E2fbMT55sRHWBq+Huaqk3b3XK+rxxlM8sPgGM6A==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.20.0.tgz", + "integrity": "sha512-cqaMiY72CkP+2xZRrFt3ExRBu0WmVitN/rYPZErA80mHjHx/Svgp8yfbzkJmDoQ/whcytOPO9/IZXnOc+wigRA==", "dev": true, "license": "MIT", "engines": { @@ -12223,14 +10669,14 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.22.0.tgz", - "integrity": "sha512-SJX99NAS2ugGOzpyhMza/tX+zDwjvwAtQFLsBo3GQxiGcvaKlqGBkmZ+Y1IdiSi9h4Q0Lr5ey+Cp9CGWNY/F/w==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.20.0.tgz", + "integrity": "sha512-Y7ncuy78bJqHI35NwzWol8E0X7XkRVS4K4P4TCyzWkOJih5NDvtoRDW4Ba9YJJoB2igm9yXDdYI/+fkiiAxPzA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.22.0", - "@typescript-eslint/visitor-keys": "8.22.0", + "@typescript-eslint/types": "8.20.0", + "@typescript-eslint/visitor-keys": "8.20.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -12254,7 +10700,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.22.0.tgz", "integrity": "sha512-T8oc1MbF8L+Bk2msAvCUzjxVB2Z2f+vXYfcucE2wOmYs7ZUwco5Ep0fYZw8quNwOiw9K8GYVL+Kgc2pETNTLOg==", "dev": true, - "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@typescript-eslint/scope-manager": "8.22.0", @@ -12273,12 +10718,67 @@ "typescript": ">=4.8.4 <5.8.0" } }, - "node_modules/@typescript-eslint/visitor-keys": { + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.22.0.tgz", + "integrity": "sha512-/lwVV0UYgkj7wPSw0o8URy6YI64QmcOdwHuGuxWIYznO6d45ER0wXUbksr9pYdViAofpUCNJx/tAzNukgvaaiQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.22.0", + "@typescript-eslint/visitor-keys": "8.22.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.22.0.tgz", + "integrity": "sha512-0S4M4baNzp612zwpD4YOieP3VowOARgK2EkN/GBn95hpyF8E2fbMT55sRHWBq+Huaqk3b3XK+rxxlM8sPgGM6A==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.22.0.tgz", + "integrity": "sha512-SJX99NAS2ugGOzpyhMza/tX+zDwjvwAtQFLsBo3GQxiGcvaKlqGBkmZ+Y1IdiSi9h4Q0Lr5ey+Cp9CGWNY/F/w==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.22.0", + "@typescript-eslint/visitor-keys": "8.22.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { "version": "8.22.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.22.0.tgz", "integrity": "sha512-AWpYAXnUgvLNabGTy3uBylkgZoosva/miNd1I8Bz3SjotmQPbVqhO4Cczo8AsZ44XVErEBPr/CRSgaj8sG7g0w==", "dev": true, - "license": "MIT", "dependencies": { "@typescript-eslint/types": "8.22.0", "eslint-visitor-keys": "^4.2.0" @@ -12291,6 +10791,36 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/utils/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.20.0.tgz", + "integrity": "sha512-v/BpkeeYAsPkKCkR8BDwcno0llhzWVqPOamQrAEMdpZav2Y9OVjd9dwJyBLJWwf335B5DmlifECIkZRJCaGaHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.20.0", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", @@ -12305,9 +10835,9 @@ } }, "node_modules/@ungap/structured-clone": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", - "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dev": true, "license": "ISC" }, @@ -13080,9 +11610,9 @@ } }, "node_modules/agentkeepalive": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz", - "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", + "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", "dev": true, "license": "MIT", "dependencies": { @@ -13159,7 +11689,6 @@ "resolved": "https://registry.npmjs.org/angular-eslint/-/angular-eslint-18.4.3.tgz", "integrity": "sha512-0ZjLzzADGRLUhZC8ZpwSo6CE/m6QhQB/oljMJ0mEfP+lB1sy1v8PBKNsJboIcfEEgGW669Z/efVQ3df88yJLYg==", "dev": true, - "license": "MIT", "dependencies": { "@angular-devkit/core": ">= 18.0.0 < 19.0.0", "@angular-devkit/schematics": ">= 18.0.0 < 19.0.0", @@ -13177,106 +11706,6 @@ "typescript-eslint": "^8.0.0" } }, - "node_modules/angular-eslint/node_modules/@angular-devkit/core": { - "version": "18.2.14", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.14.tgz", - "integrity": "sha512-UGIGOjXuOyCW+5S4tINu7e6LOu738CmTw3h7Ui1I8OzdTIYJcYJrei8sgrwDwOYADRal+p0MeMlnykH3TM5XBA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "8.17.1", - "ajv-formats": "3.0.1", - "jsonc-parser": "3.3.1", - "picomatch": "4.0.2", - "rxjs": "7.8.1", - "source-map": "0.7.4" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^3.5.2" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/angular-eslint/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/angular-eslint/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "optional": true, - "peer": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/angular-eslint/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/angular-eslint/node_modules/readdirp/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", @@ -13489,6 +11918,13 @@ "node": ">=10" } }, + "node_modules/app-builder-lib/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, "node_modules/app-builder-lib/node_modules/fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", @@ -13504,6 +11940,19 @@ "node": ">=12" } }, + "node_modules/app-builder-lib/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/app-builder-lib/node_modules/minimatch": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", @@ -13688,31 +12137,35 @@ "license": "MIT" }, "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, - "license": "Python-2.0" + "license": "MIT", + "peer": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } }, "node_modules/aria-query": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", - "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", "dev": true, "license": "Apache-2.0", - "engines": { - "node": ">= 0.4" + "dependencies": { + "dequal": "^2.0.3" } }, "node_modules/array-buffer-byte-length": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", - "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "is-array-buffer": "^3.0.5" + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" }, "engines": { "node": ">= 0.4" @@ -13781,16 +12234,16 @@ } }, "node_modules/array.prototype.flat": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", - "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-shim-unscopables": "^1.0.2" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -13800,16 +12253,16 @@ } }, "node_modules/array.prototype.flatmap": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", - "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-shim-unscopables": "^1.0.2" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -13819,19 +12272,20 @@ } }, "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", - "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", "dev": true, "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.8", + "call-bind": "^1.0.5", "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "is-array-buffer": "^3.0.4" + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -13902,16 +12356,6 @@ "node": ">=0.12.0" } }, - "node_modules/async-function": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", - "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -13976,9 +12420,9 @@ } }, "node_modules/autoprefixer/node_modules/browserslist": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", - "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", "dev": true, "funding": [ { @@ -13996,9 +12440,9 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001688", - "electron-to-chromium": "^1.5.73", - "node-releases": "^2.0.19", + "caniuse-lite": "^1.0.30001669", + "electron-to-chromium": "^1.5.41", + "node-releases": "^2.0.18", "update-browserslist-db": "^1.1.1" }, "bin": { @@ -14051,7 +12495,6 @@ "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", "dev": true, - "license": "Apache-2.0", "engines": { "node": ">= 0.4" } @@ -14079,17 +12522,6 @@ "@babel/core": "^7.8.0" } }, - "node_modules/babel-jest/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, "node_modules/babel-loader": { "version": "9.2.1", "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.2.1.tgz", @@ -14126,35 +12558,6 @@ "node": ">=8" } }, - "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", - "dev": true, - "license": "BSD-3-Clause", - "peer": true, - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-istanbul/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "peer": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/babel-plugin-jest-hoist": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", @@ -14203,15 +12606,6 @@ "node": ">=10" } }, - "node_modules/babel-plugin-macros/node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/babel-plugin-macros/node_modules/yaml": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", @@ -14222,14 +12616,14 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.12", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz", - "integrity": "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==", + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", + "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", "dev": true, "license": "MIT", "dependencies": { "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.3", + "@babel/helper-define-polyfill-provider": "^0.6.2", "semver": "^6.3.1" }, "peerDependencies": { @@ -14251,7 +12645,6 @@ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.2", "core-js-compat": "^3.38.0" @@ -14265,7 +12658,6 @@ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz", "integrity": "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.3" }, @@ -14561,39 +12953,10 @@ "dev": true, "license": "MIT" }, - "node_modules/body-parser/node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/body-parser/node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/bonjour-service": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz", - "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", + "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", "dev": true, "license": "MIT", "dependencies": { @@ -14632,15 +12995,14 @@ } }, "node_modules/bootstrap.native": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/bootstrap.native/-/bootstrap.native-5.1.2.tgz", - "integrity": "sha512-jkXzWs1EopckMT5FIc2CS9PsGloOfmHqyC4dHv3nVC5gpnOFoJPVDpUCKsoMta46SBh46g312BI3aWth0zkRDw==", + "version": "5.0.13", + "resolved": "https://registry.npmjs.org/bootstrap.native/-/bootstrap.native-5.0.13.tgz", + "integrity": "sha512-SiiTxaK3LjuOjPaXEnDBQNY3w0t28Qdx6I8drortuFg6Ch3q6cWoOxlFHThcGOPewziVarQAA4WPE00GFQmbWQ==", "dev": true, "license": "MIT", "dependencies": { - "@thednp/event-listener": "^2.0.8", - "@thednp/position-observer": "^1.0.7", - "@thednp/shorty": "^2.0.10" + "@thednp/event-listener": "^2.0.4", + "@thednp/shorty": "^2.0.0" }, "engines": { "node": ">=16", @@ -14670,9 +13032,9 @@ } }, "node_modules/braintree-web": { - "version": "3.103.0", - "resolved": "https://registry.npmjs.org/braintree-web/-/braintree-web-3.103.0.tgz", - "integrity": "sha512-gwmC5LSUP5VUC2HmUyaFnEyLjRRAo1iKKHS5eD9KIAZHB7cAQ2il1V1q2f5zdz7+7EE11eSHXznj6n/Qm6jp6w==", + "version": "3.113.0", + "resolved": "https://registry.npmjs.org/braintree-web/-/braintree-web-3.113.0.tgz", + "integrity": "sha512-qykYxZyld4X1tRNgXZQ3ZGzmhDGTBTRQ6Q24KaG9PuYqo+P2TVDEDOVC6tRbkx2RUIdXLv2M6WpkG7oLqEia9Q==", "license": "MIT", "dependencies": { "@braintree/asset-loader": "2.0.1", @@ -14683,6 +13045,7 @@ "@braintree/sanitize-url": "7.0.4", "@braintree/uuid": "1.0.0", "@braintree/wrap-promise": "2.1.0", + "@paypal/accelerated-checkout-loader": "1.1.0", "card-validator": "10.0.0", "credit-card-type": "10.0.1", "framebus": "6.0.0", @@ -14692,9 +13055,9 @@ } }, "node_modules/braintree-web-drop-in": { - "version": "1.43.0", - "resolved": "https://registry.npmjs.org/braintree-web-drop-in/-/braintree-web-drop-in-1.43.0.tgz", - "integrity": "sha512-lkUpQfYXR0CGtR7mPRR17AnZoYkHjhycxVnMGIPcWT6JPagEZcG/7tYyy34iWjYZeGa2wsquLBDV2Xeita962Q==", + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/braintree-web-drop-in/-/braintree-web-drop-in-1.44.0.tgz", + "integrity": "sha512-maOq9SwiXztIzixJhOras7K44x4UIqqnkyQMYAJqxQ8WkADv9AkflCu2j3IeVYCus/Th9gWWFHcBugn3C4sZGw==", "license": "MIT", "dependencies": { "@braintree/asset-loader": "2.0.1", @@ -14702,7 +13065,7 @@ "@braintree/event-emitter": "0.4.1", "@braintree/uuid": "1.0.0", "@braintree/wrap-promise": "2.1.0", - "braintree-web": "3.103.0" + "braintree-web": "3.113.0" } }, "node_modules/browser-assert": { @@ -14878,6 +13241,13 @@ "node": ">=12.0.0" } }, + "node_modules/builder-util/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, "node_modules/builder-util/node_modules/fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", @@ -14907,6 +13277,19 @@ "node": ">= 6" } }, + "node_modules/builder-util/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/bundle-name": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", @@ -15161,44 +13544,16 @@ } }, "node_modules/call-bind": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", - "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", - "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", - "license": "MIT", - "dependencies": { "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/call-bound": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", - "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "get-intrinsic": "^1.2.6" + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" }, "engines": { "node": ">= 0.4" @@ -15258,9 +13613,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001696", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001696.tgz", - "integrity": "sha512-pDCPkvzfa39ehJtJ+OwGT/2yvT2SbjfHhiIW2LWOAcMQ7BzwxT/XuyUp4OTOd0XFWA6BKw0JalnBHgSi5DGJBQ==", + "version": "1.0.30001677", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001677.tgz", + "integrity": "sha512-fmfjsOlJUpMWu+mAAtZZZHz7UEwsUxIIvu1TJfO1HqFQvB/B+ii0xr9B5HpbZY/mC4XZ8SvjHJqtAY6pDPQEog==", "funding": [ { "type": "opencollective", @@ -15391,28 +13746,6 @@ "node": ">= 16" } }, - "node_modules/cheerio": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", - "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "cheerio-select": "^2.1.0", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "htmlparser2": "^8.0.1", - "parse5": "^7.0.0", - "parse5-htmlparser2-tree-adapter": "^7.0.0" - }, - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/cheeriojs/cheerio?sponsor=1" - } - }, "node_modules/cheerio-select": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", @@ -15432,19 +13765,28 @@ } }, "node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, "license": "MIT", "dependencies": { - "readdirp": "^4.0.1" + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" }, "engines": { - "node": ">= 14.16.0" + "node": ">= 8.10.0" }, "funding": { "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" } }, "node_modules/chownr": { @@ -15458,9 +13800,9 @@ } }, "node_modules/chromatic": { - "version": "11.20.2", - "resolved": "https://registry.npmjs.org/chromatic/-/chromatic-11.20.2.tgz", - "integrity": "sha512-c+M3HVl5Y60c7ipGTZTyeWzWubRW70YsJ7PPDpO1D735ib8+Lu3yGF90j61pvgkXGngpkTPHZyBw83lcu2JMxA==", + "version": "11.25.2", + "resolved": "https://registry.npmjs.org/chromatic/-/chromatic-11.25.2.tgz", + "integrity": "sha512-/9eQWn6BU1iFsop86t8Au21IksTRxwXAl7if8YHD05L2AbuMjClLWZo5cZojqrJHGKDhTqfrC2X2xE4uSm0iKw==", "dev": true, "license": "MIT", "bin": { @@ -15596,13 +13938,12 @@ } }, "node_modules/cli-width": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", - "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", - "dev": true, + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", "license": "ISC", "engines": { - "node": ">= 12" + "node": ">= 10" } }, "node_modules/cliui": { @@ -15675,6 +14016,16 @@ "node": ">=0.10.0" } }, + "node_modules/clone-deep/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/clone-response": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", @@ -16051,67 +14402,6 @@ "typescript": "^5.3.3" } }, - "node_modules/config-file-ts/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/config-file-ts/node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/config-file-ts/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/config-file-ts/node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/connect": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", @@ -16263,10 +14553,70 @@ "webpack": "^5.1.0" } }, + "node_modules/copy-webpack-plugin/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/globby": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz", + "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.2", + "ignore": "^5.2.4", + "path-type": "^5.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/copy-webpack-plugin/node_modules/path-type": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", + "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/copy-webpack-plugin/node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/core-js": { - "version": "3.39.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.39.0.tgz", - "integrity": "sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g==", + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.40.0.tgz", + "integrity": "sha512-7vsMc/Lty6AGnn7uFpYT56QesI5D2Y/UkgKounk87OP9Z2H9Z8kj6jzcSGAxFmUtDOS0ntK6lbQz+Nsa0Jj6mQ==", "hasInstallScript": true, "license": "MIT", "funding": { @@ -16275,13 +14625,13 @@ } }, "node_modules/core-js-compat": { - "version": "3.40.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.40.0.tgz", - "integrity": "sha512-0XEDpr5y5mijvw8Lbc6E5AkjrHfp7eEoPlu36SWeAbcL8fn1G1ANe8DBlo2XoNN89oVpxWwOjYIPVzR4ZvsKCQ==", + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.39.0.tgz", + "integrity": "sha512-VgEUx3VwlExr5no0tXlBt+silBvhTryPwCXRI2Id1PN8WTKu7MreethvddqOubrYxkFdv/RnYrqlv1sFNAUelw==", "dev": true, "license": "MIT", "dependencies": { - "browserslist": "^4.24.3" + "browserslist": "^4.24.2" }, "funding": { "type": "opencollective", @@ -16289,9 +14639,9 @@ } }, "node_modules/core-js-compat/node_modules/browserslist": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", - "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", "dev": true, "funding": [ { @@ -16309,9 +14659,9 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001688", - "electron-to-chromium": "^1.5.73", - "node-releases": "^2.0.19", + "caniuse-lite": "^1.0.30001669", + "electron-to-chromium": "^1.5.41", + "node-releases": "^2.0.18", "update-browserslist-db": "^1.1.1" }, "bin": { @@ -16368,6 +14718,26 @@ } } }, + "node_modules/cosmiconfig/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/cosmiconfig/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/crc": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", @@ -16469,7 +14839,6 @@ "integrity": "sha512-Oyqew0FGM0wYUSNqR0L6AteO5MpMoUU0rhKRieXeiKs+PmRTxiJMyaunYB2KF6fQ3dzChXKCpbFOEJx3OQ1v/Q==", "deprecated": "Ownership of Critters has moved to the Nuxt team, who will be maintaining the project going forward. If you'd like to keep using Critters, please switch to the actively-maintained fork at https://github.com/danielroe/beasties", "dev": true, - "license": "Apache-2.0", "dependencies": { "chalk": "^4.1.0", "css-select": "^5.1.0", @@ -16500,9 +14869,9 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -16625,12 +14994,6 @@ "node": ">=18" } }, - "node_modules/cssstyle/node_modules/rrweb-cssom": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", - "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==", - "license": "MIT" - }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", @@ -16651,15 +15014,15 @@ } }, "node_modules/data-view-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", - "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", + "call-bind": "^1.0.6", "es-errors": "^1.3.0", - "is-data-view": "^1.0.2" + "is-data-view": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -16669,31 +15032,31 @@ } }, "node_modules/data-view-byte-length": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", - "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", + "call-bind": "^1.0.7", "es-errors": "^1.3.0", - "is-data-view": "^1.0.2" + "is-data-view": "^1.0.1" }, "engines": { "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/inspect-js" + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/data-view-byte-offset": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", - "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", + "call-bind": "^1.0.6", "es-errors": "^1.3.0", "is-data-view": "^1.0.1" }, @@ -16761,9 +15124,9 @@ } }, "node_modules/decimal.js": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.5.0.tgz", - "integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==", + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", "license": "MIT" }, "node_modules/decode-named-character-reference": { @@ -17128,16 +15491,6 @@ "node": ">=8" } }, - "node_modules/dir-glob/node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/dlv": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", @@ -17163,6 +15516,13 @@ "dmg-license": "^1.0.11" } }, + "node_modules/dmg-builder/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, "node_modules/dmg-builder/node_modules/fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", @@ -17178,6 +15538,19 @@ "node": ">=12" } }, + "node_modules/dmg-builder/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/dmg-license": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/dmg-license/-/dmg-license-1.0.11.tgz", @@ -17333,9 +15706,9 @@ } }, "node_modules/domutils": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", - "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -17398,20 +15771,6 @@ "dev": true, "license": "BSD-2-Clause" }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/duplexer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", @@ -17600,70 +15959,6 @@ "chokidar": "^3.5.2" } }, - "node_modules/electron-reload/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/electron-reload/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/electron-reload/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/electron-reload/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, "node_modules/electron-store": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/electron-store/-/electron-store-8.2.0.tgz", @@ -17679,9 +15974,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.90", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.90.tgz", - "integrity": "sha512-C3PN4aydfW91Natdyd449Kw+BzhLmof6tzy5W1pFC5SpQxVXT+oyiyOG9AgYYSN9OdA/ik3YkCrpwqI8ug5Tug==", + "version": "1.5.51", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.51.tgz", + "integrity": "sha512-kKeWV57KSS8jH4alKt/jKnvHPmJgBxXzGUSbMd4eQF+iOsVPl7bz2KUmu6eo80eMP8wVioTfTyTzdMgM15WXNg==", "license": "ISC" }, "node_modules/electron-updater": { @@ -17701,6 +15996,13 @@ "tiny-typed-emitter": "^2.1.0" } }, + "node_modules/electron-updater/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, "node_modules/electron-updater/node_modules/builder-util-runtime": { "version": "9.2.10", "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.10.tgz", @@ -17730,23 +16032,29 @@ "node": ">=12" } }, + "node_modules/electron-updater/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/electron/node_modules/@types/node": { - "version": "20.17.16", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.16.tgz", - "integrity": "sha512-vOTpLduLkZXePLxHiHsBLp98mHGnl8RptV4YAO3HfKO5UHjDvySGbxKtpYfy8Sx5+WKcgc45qNreJJRVM3L6mw==", + "version": "20.17.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.14.tgz", + "integrity": "sha512-w6qdYetNL5KRBiSClK/KWai+2IMEJuAj+EujKCumalFOwXtvOXaEan9AuwcRID2IcOIAWSIfR495hBtgKlx2zg==", "dev": true, "license": "MIT", "dependencies": { "undici-types": "~6.19.2" } }, - "node_modules/electron/node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "dev": true, - "license": "MIT" - }, "node_modules/emitter-component": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/emitter-component/-/emitter-component-1.1.2.tgz", @@ -17787,9 +16095,10 @@ } }, "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -17816,9 +16125,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.18.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.0.tgz", - "integrity": "sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ==", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", "dev": true, "license": "MIT", "dependencies": { @@ -17851,6 +16160,19 @@ "node": ">=6" } }, + "node_modules/envify": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/envify/-/envify-4.1.0.tgz", + "integrity": "sha512-IKRVVoAYr4pIx4yIWNsz9mOsboxlNXiu7TNBnem/K/uTHdkyzXWDzHCK7UTolqBbgaBz0tQHsD3YNls0uIIjiw==", + "license": "MIT", + "dependencies": { + "esprima": "^4.0.0", + "through": "~2.3.4" + }, + "bin": { + "envify": "bin/envify" + } + }, "node_modules/envinfo": { "version": "7.14.0", "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.14.0.tgz", @@ -17908,63 +16230,58 @@ } }, "node_modules/es-abstract": { - "version": "1.23.9", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz", - "integrity": "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==", + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", "dev": true, "license": "MIT", "dependencies": { - "array-buffer-byte-length": "^1.0.2", - "arraybuffer.prototype.slice": "^1.0.4", + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "data-view-buffer": "^1.0.2", - "data-view-byte-length": "^1.0.2", - "data-view-byte-offset": "^1.0.1", - "es-define-property": "^1.0.1", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.1.0", - "es-to-primitive": "^1.3.0", - "function.prototype.name": "^1.1.8", - "get-intrinsic": "^1.2.7", - "get-proto": "^1.0.0", - "get-symbol-description": "^1.1.0", - "globalthis": "^1.0.4", - "gopd": "^1.2.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2", - "has-proto": "^1.2.0", - "has-symbols": "^1.1.0", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", "hasown": "^2.0.2", - "internal-slot": "^1.1.0", - "is-array-buffer": "^3.0.5", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", "is-callable": "^1.2.7", - "is-data-view": "^1.0.2", - "is-regex": "^1.2.1", - "is-shared-array-buffer": "^1.0.4", - "is-string": "^1.1.1", - "is-typed-array": "^1.1.15", - "is-weakref": "^1.1.0", - "math-intrinsics": "^1.1.0", - "object-inspect": "^1.13.3", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", "object-keys": "^1.1.1", - "object.assign": "^4.1.7", - "own-keys": "^1.0.1", - "regexp.prototype.flags": "^1.5.3", - "safe-array-concat": "^1.1.3", - "safe-push-apply": "^1.0.0", - "safe-regex-test": "^1.1.0", - "set-proto": "^1.0.0", - "string.prototype.trim": "^1.2.10", - "string.prototype.trimend": "^1.0.9", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.3", - "typed-array-byte-length": "^1.0.3", - "typed-array-byte-offset": "^1.0.4", - "typed-array-length": "^1.0.7", - "unbox-primitive": "^1.1.0", - "which-typed-array": "^1.1.18" + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" }, "engines": { "node": ">= 0.4" @@ -17974,10 +16291,13 @@ } }, "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, "engines": { "node": ">= 0.4" } @@ -17999,9 +16319,10 @@ "license": "MIT" }, "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -18011,16 +16332,15 @@ } }, "node_modules/es-set-tostringtag": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", "dev": true, "license": "MIT", "dependencies": { - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", + "get-intrinsic": "^1.2.4", "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" + "hasown": "^2.0.1" }, "engines": { "node": ">= 0.4" @@ -18037,15 +16357,15 @@ } }, "node_modules/es-to-primitive": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", - "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, "license": "MIT", "dependencies": { - "is-callable": "^1.2.7", - "is-date-object": "^1.0.5", - "is-symbol": "^1.0.4" + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -18075,7 +16395,6 @@ "integrity": "sha512-1lvV17H2bMYda/WaFb2jLPeHU3zml2k4/yagNMG8Q/YtfMjCwEUZa2eXXMgZTVSL5q1n4H7sQ0X6CdJDqqeCFA==", "dev": true, "hasInstallScript": true, - "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -18127,7 +16446,6 @@ "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.23.0.tgz", "integrity": "sha512-6jP8UmWy6R6TUUV8bMuC3ZyZ6lZKI56x0tkxyCIqWwRRJ/DgeQKneh/Oid5EoGoPFLrGNkz47ZEtWAYuiY/u9g==", "dev": true, - "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -18580,6 +16898,13 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/eslint/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, "node_modules/eslint/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -18608,6 +16933,19 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/eslint/node_modules/globals": { "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", @@ -18624,14 +16962,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "node_modules/eslint/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "license": "MIT", - "engines": { - "node": ">= 4" + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, "node_modules/eslint/node_modules/json-schema-traverse": { @@ -18689,7 +17030,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", @@ -18989,16 +17329,6 @@ "dev": true, "license": "MIT" }, - "node_modules/express/node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/express/node_modules/finalhandler": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", @@ -19031,19 +17361,6 @@ "node": ">=4" } }, - "node_modules/express/node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/express/node_modules/path-to-regexp": { "version": "0.1.12", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", @@ -19051,22 +17368,6 @@ "dev": true, "license": "MIT" }, - "node_modules/express/node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/express/node_modules/send": { "version": "0.19.0", "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", @@ -19102,16 +17403,6 @@ "node": ">= 0.8" } }, - "node_modules/express/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -19145,6 +17436,18 @@ "node": ">=0.10.0" } }, + "node_modules/external-editor/node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/extract-zip": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", @@ -19214,19 +17517,6 @@ "node": ">=8.6.0" } }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -19242,20 +17532,10 @@ "license": "MIT" }, "node_modules/fast-uri": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", - "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz", + "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], "license": "BSD-3-Clause" }, "node_modules/fastest-levenshtein": { @@ -19269,9 +17549,9 @@ } }, "node_modules/fastq": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz", - "integrity": "sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, "license": "ISC", "dependencies": { @@ -19323,9 +17603,9 @@ } }, "node_modules/fdir": { - "version": "6.4.3", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.3.tgz", - "integrity": "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.2.tgz", + "integrity": "sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==", "dev": true, "license": "MIT", "peerDependencies": { @@ -19448,6 +17728,16 @@ "ms": "2.0.0" } }, + "node_modules/finalhandler/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/finalhandler/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -19455,6 +17745,29 @@ "dev": true, "license": "MIT" }, + "node_modules/finalhandler/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/find-cache-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", @@ -19604,9 +17917,9 @@ } }, "node_modules/flatted": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", - "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true, "license": "ISC" }, @@ -19632,19 +17945,13 @@ } }, "node_modules/for-each": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.4.tgz", - "integrity": "sha512-kKaIINnFpzW6ffJNDjjyjrk21BkDx38c0xa/klsT8VzLCaMEefv4ZTacrcVR4DmgTeBra++jMDAfS/tS799YDw==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dev": true, "license": "MIT", "dependencies": { - "is-callable": "^1.2.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "is-callable": "^1.1.3" } }, "node_modules/foreground-child": { @@ -19731,31 +18038,6 @@ "concat-map": "0.0.1" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", @@ -19788,19 +18070,6 @@ "node": ">=12" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -19821,42 +18090,6 @@ "node": "*" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", @@ -20014,9 +18247,9 @@ "license": "MIT" }, "node_modules/fs-extra": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", - "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "dev": true, "license": "MIT", "dependencies": { @@ -20099,18 +18332,16 @@ } }, "node_modules/function.prototype.name": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", - "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "functions-have-names": "^1.2.3", - "hasown": "^2.0.2", - "is-callable": "^1.2.7" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" }, "engines": { "node": ">= 0.4" @@ -20162,21 +18393,16 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz", - "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-define-property": "^1.0.1", "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", "function-bind": "^1.1.2", - "get-proto": "^1.0.0", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" }, "engines": { "node": ">= 0.4" @@ -20196,19 +18422,6 @@ "node": ">=8.0.0" } }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/get-stream": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", @@ -20226,15 +18439,15 @@ } }, "node_modules/get-symbol-description": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", - "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", + "call-bind": "^1.0.5", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6" + "get-intrinsic": "^1.2.4" }, "engines": { "node": ">= 0.4" @@ -20244,9 +18457,9 @@ } }, "node_modules/get-tsconfig": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.0.tgz", - "integrity": "sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==", + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.1.tgz", + "integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==", "dev": true, "license": "MIT", "dependencies": { @@ -20264,40 +18477,37 @@ "license": "MIT" }, "node_modules/glob": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.1.tgz", - "integrity": "sha512-zrQDm8XPnYEKawJScsnM0QzobJxlT/kHOOlRTio8IH/GrmxRE5fjllkzdaHclIuNjUQTJYH2xHNIGfdpJkDJUw==", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", - "jackspeak": "^4.0.1", - "minimatch": "^10.0.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", - "path-scurry": "^2.0.0" + "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" }, - "engines": { - "node": "20 || >=22" - }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "license": "ISC", "dependencies": { - "is-glob": "^4.0.3" + "is-glob": "^4.0.1" }, "engines": { - "node": ">=10.13.0" + "node": ">= 6" } }, "node_modules/glob-to-regexp": { @@ -20307,22 +18517,6 @@ "dev": true, "license": "BSD-2-Clause" }, - "node_modules/glob/node_modules/minimatch": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", - "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/global-agent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", @@ -20369,43 +18563,33 @@ } }, "node_modules/globby": { - "version": "14.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz", - "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, "license": "MIT", "dependencies": { - "@sindresorhus/merge-streams": "^2.1.0", - "fast-glob": "^3.3.2", - "ignore": "^5.2.4", - "path-type": "^5.0.0", - "slash": "^5.1.0", - "unicorn-magic": "^0.1.0" + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" }, "engines": { - "node": ">=18" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/globby/node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "license": "MIT", - "engines": { - "node": ">= 0.4" + "dependencies": { + "get-intrinsic": "^1.1.3" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -20500,14 +18684,11 @@ } }, "node_modules/has-bigints": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", - "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "dev": true, "license": "MIT", - "engines": { - "node": ">= 0.4" - }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -20534,14 +18715,10 @@ } }, "node_modules/has-proto": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", - "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", - "dev": true, + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.0" - }, "engines": { "node": ">= 0.4" }, @@ -20550,9 +18727,9 @@ } }, "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -20858,7 +19035,6 @@ "url": "https://github.com/sponsors/fb55" } ], - "license": "MIT", "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", @@ -20904,6 +19080,15 @@ "node": ">= 0.6" } }, + "node_modules/http-assert/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/http-auth": { "version": "4.1.9", "resolved": "https://registry.npmjs.org/http-auth/-/http-auth-4.1.9.tgz", @@ -20970,19 +19155,10 @@ "node": ">= 0.8" } }, - "node_modules/http-errors/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/http-parser-js": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.9.tgz", - "integrity": "sha512-n1XsPy3rXVxlqxVioEWdC+0+M+SQw0DpJynwtOPo1X+ZlvdzTLtDBIJJlDQTnwZIFJrZSzSGmIOUdP8tu+SgLw==", + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", "dev": true, "license": "MIT" }, @@ -21017,21 +19193,28 @@ } }, "node_modules/http-proxy-middleware": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.3.tgz", - "integrity": "sha512-usY0HG5nyDUwtqpiZdETNbmKtw3QQ1jwYFZ9wi5iHzX2BcILwQKtYDJPo7XHTsu5Z0B2Hj3W9NNnbd+AjFWjqg==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", + "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", "dev": true, "license": "MIT", "dependencies": { - "@types/http-proxy": "^1.17.15", - "debug": "^4.3.6", + "@types/http-proxy": "^1.17.8", "http-proxy": "^1.18.1", - "is-glob": "^4.0.3", - "is-plain-object": "^5.0.0", - "micromatch": "^4.0.8" + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } } }, "node_modules/http2-wrapper": { @@ -21062,10 +19245,13 @@ } }, "node_modules/https-proxy-agent/node_modules/agent-base": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", - "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, "engines": { "node": ">= 14" } @@ -21117,9 +19303,9 @@ } }, "node_modules/i18next": { - "version": "23.16.8", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.16.8.tgz", - "integrity": "sha512-06r/TitrM88Mg5FdUXAKL96dJMzgqLE5dv3ryBAra4KCwD9mJ4ndOTS95ZuymIGoE+2hzfdaMak2X11/es7ZWg==", + "version": "23.16.4", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.16.4.tgz", + "integrity": "sha512-9NIYBVy9cs4wIqzurf7nLXPyf3R78xYbxExVqHLK9od3038rjpyOEzW+XB130kZ1N4PZ9inTtJ471CRJ4Ituyg==", "dev": true, "funding": [ { @@ -21212,9 +19398,9 @@ "license": "BSD-3-Clause" }, "node_modules/ignore": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-6.0.2.tgz", - "integrity": "sha512-InwqeHHN2XpumIkMvpl/DCJVrAHgCsG5+cn1XlnLWGwtZBm8QJfSusItfrwx81CTp5agNZqpKU2J/ccC5nGT4A==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, "license": "MIT", "engines": { @@ -21226,7 +19412,6 @@ "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-6.0.5.tgz", "integrity": "sha512-VuuG0wCnjhnylG1ABXT3dAuIpTNDs/G8jlpmwXY03fXoXy/8ZK8/T+hMzt8L4WnrLCJgdybqgPagnF/f97cg3A==", "dev": true, - "license": "ISC", "dependencies": { "minimatch": "^9.0.0" }, @@ -21255,11 +19440,10 @@ "license": "MIT" }, "node_modules/immutable": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.0.3.tgz", - "integrity": "sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==", - "dev": true, - "license": "MIT" + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", + "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==", + "dev": true }, "node_modules/import-fresh": { "version": "3.3.0", @@ -21277,6 +19461,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/import-local": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", @@ -21424,7 +19617,6 @@ "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", "dev": true, - "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -21461,31 +19653,16 @@ "node": ">=12.0.0" } }, - "node_modules/inquirer/node_modules/cli-width": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", - "license": "ISC", - "engines": { - "node": ">= 10" - } - }, - "node_modules/inquirer/node_modules/mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "license": "ISC" - }, "node_modules/internal-slot": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", - "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "hasown": "^2.0.2", - "side-channel": "^1.1.0" + "hasown": "^2.0.0", + "side-channel": "^1.0.4" }, "engines": { "node": ">= 0.4" @@ -21532,25 +19709,32 @@ "node": ">= 12" } }, + "node_modules/ip-address/node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true, + "license": "BSD-3-Clause" + }, "node_modules/ipaddr.js": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", - "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "dev": true, "license": "MIT", "engines": { - "node": ">= 10" + "node": ">= 0.10" } }, "node_modules/is-arguments": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", - "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", - "has-tostringtag": "^1.0.2" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -21560,15 +19744,14 @@ } }, "node_modules/is-array-buffer": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", - "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "get-intrinsic": "^1.2.6" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" }, "engines": { "node": ">= 0.4" @@ -21583,37 +19766,14 @@ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "license": "MIT" }, - "node_modules/is-async-function": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", - "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "async-function": "^1.0.0", - "call-bound": "^1.0.3", - "get-proto": "^1.0.1", - "has-tostringtag": "^1.0.2", - "safe-regex-test": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-bigint": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", - "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dev": true, "license": "MIT", "dependencies": { - "has-bigints": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" + "has-bigints": "^1.0.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -21633,14 +19793,14 @@ } }, "node_modules/is-boolean-object": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.1.tgz", - "integrity": "sha512-l9qO6eFlUETHtuihLcYOaLKByJ1f+N4kthcU9YjHy3N+B3hWv0y/2Nd0mu/7lTFnRQHTrSdXF50HQ3bl5fEnng==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", - "has-tostringtag": "^1.0.2" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -21686,9 +19846,9 @@ } }, "node_modules/is-core-module": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", "license": "MIT", "dependencies": { "hasown": "^2.0.2" @@ -21701,14 +19861,12 @@ } }, "node_modules/is-data-view": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", - "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", - "get-intrinsic": "^1.2.6", "is-typed-array": "^1.1.13" }, "engines": { @@ -21719,14 +19877,13 @@ } }, "node_modules/is-date-object": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", - "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", - "has-tostringtag": "^1.0.2" + "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -21760,22 +19917,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-finalizationregistry": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", - "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -21797,15 +19938,12 @@ } }, "node_modules/is-generator-function": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", - "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "get-proto": "^1.0.0", - "has-tostringtag": "^1.0.2", - "safe-regex-test": "^1.1.0" + "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -21878,10 +20016,10 @@ "dev": true, "license": "MIT" }, - "node_modules/is-map": { + "node_modules/is-negative-zero": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", - "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true, "license": "MIT", "engines": { @@ -21914,14 +20052,13 @@ } }, "node_modules/is-number-object": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", - "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" + "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -21951,13 +20088,13 @@ } }, "node_modules/is-plain-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", "dev": true, "license": "MIT", "engines": { - "node": ">=12" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -21968,7 +20105,6 @@ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -21986,29 +20122,15 @@ "license": "MIT" }, "node_modules/is-regex": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", - "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "gopd": "^1.2.0", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-set": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", - "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -22017,13 +20139,13 @@ } }, "node_modules/is-shared-array-buffer": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", - "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3" + "call-bind": "^1.0.7" }, "engines": { "node": ">= 0.4" @@ -22046,14 +20168,13 @@ } }, "node_modules/is-string": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", - "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" + "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -22063,15 +20184,13 @@ } }, "node_modules/is-symbol": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", - "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", - "has-symbols": "^1.1.0", - "safe-regex-test": "^1.1.0" + "has-symbols": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -22081,13 +20200,13 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", - "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", "dev": true, "license": "MIT", "dependencies": { - "which-typed-array": "^1.1.16" + "which-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" @@ -22108,47 +20227,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-weakmap": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", - "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-weakref": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.0.tgz", - "integrity": "sha512-SXM8Nwyys6nT5WP6pltOwKytLV7FqQ4UiibxVmW+EIosHcmCqkkjViTb5SNssDlkCiEYRP1/pdWUKVvZBmsR2Q==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakset": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", - "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "get-intrinsic": "^1.2.6" - }, - "engines": { - "node": ">= 0.4" + "call-bind": "^1.0.2" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -22219,20 +20305,32 @@ } }, "node_modules/istanbul-lib-instrument": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", - "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, "license": "BSD-3-Clause", + "peer": true, "dependencies": { - "@babel/core": "^7.23.9", - "@babel/parser": "^7.23.9", - "@istanbuljs/schema": "^0.1.3", + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", "istanbul-lib-coverage": "^3.2.0", - "semver": "^7.5.4" + "semver": "^6.3.0" }, "engines": { - "node": ">=10" + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "peer": true, + "bin": { + "semver": "bin/semver.js" } }, "node_modules/istanbul-lib-report": { @@ -22294,19 +20392,19 @@ } }, "node_modules/jackspeak": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.2.tgz", - "integrity": "sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" }, - "engines": { - "node": "20 || >=22" - }, "funding": { "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" } }, "node_modules/jake": { @@ -22467,17 +20565,6 @@ "license": "MIT", "peer": true }, - "node_modules/jest-circus/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-cli": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", @@ -22647,17 +20734,6 @@ "license": "MIT", "peer": true }, - "node_modules/jest-config/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-diff": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", @@ -23056,6 +21132,16 @@ "fsevents": "^2.3.2" } }, + "node_modules/jest-haste-map/node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "peer": true, + "dependencies": { + "makeerror": "1.0.12" + } + }, "node_modules/jest-junit": { "version": "16.0.0", "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-16.0.0.tgz", @@ -23242,16 +21328,6 @@ "dev": true, "license": "MIT" }, - "node_modules/jest-message-util/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/jest-mock": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", @@ -23412,17 +21488,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-resolve/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-runner": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", @@ -23564,17 +21629,6 @@ "node": "*" } }, - "node_modules/jest-runtime/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-snapshot": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", @@ -23804,9 +21858,9 @@ } }, "node_modules/jiti": { - "version": "1.21.7", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", - "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "version": "1.21.6", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", "dev": true, "license": "MIT", "bin": { @@ -23863,13 +21917,15 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "argparse": "^2.0.1" + "argparse": "^1.0.7", + "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" @@ -23893,22 +21949,22 @@ } }, "node_modules/jsdom": { - "version": "25.0.1", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.1.tgz", - "integrity": "sha512-8i7LzZj7BF8uplX+ZyOlIz86V6TAsSs+np6m1kpW9u0JWi4z/1t+FzcK1aek+ybTnAC4KhBL4uXCNT0wcUIeCw==", + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.0.0.tgz", + "integrity": "sha512-BZYDGVAIriBWTpIxYzrXjv3E/4u8+/pSG5bQdIYCbNCGOvsPkDQfTVLAIXAf9ETdCpduCVTkDe2NNZ8NIwUVzw==", "license": "MIT", "dependencies": { - "cssstyle": "^4.1.0", + "cssstyle": "^4.2.1", "data-urls": "^5.0.0", "decimal.js": "^10.4.3", - "form-data": "^4.0.0", + "form-data": "^4.0.1", "html-encoding-sniffer": "^4.0.0", "http-proxy-agent": "^7.0.2", - "https-proxy-agent": "^7.0.5", + "https-proxy-agent": "^7.0.6", "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.12", - "parse5": "^7.1.2", - "rrweb-cssom": "^0.7.1", + "nwsapi": "^2.2.16", + "parse5": "^7.2.1", + "rrweb-cssom": "^0.8.0", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", "tough-cookie": "^5.0.0", @@ -23916,7 +21972,7 @@ "webidl-conversions": "^7.0.0", "whatwg-encoding": "^3.1.1", "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^14.0.0", + "whatwg-url": "^14.1.0", "ws": "^8.18.0", "xml-name-validator": "^5.0.0" }, @@ -23924,7 +21980,7 @@ "node": ">=18" }, "peerDependencies": { - "canvas": "^2.11.2" + "canvas": "^3.0.0" }, "peerDependenciesMeta": { "canvas": { @@ -23941,6 +21997,20 @@ "node": ">= 14" } }, + "node_modules/jsdom/node_modules/form-data": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/jsdom/node_modules/http-proxy-agent": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", @@ -23954,10 +22024,23 @@ "node": ">= 14" } }, + "node_modules/jsdom/node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/jsdom/node_modules/tough-cookie": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.0.tgz", - "integrity": "sha512-rvZUv+7MoBYTiDmFPBrhL7Ujx9Sk+q9wwm22x8c8T5IJaR+Wsyc7TNxbVxo84kZoRJZZMazowFLqpankBEQrGg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.0.0.tgz", + "integrity": "sha512-FRKsF7cz96xIIeMZ82ehjC3xW2E+O2+v11udrDYewUbszngYhsGa8z6YUMMzO9QJZzzyd0nGGXnML/TReX6W8Q==", "license": "BSD-3-Clause", "dependencies": { "tldts": "^6.1.32" @@ -23970,6 +22053,7 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, "license": "MIT", "bin": { "jsesc": "bin/jsesc" @@ -23990,7 +22074,6 @@ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", "dev": true, - "license": "MIT", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -24010,13 +22093,12 @@ "license": "BSD-2-Clause" }, "node_modules/json-stable-stringify": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.2.1.tgz", - "integrity": "sha512-Lp6HbbBgosLmJbjx0pBLbgvx68FaFU1sdkmBuckmhhJ88kL13OA51CDtR2yJB50eCNMH9wRqtQNNiAqQH4YXnA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.1.1.tgz", + "integrity": "sha512-SU/971Kt5qVQfJpyDveVhQ/vya+5hvrjClFOcr8c0Fq5aODJjMwutrOfCU+eCnVD5gpx1Q3fEqkyom77zH1iIg==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", + "call-bind": "^1.0.5", "isarray": "^2.0.5", "jsonify": "^0.0.1", "object-keys": "^1.1.1" @@ -24057,8 +22139,7 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/jsonfile": { "version": "6.1.0", @@ -24088,8 +22169,7 @@ "dev": true, "engines": [ "node >= 0.2.0" - ], - "license": "MIT" + ] }, "node_modules/jsqr": { "version": "1.4.0", @@ -24189,16 +22269,6 @@ "json-buffer": "3.0.1" } }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/klaw-sync": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", @@ -24301,6 +22371,15 @@ "streaming-json-stringify": "3" } }, + "node_modules/koa/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/koa/node_modules/http-errors": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", @@ -24326,6 +22405,15 @@ "node": ">= 0.6" } }, + "node_modules/koa/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/launch-editor": { "version": "2.9.1", "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.9.1.tgz", @@ -24434,7 +22522,6 @@ "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-12.2.0.tgz", "integrity": "sha512-MYUxjSQSBUQmowc0l5nPieOYwMzGPUaTzB6inNW/bdPEG9zOL3eAAD1Qw5ZxSPk7we5dMojHwNODYMV1hq4EVg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 18.12.0" }, @@ -24617,32 +22704,6 @@ "url": "https://opencollective.com/lint-staged" } }, - "node_modules/lint-staged/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/lint-staged/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/lint-staged/node_modules/chalk": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", @@ -24656,23 +22717,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/lint-staged/node_modules/cli-truncate": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", - "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", - "dev": true, - "license": "MIT", - "dependencies": { - "slice-ansi": "^5.0.0", - "string-width": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/lint-staged/node_modules/commander": { "version": "12.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", @@ -24683,20 +22727,6 @@ "node": ">=18" } }, - "node_modules/lint-staged/node_modules/emoji-regex": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", - "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", - "dev": true, - "license": "MIT" - }, - "node_modules/lint-staged/node_modules/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "dev": true, - "license": "MIT" - }, "node_modules/lint-staged/node_modules/execa": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", @@ -24744,19 +22774,6 @@ "node": ">=16.17.0" } }, - "node_modules/lint-staged/node_modules/is-fullwidth-code-point": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", - "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/lint-staged/node_modules/is-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", @@ -24770,24 +22787,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lint-staged/node_modules/listr2": { - "version": "8.2.5", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.5.tgz", - "integrity": "sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "cli-truncate": "^4.0.0", - "colorette": "^2.0.20", - "eventemitter3": "^5.0.1", - "log-update": "^6.1.0", - "rfdc": "^1.4.1", - "wrap-ansi": "^9.0.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, "node_modules/lint-staged/node_modules/mimic-fn": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", @@ -24846,57 +22845,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lint-staged/node_modules/slice-ansi": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", - "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.0.0", - "is-fullwidth-code-point": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/lint-staged/node_modules/string-width": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lint-staged/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/lint-staged/node_modules/strip-final-newline": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", @@ -24910,28 +22858,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lint-staged/node_modules/wrap-ansi": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", - "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.2.1", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/listr2": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.4.tgz", - "integrity": "sha512-opevsywziHd3zHCVQGAj8zu+Z3yHNkkoYhWIGnq54RrCVwLz0MozotJEDnKsIBLvkfLGN6BLOyAeRrYI0pKA4g==", + "version": "8.2.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.5.tgz", + "integrity": "sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ==", "dev": true, "license": "MIT", "dependencies": { @@ -25122,7 +23052,6 @@ "integrity": "sha512-UGe+BbaSUQtAMZobTb4nHvFMrmvuAQKSeaqAX2meTEQjfsbpl5sxdHD8T72OnwD4GU9uwNhYXIVe4QGs8N9Zyw==", "dev": true, "hasInstallScript": true, - "license": "MIT", "dependencies": { "msgpackr": "^1.10.2", "node-addon-api": "^6.1.0", @@ -25146,8 +23075,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/loader-runner": { "version": "4.3.0", @@ -25164,7 +23092,6 @@ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 12.13.0" } @@ -25240,7 +23167,6 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", - "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.", "dev": true, "license": "MIT" }, @@ -25624,7 +23550,6 @@ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", "dev": true, - "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } @@ -25788,19 +23713,10 @@ "node": ">=10" } }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, "node_modules/mdast-util-find-and-replace": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", - "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz", + "integrity": "sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==", "dev": true, "license": "MIT", "dependencies": { @@ -26080,9 +23996,9 @@ } }, "node_modules/micromark": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.1.tgz", - "integrity": "sha512-eBPdkcoCNvYcxQOAKAlceo5SNdzZWfF+FcSupREAzdAh9rRmE239CEQAiTwIgblwnoM8zzj35sZ5ZwvSEOF6Kw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", + "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", "dev": true, "funding": [ { @@ -26116,9 +24032,9 @@ } }, "node_modules/micromark-core-commonmark": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.2.tgz", - "integrity": "sha512-FKjQKbxd1cibWMM1P9N+H8TwlgGgSkWZMmfuVucLCHaYqeSvJ0hFeHsIa65pA2nYbes0f8LDHPMrd9X7Ujxg9w==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.1.tgz", + "integrity": "sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==", "dev": true, "funding": [ { @@ -26229,9 +24145,9 @@ } }, "node_modules/micromark-extension-gfm-table": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", - "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.0.tgz", + "integrity": "sha512-Ub2ncQv+fwD70/l4ou27b4YzfNaCJOvyX4HxXU15m7mpYY+rjuWzsLIPZHJL253Z643RpbcP1oeIJlQ/SKW67g==", "dev": true, "license": "MIT", "dependencies": { @@ -26279,9 +24195,9 @@ } }, "node_modules/micromark-factory-destination": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", - "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", + "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", "dev": true, "funding": [ { @@ -26301,9 +24217,9 @@ } }, "node_modules/micromark-factory-label": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", - "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", + "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", "dev": true, "funding": [ { @@ -26324,9 +24240,9 @@ } }, "node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", "dev": true, "funding": [ { @@ -26345,9 +24261,9 @@ } }, "node_modules/micromark-factory-title": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", - "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", + "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", "dev": true, "funding": [ { @@ -26368,9 +24284,9 @@ } }, "node_modules/micromark-factory-whitespace": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", - "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", + "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", "dev": true, "funding": [ { @@ -26391,9 +24307,9 @@ } }, "node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "dev": true, "funding": [ { @@ -26412,9 +24328,9 @@ } }, "node_modules/micromark-util-chunked": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", - "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", + "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", "dev": true, "funding": [ { @@ -26432,9 +24348,9 @@ } }, "node_modules/micromark-util-classify-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", - "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", + "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", "dev": true, "funding": [ { @@ -26454,9 +24370,9 @@ } }, "node_modules/micromark-util-combine-extensions": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", - "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", + "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", "dev": true, "funding": [ { @@ -26475,9 +24391,9 @@ } }, "node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", - "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", + "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", "dev": true, "funding": [ { @@ -26495,9 +24411,9 @@ } }, "node_modules/micromark-util-decode-string": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", - "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", + "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", "dev": true, "funding": [ { @@ -26518,9 +24434,9 @@ } }, "node_modules/micromark-util-encode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", - "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", + "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", "dev": true, "funding": [ { @@ -26535,9 +24451,9 @@ "license": "MIT" }, "node_modules/micromark-util-html-tag-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", - "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", + "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", "dev": true, "funding": [ { @@ -26552,9 +24468,9 @@ "license": "MIT" }, "node_modules/micromark-util-normalize-identifier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", - "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", + "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", "dev": true, "funding": [ { @@ -26572,9 +24488,9 @@ } }, "node_modules/micromark-util-resolve-all": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", - "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", + "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", "dev": true, "funding": [ { @@ -26592,9 +24508,9 @@ } }, "node_modules/micromark-util-sanitize-uri": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", - "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", + "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", "dev": true, "funding": [ { @@ -26614,9 +24530,9 @@ } }, "node_modules/micromark-util-subtokenize": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.4.tgz", - "integrity": "sha512-N6hXjrin2GTJDe3MVjf5FuXpm12PGm80BrUAeub9XFXca8JZbP+oIwY4LJSVwFUCL1IPm/WwSVUN7goFHmSGGQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.1.tgz", + "integrity": "sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==", "dev": true, "funding": [ { @@ -26637,9 +24553,9 @@ } }, "node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", "dev": true, "funding": [ { @@ -26654,9 +24570,9 @@ "license": "MIT" }, "node_modules/micromark-util-types": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.1.tgz", - "integrity": "sha512-534m2WhVTddrcKVepwmVEVnUAmtrx9bfIjNoQHRqfnvdaHQiFytEhJoTgpWJvDEXCO5gLTQh3wYC1PgOJA4NSQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", + "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", "dev": true, "funding": [ { @@ -26797,8 +24713,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/minimatch": { "version": "9.0.5", @@ -27103,6 +25018,19 @@ "dev": true, "license": "MIT" }, + "node_modules/morgan/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/mrmime": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", @@ -27124,7 +25052,6 @@ "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.2.tgz", "integrity": "sha512-F9UngXRlPyWCDEASDpTf6c9uNhGPTqnTeLVt7bN+bU1eajoR/8V9ys2BRaV5C/e5ihE6sJ9uPIKaYt6bFuO32g==", "dev": true, - "license": "MIT", "optionalDependencies": { "msgpackr-extract": "^3.0.2" } @@ -27135,7 +25062,6 @@ "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==", "dev": true, "hasInstallScript": true, - "license": "MIT", "optional": true, "dependencies": { "node-gyp-build-optional-packages": "5.2.2" @@ -27222,14 +25148,10 @@ } }, "node_modules/mute-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", - "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "license": "ISC" }, "node_modules/mz": { "version": "2.7.0", @@ -27263,9 +25185,9 @@ } }, "node_modules/napi-build-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", - "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", "dev": true, "license": "MIT" }, @@ -27340,7 +25262,6 @@ "integrity": "sha512-px/KnJAJZf5RuBGcfD+Sp2pAKq0ytz8j+1NehvgIGFkvtvFrDM3T8E4x/JJODXK9WZow8RRGrbA9QQ3hs+pDhA==", "dev": true, "hasInstallScript": true, - "license": "MIT", "optional": true, "os": [ "!win32" @@ -27355,7 +25276,6 @@ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", "dev": true, - "license": "MIT", "optional": true }, "node_modules/no-case": { @@ -27370,9 +25290,9 @@ } }, "node_modules/node-abi": { - "version": "3.73.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.73.0.tgz", - "integrity": "sha512-z8iYzQGBu35ZkTQ9mtR8RqugJZ9RCLn8fv3d7LsgDBzOijGQP3RdKTX4LA7LXw03ZhU5z0l4xfhIMgSES31+cg==", + "version": "3.71.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.71.0.tgz", + "integrity": "sha512-SZ40vRiy/+wRTf21hxkkEjPJZpARzUMVcJoQse2EF8qkUWbbO2z7vd5oA/H6bVH6SZQ5STGcu0KRDS7biNRfxw==", "dev": true, "license": "MIT", "dependencies": { @@ -27390,9 +25310,9 @@ "license": "MIT" }, "node_modules/node-addon-api": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.3.0.tgz", - "integrity": "sha512-8VOpLHFrOQlAH+qA0ZzuGRlALRA6/LVh8QJldbrC4DY0hXoMP0l4Acq8TzFC018HztWiRqyCEj2aTWY2UvnJUg==", + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.2.1.tgz", + "integrity": "sha512-vmEOvxwiH8tlOcv4SyE8RH34rI5/nWVaigUeAUPawC6f0+HoDthwI0vkMu4tbtsZrXq6QXFfrkhjofzKEs5tpA==", "license": "MIT", "engines": { "node": "^18 || ^20 || >= 21" @@ -27460,11 +25380,10 @@ } }, "node_modules/node-gyp": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-10.3.1.tgz", - "integrity": "sha512-Pp3nFHBThHzVtNY7U6JfPjvT/DTE8+o/4xKsLQtBoU+j2HLsGlhcfzflAoUreaJbNmYnX+LlLi0qjV8kpyO6xQ==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-10.2.0.tgz", + "integrity": "sha512-sp3FonBAaFe4aYTcFdZUn2NYkbP7xroPGYvQmP4Nl5PxamznItBnNCgjrVTKrEfQynInMsJvZrdmqUnysCJ8rw==", "dev": true, - "license": "MIT", "dependencies": { "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", @@ -27485,9 +25404,9 @@ } }, "node_modules/node-gyp-build": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", - "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "version": "4.8.2", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz", + "integrity": "sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==", "license": "MIT", "bin": { "node-gyp-build": "bin.js", @@ -27500,7 +25419,6 @@ "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", "dev": true, - "license": "MIT", "dependencies": { "detect-libc": "^2.0.1" }, @@ -27515,7 +25433,6 @@ "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz", "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==", "dev": true, - "license": "ISC", "dependencies": { "semver": "^7.3.5" }, @@ -27528,7 +25445,6 @@ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", "dev": true, - "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -27538,7 +25454,6 @@ "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.4.tgz", "integrity": "sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==", "dev": true, - "license": "ISC", "dependencies": { "@npmcli/fs": "^3.1.0", "fs-minipass": "^3.0.0", @@ -27562,7 +25477,6 @@ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -27570,66 +25484,26 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/node-gyp/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/node-gyp/node_modules/isexe": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", "dev": true, - "license": "ISC", "engines": { "node": ">=16" } }, - "node_modules/node-gyp/node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, "node_modules/node-gyp/node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/node-gyp/node_modules/make-fetch-happen": { "version": "13.0.1", "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.1.tgz", "integrity": "sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==", "dev": true, - "license": "ISC", "dependencies": { "@npmcli/agent": "^2.0.0", "cacache": "^18.0.0", @@ -27653,7 +25527,6 @@ "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -27666,7 +25539,6 @@ "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", "dev": true, - "license": "MIT", "dependencies": { "minipass": "^7.0.3", "minipass-sized": "^1.0.3", @@ -27684,7 +25556,6 @@ "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz", "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==", "dev": true, - "license": "ISC", "dependencies": { "abbrev": "^2.0.0" }, @@ -27695,29 +25566,11 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/node-gyp/node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/node-gyp/node_modules/proc-log": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", "dev": true, - "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -27727,7 +25580,6 @@ "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -27740,7 +25592,6 @@ "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", "dev": true, - "license": "ISC", "dependencies": { "unique-slug": "^4.0.0" }, @@ -27753,7 +25604,6 @@ "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", "dev": true, - "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4" }, @@ -27766,7 +25616,6 @@ "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", "dev": true, - "license": "ISC", "dependencies": { "isexe": "^3.1.1" }, @@ -27801,9 +25650,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", "license": "MIT" }, "node_modules/nopt": { @@ -27833,7 +25682,6 @@ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "hosted-git-info": "^7.0.0", "semver": "^7.3.5", @@ -27848,7 +25696,6 @@ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", "dev": true, - "license": "ISC", "dependencies": { "lru-cache": "^10.0.1" }, @@ -27860,8 +25707,7 @@ "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/normalize-path": { "version": "3.0.0", @@ -27901,7 +25747,6 @@ "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-3.0.1.tgz", "integrity": "sha512-+AvaheE/ww1JEwRHOrn4WHNzOxGtVp+adrg2AeZS/7KuxGUYFuBta98wYpfHBbJp6Tg6j1NKSEVHNcfZzJHQwQ==", "dev": true, - "license": "ISC", "dependencies": { "npm-normalize-package-bin": "^3.0.0" }, @@ -27914,7 +25759,6 @@ "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.3.0.tgz", "integrity": "sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "semver": "^7.1.1" }, @@ -27927,7 +25771,6 @@ "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", "dev": true, - "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -27937,7 +25780,6 @@ "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.3.tgz", "integrity": "sha512-sHGJy8sOC1YraBywpzQlIKBE4pBbGbiF95U6Auspzyem956E0+FtDtsx1ZxlOJkQCZ1AFXAY/yuvtFYrOxF+Bw==", "dev": true, - "license": "ISC", "dependencies": { "hosted-git-info": "^7.0.0", "proc-log": "^4.0.0", @@ -27953,7 +25795,6 @@ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", "dev": true, - "license": "ISC", "dependencies": { "lru-cache": "^10.0.1" }, @@ -27965,15 +25806,13 @@ "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/npm-package-arg/node_modules/proc-log": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", "dev": true, - "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -27983,7 +25822,6 @@ "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-8.0.2.tgz", "integrity": "sha512-shYrPFIS/JLP4oQmAwDyk5HcyysKW8/JLTEA32S0Z5TzvpaeeX2yMFfoK1fjEBnCBvVyIB/Jj/GBFdm0wsgzbA==", "dev": true, - "license": "ISC", "dependencies": { "ignore-walk": "^6.0.4" }, @@ -27996,7 +25834,6 @@ "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-9.1.0.tgz", "integrity": "sha512-nkc+3pIIhqHVQr085X9d2JzPzLyjzQS96zbruppqC9aZRm/x8xx6xhI98gHtsfELP2bE+loHq8ZaHFHhe+NauA==", "dev": true, - "license": "ISC", "dependencies": { "npm-install-checks": "^6.0.0", "npm-normalize-package-bin": "^3.0.0", @@ -28012,7 +25849,6 @@ "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-17.1.0.tgz", "integrity": "sha512-5+bKQRH0J1xG1uZ1zMNvxW0VEyoNWgJpY9UDuluPFLKDfJ9u2JmmjmTJV1srBGQOROfdBMiVvnH2Zvpbm+xkVA==", "dev": true, - "license": "ISC", "dependencies": { "@npmcli/redact": "^2.0.0", "jsonparse": "^1.3.1", @@ -28032,7 +25868,6 @@ "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz", "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==", "dev": true, - "license": "ISC", "dependencies": { "semver": "^7.3.5" }, @@ -28045,7 +25880,6 @@ "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.4.tgz", "integrity": "sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==", "dev": true, - "license": "ISC", "dependencies": { "@npmcli/fs": "^3.1.0", "fs-minipass": "^3.0.0", @@ -28069,7 +25903,6 @@ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -28077,56 +25910,17 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/npm-registry-fetch/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm-registry-fetch/node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, "node_modules/npm-registry-fetch/node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/npm-registry-fetch/node_modules/make-fetch-happen": { "version": "13.0.1", "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.1.tgz", "integrity": "sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==", "dev": true, - "license": "ISC", "dependencies": { "@npmcli/agent": "^2.0.0", "cacache": "^18.0.0", @@ -28150,7 +25944,6 @@ "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -28163,7 +25956,6 @@ "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", "dev": true, - "license": "MIT", "dependencies": { "minipass": "^7.0.3", "minipass-sized": "^1.0.3", @@ -28176,29 +25968,11 @@ "encoding": "^0.1.13" } }, - "node_modules/npm-registry-fetch/node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/npm-registry-fetch/node_modules/proc-log": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", "dev": true, - "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -28208,7 +25982,6 @@ "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -28221,7 +25994,6 @@ "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", "dev": true, - "license": "ISC", "dependencies": { "unique-slug": "^4.0.0" }, @@ -28234,7 +26006,6 @@ "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", "dev": true, - "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4" }, @@ -28294,9 +26065,9 @@ } }, "node_modules/object-inspect": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", - "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -28315,17 +26086,15 @@ } }, "node_modules/object.assign": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", - "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", + "call-bind": "^1.0.5", "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0", - "has-symbols": "^1.1.0", + "has-symbols": "^1.0.3", "object-keys": "^1.1.1" }, "engines": { @@ -28370,14 +26139,13 @@ } }, "node_modules/object.values": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", - "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", + "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" }, @@ -28409,9 +26177,9 @@ } }, "node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "license": "MIT", "dependencies": { "ee-first": "1.1.1" @@ -28540,8 +26308,7 @@ "version": "1.5.3", "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.5.3.tgz", "integrity": "sha512-oGFr3T+pYdTGJ+YFEILMpS3es+GiIbs9h/XQrclBXUtd44ey7XwfsMzM31f64I1SQOawDoDr/D823kNCADI8TA==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/os-name": { "version": "4.0.1", @@ -28569,24 +26336,6 @@ "node": ">=0.10.0" } }, - "node_modules/own-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", - "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.6", - "object-keys": "^1.1.1", - "safe-push-apply": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/p-cancelable": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", @@ -28656,9 +26405,9 @@ } }, "node_modules/p-retry": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz", - "integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.0.tgz", + "integrity": "sha512-JA6nkq6hKyWLLasXQXUrO4z8BUZGUt/LjlJxx8Gb2+2ntodU/SS63YZ8b0LUTbQ8ZB9iwOfhEPhg4ykKnn2KsA==", "dev": true, "license": "MIT", "dependencies": { @@ -28712,7 +26461,6 @@ "resolved": "https://registry.npmjs.org/pacote/-/pacote-18.0.6.tgz", "integrity": "sha512-+eK3G27SMwsB8kLIuj4h1FUhHtwiEUo21Tw8wNjmvdlpOEr613edv+8FUsTj/4F/VN5ywGE19X18N7CC2EJk6A==", "dev": true, - "license": "ISC", "dependencies": { "@npmcli/git": "^5.0.0", "@npmcli/installed-package-contents": "^2.0.1", @@ -28744,7 +26492,6 @@ "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz", "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==", "dev": true, - "license": "ISC", "dependencies": { "semver": "^7.3.5" }, @@ -28757,7 +26504,6 @@ "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.4.tgz", "integrity": "sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==", "dev": true, - "license": "ISC", "dependencies": { "@npmcli/fs": "^3.1.0", "fs-minipass": "^3.0.0", @@ -28781,7 +26527,6 @@ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -28789,56 +26534,17 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/pacote/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/pacote/node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, "node_modules/pacote/node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/pacote/node_modules/minipass-collect": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -28846,29 +26552,11 @@ "node": ">=16 || 14 >=14.17" } }, - "node_modules/pacote/node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/pacote/node_modules/proc-log": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", "dev": true, - "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -28878,7 +26566,6 @@ "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -28891,7 +26578,6 @@ "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", "dev": true, - "license": "ISC", "dependencies": { "unique-slug": "^4.0.0" }, @@ -28904,7 +26590,6 @@ "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", "dev": true, - "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4" }, @@ -28919,9 +26604,9 @@ "license": "(MIT AND Zlib)" }, "node_modules/papaparse": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.4.1.tgz", - "integrity": "sha512-HipMsgJkZu8br23pW15uvo6sib6wne/4woLZPlFf3rpDyMe9ywEXUsuD7+6K9PRkJlVT51j/sCOYDKGGS3ZJrw==", + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.5.2.tgz", + "integrity": "sha512-PZXg8UuAc4PcVwLosEEDYjPyfWnTEhOrUfdv+3Bx+NuAb+5NhDmXzg5fHWmdCh1mP5p7JAZfFr3IMQfcntNAdA==", "license": "MIT" }, "node_modules/param-case": { @@ -29181,6 +26866,18 @@ "node": ">=6" } }, + "node_modules/patch-package/node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/path-browserify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", @@ -29223,31 +26920,28 @@ "license": "MIT" }, "node_modules/path-scurry": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", - "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { - "node": "20 || >=22" + "node": ">=16 || 14 >=14.18" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.2.tgz", - "integrity": "sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==", + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "dev": true, - "license": "ISC", - "engines": { - "node": "20 || >=22" - } + "license": "ISC" }, "node_modules/path-to-regexp": { "version": "6.3.0", @@ -29256,16 +26950,12 @@ "license": "MIT" }, "node_modules/path-type": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", - "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", - "dev": true, + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "license": "MIT", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/pathe": { @@ -29317,7 +27007,6 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -29362,7 +27051,6 @@ "resolved": "https://registry.npmjs.org/piscina/-/piscina-4.6.1.tgz", "integrity": "sha512-z30AwWGtQE+Apr+2WBZensP2lIvwoaMcOPkQlIEmSGMJNUvaYACylPYrQM6wSdUNJlnDVMSpLv7xTMJqlVshOA==", "dev": true, - "license": "MIT", "optionalDependencies": { "nice-napi": "^1.0.2" } @@ -29600,9 +27288,9 @@ } }, "node_modules/postcss": { - "version": "8.4.49", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", - "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz", + "integrity": "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==", "dev": true, "funding": [ { @@ -29620,7 +27308,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.7", + "nanoid": "^3.3.8", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -29738,8 +27426,7 @@ "version": "0.2.3", "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/postcss-modules-extract-imports": { "version": "3.1.0", @@ -29755,14 +27442,14 @@ } }, "node_modules/postcss-modules-local-by-default": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", - "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", + "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", "dev": true, "license": "MIT", "dependencies": { "icss-utils": "^5.0.0", - "postcss-selector-parser": "^7.0.0", + "postcss-selector-parser": "^6.0.2", "postcss-value-parser": "^4.1.0" }, "engines": { @@ -29773,13 +27460,13 @@ } }, "node_modules/postcss-modules-scope": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", - "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", + "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", "dev": true, "license": "ISC", "dependencies": { - "postcss-selector-parser": "^7.0.0" + "postcss-selector-parser": "^6.0.4" }, "engines": { "node": "^10 || ^12 || >= 14" @@ -29830,7 +27517,7 @@ "postcss": "^8.2.14" } }, - "node_modules/postcss-nested/node_modules/postcss-selector-parser": { + "node_modules/postcss-selector-parser": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", @@ -29844,20 +27531,6 @@ "node": ">=4" } }, - "node_modules/postcss-selector-parser": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", - "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", @@ -29866,9 +27539,9 @@ "license": "MIT" }, "node_modules/prebuild-install": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", - "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", + "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==", "dev": true, "license": "MIT", "dependencies": { @@ -29877,7 +27550,7 @@ "github-from-package": "0.0.0", "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^2.0.0", + "napi-build-utils": "^1.0.1", "node-abi": "^3.3.0", "pump": "^3.0.0", "rc": "^1.2.7", @@ -30164,16 +27837,6 @@ "node": ">= 0.10" } }, - "node_modules/proxy-addr/node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -30200,16 +27863,10 @@ "optional": true }, "node_modules/psl": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", - "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", - "license": "MIT", - "dependencies": { - "punycode": "^2.3.1" - }, - "funding": { - "url": "https://github.com/sponsors/lupomontero" - } + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "license": "MIT" }, "node_modules/pump": { "version": "3.0.2", @@ -30265,12 +27922,12 @@ "license": "GPL-3.0" }, "node_modules/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.1.0" + "side-channel": "^1.0.6" }, "engines": { "node": ">=0.6" @@ -30484,6 +28141,26 @@ "node": ">=12.0.0" } }, + "node_modules/read-config-file/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/read-config-file/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -30524,17 +28201,29 @@ } }, "node_modules/readdirp": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.1.tgz", - "integrity": "sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "license": "MIT", "engines": { - "node": ">= 14.18.0" + "node": ">=8.6" }, "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/recast": { @@ -30598,29 +28287,6 @@ "dev": true, "license": "Apache-2.0" }, - "node_modules/reflect.getprototypeof": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", - "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.9", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.7", - "get-proto": "^1.0.1", - "which-builtin-type": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -30665,17 +28331,15 @@ "license": "MIT" }, "node_modules/regexp.prototype.flags": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", - "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz", + "integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", + "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-errors": "^1.3.0", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", "set-function-name": "^2.0.2" }, "engines": { @@ -30686,16 +28350,16 @@ } }, "node_modules/regexpu-core": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", - "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.1.1.tgz", + "integrity": "sha512-k67Nb9jvwJcJmVpw0jPttR1/zVfnKf8Km0IPatrU/zJ5XeG3+Slx0xLXs9HByJSzXzrlz5EDvN6yLNMDc2qdnw==", "dev": true, "license": "MIT", "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.0", "regjsgen": "^0.8.0", - "regjsparser": "^0.12.0", + "regjsparser": "^0.11.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.1.0" }, @@ -30711,9 +28375,9 @@ "license": "MIT" }, "node_modules/regjsparser": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", - "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.11.2.tgz", + "integrity": "sha512-3OGZZ4HoLJkkAZx/48mTXJNlmqTGOzc0o9OWQPuWpkOlXXPbyN6OafCcoXUnBqE2D3f/T5L+pWc1kdEmnfnRsA==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -30978,7 +28642,7 @@ "node": ">=8" } }, - "node_modules/resolve-cwd/node_modules/resolve-from": { + "node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", @@ -30988,15 +28652,6 @@ "node": ">=8" } }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/resolve-pkg-maps": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", @@ -31050,9 +28705,9 @@ } }, "node_modules/resolve.exports": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", - "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", "dev": true, "license": "MIT", "peer": true, @@ -31154,6 +28809,89 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rimraf/node_modules/glob": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz", + "integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^4.0.1", + "minimatch": "^10.0.0", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/jackspeak": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.2.tgz", + "integrity": "sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/lru-cache": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.2.tgz", + "integrity": "sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", + "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/path-scurry": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", + "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/roarr": { "version": "2.15.4", "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", @@ -31173,14 +28911,22 @@ "node": ">=8.0" } }, + "node_modules/roarr/node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true + }, "node_modules/rollup": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.4.tgz", - "integrity": "sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A==", + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.4.tgz", + "integrity": "sha512-vGorVWIsWfX3xbcyAS+I047kFKapHYivmkaT63Smj77XwvLSJos6M1xGqZnBPFQFBRZDOcG1QnYEIxAvTr/HjA==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "1.0.5" + "@types/estree": "1.0.6" }, "bin": { "rollup": "dist/bin/rollup" @@ -31190,29 +28936,31 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.22.4", - "@rollup/rollup-android-arm64": "4.22.4", - "@rollup/rollup-darwin-arm64": "4.22.4", - "@rollup/rollup-darwin-x64": "4.22.4", - "@rollup/rollup-linux-arm-gnueabihf": "4.22.4", - "@rollup/rollup-linux-arm-musleabihf": "4.22.4", - "@rollup/rollup-linux-arm64-gnu": "4.22.4", - "@rollup/rollup-linux-arm64-musl": "4.22.4", - "@rollup/rollup-linux-powerpc64le-gnu": "4.22.4", - "@rollup/rollup-linux-riscv64-gnu": "4.22.4", - "@rollup/rollup-linux-s390x-gnu": "4.22.4", - "@rollup/rollup-linux-x64-gnu": "4.22.4", - "@rollup/rollup-linux-x64-musl": "4.22.4", - "@rollup/rollup-win32-arm64-msvc": "4.22.4", - "@rollup/rollup-win32-ia32-msvc": "4.22.4", - "@rollup/rollup-win32-x64-msvc": "4.22.4", + "@rollup/rollup-android-arm-eabi": "4.24.4", + "@rollup/rollup-android-arm64": "4.24.4", + "@rollup/rollup-darwin-arm64": "4.24.4", + "@rollup/rollup-darwin-x64": "4.24.4", + "@rollup/rollup-freebsd-arm64": "4.24.4", + "@rollup/rollup-freebsd-x64": "4.24.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.24.4", + "@rollup/rollup-linux-arm-musleabihf": "4.24.4", + "@rollup/rollup-linux-arm64-gnu": "4.24.4", + "@rollup/rollup-linux-arm64-musl": "4.24.4", + "@rollup/rollup-linux-powerpc64le-gnu": "4.24.4", + "@rollup/rollup-linux-riscv64-gnu": "4.24.4", + "@rollup/rollup-linux-s390x-gnu": "4.24.4", + "@rollup/rollup-linux-x64-gnu": "4.24.4", + "@rollup/rollup-linux-x64-musl": "4.24.4", + "@rollup/rollup-win32-arm64-msvc": "4.24.4", + "@rollup/rollup-win32-ia32-msvc": "4.24.4", + "@rollup/rollup-win32-x64-msvc": "4.24.4", "fsevents": "~2.3.2" } }, "node_modules/rrweb-cssom": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", - "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", + "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==", "license": "MIT" }, "node_modules/run-applescript": { @@ -31336,16 +29084,15 @@ } }, "node_modules/safe-array-concat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", - "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", - "get-intrinsic": "^1.2.6", - "has-symbols": "^1.1.0", + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", "isarray": "^2.0.5" }, "engines": { @@ -31375,32 +29122,16 @@ ], "license": "MIT" }, - "node_modules/safe-push-apply": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", - "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", "dev": true, "license": "MIT", "dependencies": { + "call-bind": "^1.0.6", "es-errors": "^1.3.0", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-regex-test": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", - "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "is-regex": "^1.2.1" + "is-regex": "^1.1.4" }, "engines": { "node": ">= 0.4" @@ -31487,6 +29218,43 @@ } } }, + "node_modules/sass/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/sass/node_modules/immutable": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.0.3.tgz", + "integrity": "sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==", + "dev": true, + "license": "MIT" + }, + "node_modules/sass/node_modules/readdirp": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.1.tgz", + "integrity": "sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/sax": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", @@ -31517,9 +29285,9 @@ } }, "node_modules/schema-utils": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", - "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dev": true, "license": "MIT", "dependencies": { @@ -31529,7 +29297,7 @@ "ajv-keywords": "^5.1.0" }, "engines": { - "node": ">= 10.13.0" + "node": ">= 12.13.0" }, "funding": { "type": "opencollective", @@ -31619,39 +29387,6 @@ "node": ">= 18" } }, - "node_modules/send/node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/send/node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/send/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/serialize-error": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", @@ -31769,6 +29504,16 @@ "dev": true, "license": "ISC" }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/serve-static": { "version": "1.16.2", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", @@ -31802,16 +29547,6 @@ "dev": true, "license": "MIT" }, - "node_modules/serve-static/node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/serve-static/node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -31825,19 +29560,6 @@ "node": ">=4" } }, - "node_modules/serve-static/node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/serve-static/node_modules/send": { "version": "0.19.0", "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", @@ -31873,16 +29595,6 @@ "node": ">= 0.8" } }, - "node_modules/serve-static/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/set-cookie-parser": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", @@ -31922,21 +29634,6 @@ "node": ">= 0.4" } }, - "node_modules/set-proto": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", - "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", - "dev": true, - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", @@ -31962,6 +29659,16 @@ "node": ">=8" } }, + "node_modules/shallow-clone/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -31984,82 +29691,25 @@ } }, "node_modules/shell-quote": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz", - "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", "dev": true, "license": "MIT", - "engines": { - "node": ">= 0.4" - }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "license": "MIT", "dependencies": { + "call-bind": "^1.0.7", "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" }, "engines": { "node": ">= 0.4" @@ -32094,7 +29744,6 @@ "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-2.3.1.tgz", "integrity": "sha512-8G+/XDU8wNsJOQS5ysDVO0Etg9/2uA5gR9l4ZwijjlwxBcrU6RPfwi2+jJmbP+Ap1Hlp/nVAaEO4Fj22/SL2gQ==", "dev": true, - "license": "Apache-2.0", "dependencies": { "@sigstore/bundle": "^2.3.2", "@sigstore/core": "^1.0.0", @@ -32175,16 +29824,13 @@ "license": "MIT" }, "node_modules/slash": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", - "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, "license": "MIT", "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/slice-ansi": { @@ -32333,7 +29979,6 @@ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "dev": true, - "license": "Apache-2.0", "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" @@ -32343,26 +29988,23 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "dev": true, - "license": "CC-BY-3.0" + "dev": true }, "node_modules/spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, - "license": "MIT", "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "node_modules/spdx-license-ids": { - "version": "3.0.21", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz", - "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==", - "dev": true, - "license": "CC0-1.0" + "version": "3.0.20", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", + "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", + "dev": true }, "node_modules/spdy": { "version": "4.0.2", @@ -32410,11 +30052,12 @@ } }, "node_modules/sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true, - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "peer": true }, "node_modules/ssri": { "version": "9.0.1", @@ -32498,12 +30141,12 @@ } }, "node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">= 0.8" } }, "node_modules/std-env": { @@ -32730,19 +30373,16 @@ } }, "node_modules/string.prototype.trim": { - "version": "1.2.10", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", - "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", - "define-data-property": "^1.1.4", + "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-object-atoms": "^1.0.0", - "has-property-descriptors": "^1.0.2" + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -32752,20 +30392,16 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", - "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", + "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" }, - "engines": { - "node": ">= 0.4" - }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -32917,67 +30553,6 @@ "node": ">= 6" } }, - "node_modules/sucrase/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/sucrase/node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/sucrase/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/sucrase/node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/sumchecker": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", @@ -33089,82 +30664,17 @@ "node": ">=14.0.0" } }, - "node_modules/tailwindcss/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/tailwindcss/node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/tailwindcss/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "license": "ISC", "dependencies": { - "is-glob": "^4.0.1" + "is-glob": "^4.0.3" }, "engines": { - "node": ">= 6" - } - }, - "node_modules/tailwindcss/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/tailwindcss/node_modules/postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/tailwindcss/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" + "node": ">=10.13.0" } }, "node_modules/tapable": { @@ -33196,9 +30706,9 @@ } }, "node_modules/tar-fs": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.2.tgz", - "integrity": "sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", "dev": true, "license": "MIT", "dependencies": { @@ -33290,7 +30800,6 @@ "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz", "integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -33305,17 +30814,17 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.11", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.11.tgz", - "integrity": "sha512-RVCsMfuD0+cTt3EwX8hSl2Ks56EbFHWmhluwcqoPKtBnfjiT6olaq7PRIRfhyU8nnC2MrnDrBLfrD/RGE+cVXQ==", + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.25", + "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", - "schema-utils": "^4.3.0", - "serialize-javascript": "^6.0.2", - "terser": "^5.31.1" + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" }, "engines": { "node": ">= 10.13.0" @@ -33339,6 +30848,33 @@ } } }, + "node_modules/terser-webpack-plugin/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, "node_modules/terser-webpack-plugin/node_modules/jest-worker": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", @@ -33354,6 +30890,32 @@ "node": ">= 10.13.0" } }, + "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, "node_modules/terser-webpack-plugin/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -33586,21 +31148,19 @@ } }, "node_modules/tldts-core": { - "version": "6.1.75", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.75.tgz", - "integrity": "sha512-AOvV5YYIAFFBfransBzSTyztkc3IMfz5Eq3YluaRiEu55nn43Fzaufx70UqEKYr8BoLCach4q8g/bg6e5+/aFw==", + "version": "6.1.74", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.74.tgz", + "integrity": "sha512-gTwtY6L2GfuxiL4CWpLknv9JDYYqBvKCk/BT5uAaAvCA0s6pzX7lr2IrkQZSUlnSjRHIjTl8ZwKCVXJ7XNRWYw==", "license": "MIT" }, "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "dev": true, "license": "MIT", - "dependencies": { - "os-tmpdir": "~1.0.2" - }, "engines": { - "node": ">=0.6.0" + "node": ">=14.14" } }, "node_modules/tmp-promise": { @@ -33613,16 +31173,6 @@ "tmp": "^0.2.0" } }, - "node_modules/tmp-promise/node_modules/tmp": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", - "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.14" - } - }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -33760,9 +31310,9 @@ } }, "node_modules/ts-essentials": { - "version": "10.0.4", - "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-10.0.4.tgz", - "integrity": "sha512-lwYdz28+S4nicm+jFi6V58LaAIpxzhg9rLdgNC1VsdP/xiFBseGhF1M/shwCk6zMmwahBZdXcl34LVHrEang3A==", + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-10.0.3.tgz", + "integrity": "sha512-/FrVAZ76JLTWxJOERk04fm8hYENDo0PWSP3YLQKxevLwWtxemGcl5JJEzN4iqfDlRve0ckyfFaOBu4xbNH/wZw==", "dev": true, "license": "MIT", "peerDependencies": { @@ -33831,9 +31381,9 @@ } }, "node_modules/ts-loader": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz", - "integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==", + "version": "9.5.2", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.2.tgz", + "integrity": "sha512-Qo4piXvOTWcMGIgRiuFa6nHNm+54HbYaZCKqc9eeZCLRy3XqafQgwX2F7mofrbJG3g7EEb+lkiR+z2Lic2s3Zw==", "dev": true, "license": "MIT", "dependencies": { @@ -33942,8 +31492,7 @@ "node_modules/tslib": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", - "license": "0BSD" + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/tsscmp": { "version": "1.0.6", @@ -34001,7 +31550,6 @@ "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-2.2.1.tgz", "integrity": "sha512-GwIJau9XaA8nLVbUXsN3IlFi7WmQ48gBUrl3FTkkL/XLu/POhBzfmX9hd33FNMX1qAsfl6ozO1iMmW9NC8YniA==", "dev": true, - "license": "MIT", "dependencies": { "@tufjs/models": "2.0.1", "debug": "^4.3.4", @@ -34016,7 +31564,6 @@ "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz", "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==", "dev": true, - "license": "ISC", "dependencies": { "semver": "^7.3.5" }, @@ -34029,7 +31576,6 @@ "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.4.tgz", "integrity": "sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==", "dev": true, - "license": "ISC", "dependencies": { "@npmcli/fs": "^3.1.0", "fs-minipass": "^3.0.0", @@ -34053,7 +31599,6 @@ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -34061,56 +31606,17 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/tuf-js/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/tuf-js/node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, "node_modules/tuf-js/node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/tuf-js/node_modules/make-fetch-happen": { "version": "13.0.1", "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.1.tgz", "integrity": "sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==", "dev": true, - "license": "ISC", "dependencies": { "@npmcli/agent": "^2.0.0", "cacache": "^18.0.0", @@ -34134,7 +31640,6 @@ "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -34147,7 +31652,6 @@ "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", "dev": true, - "license": "MIT", "dependencies": { "minipass": "^7.0.3", "minipass-sized": "^1.0.3", @@ -34160,29 +31664,11 @@ "encoding": "^0.1.13" } }, - "node_modules/tuf-js/node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/tuf-js/node_modules/proc-log": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", "dev": true, - "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -34192,7 +31678,6 @@ "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -34205,7 +31690,6 @@ "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", "dev": true, - "license": "ISC", "dependencies": { "unique-slug": "^4.0.0" }, @@ -34218,7 +31702,6 @@ "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", "dev": true, - "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4" }, @@ -34252,16 +31735,6 @@ "node": ">= 0.8.0" } }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/type-fest": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", @@ -34289,32 +31762,32 @@ } }, "node_modules/typed-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", - "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", + "call-bind": "^1.0.7", "es-errors": "^1.3.0", - "is-typed-array": "^1.1.14" + "is-typed-array": "^1.1.13" }, "engines": { "node": ">= 0.4" } }, "node_modules/typed-array-byte-length": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", - "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "gopd": "^1.2.0", - "has-proto": "^1.2.0", - "is-typed-array": "^1.1.14" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" }, "engines": { "node": ">= 0.4" @@ -34324,19 +31797,18 @@ } }, "node_modules/typed-array-byte-offset": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", - "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", "dev": true, "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "gopd": "^1.2.0", - "has-proto": "^1.2.0", - "is-typed-array": "^1.1.15", - "reflect.getprototypeof": "^1.0.9" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" }, "engines": { "node": ">= 0.4" @@ -34346,18 +31818,18 @@ } }, "node_modules/typed-array-length": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", - "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", + "has-proto": "^1.0.3", "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0", - "reflect.getprototypeof": "^1.0.6" + "possible-typed-array-names": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -34398,7 +31870,6 @@ "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.20.0.tgz", "integrity": "sha512-Kxz2QRFsgbWj6Xcftlw3Dd154b3cEPFqQC+qMZrMypSijPd4UanKKvoKDrJ4o8AIfZFKAF+7sMaEIR8mTElozA==", "dev": true, - "license": "MIT", "dependencies": { "@typescript-eslint/eslint-plugin": "8.20.0", "@typescript-eslint/parser": "8.20.0", @@ -34416,71 +31887,11 @@ "typescript": ">=4.8.4 <5.8.0" } }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/scope-manager": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.20.0.tgz", - "integrity": "sha512-J7+VkpeGzhOt3FeG1+SzhiMj9NzGD/M6KoGn9f4dbz3YzK9hvbhVTmLj/HiTp9DazIzJ8B4XcM80LrR9Dm1rJw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.20.0", - "@typescript-eslint/visitor-keys": "8.20.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/types": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.20.0.tgz", - "integrity": "sha512-cqaMiY72CkP+2xZRrFt3ExRBu0WmVitN/rYPZErA80mHjHx/Svgp8yfbzkJmDoQ/whcytOPO9/IZXnOc+wigRA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.20.0.tgz", - "integrity": "sha512-Y7ncuy78bJqHI35NwzWol8E0X7XkRVS4K4P4TCyzWkOJih5NDvtoRDW4Ba9YJJoB2igm9yXDdYI/+fkiiAxPzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.20.0", - "@typescript-eslint/visitor-keys": "8.20.0", - "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^2.0.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <5.8.0" - } - }, "node_modules/typescript-eslint/node_modules/@typescript-eslint/utils": { "version": "8.20.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.20.0.tgz", "integrity": "sha512-dq70RUw6UK9ei7vxc4KQtBRk7qkHZv447OUZ6RPQMQl71I3NZxQJX/f32Smr+iqWrB02pHKn2yAdHBb0KNrRMA==", "dev": true, - "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@typescript-eslint/scope-manager": "8.20.0", @@ -34499,37 +31910,6 @@ "typescript": ">=4.8.4 <5.8.0" } }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.20.0.tgz", - "integrity": "sha512-v/BpkeeYAsPkKCkR8BDwcno0llhzWVqPOamQrAEMdpZav2Y9OVjd9dwJyBLJWwf335B5DmlifECIkZRJCaGaHA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.20.0", - "eslint-visitor-keys": "^4.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/typescript-eslint/node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, "node_modules/typescript-strict-plugin": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/typescript-strict-plugin/-/typescript-strict-plugin-2.4.4.tgz", @@ -34677,28 +32057,25 @@ } }, "node_modules/unbox-primitive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", - "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", + "call-bind": "^1.0.2", "has-bigints": "^1.0.2", - "has-symbols": "^1.1.0", - "which-boxed-primitive": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/undici-types": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", - "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "dev": true, "license": "MIT" }, @@ -34779,6 +32156,19 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/unified/node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/unique-filename": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz", @@ -34904,9 +32294,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", - "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", "funding": [ { "type": "opencollective", @@ -34924,7 +32314,7 @@ "license": "MIT", "dependencies": { "escalade": "^3.2.0", - "picocolors": "^1.1.1" + "picocolors": "^1.1.0" }, "bin": { "update-browserslist-db": "cli.js" @@ -35032,9 +32422,9 @@ } }, "node_modules/uuid": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", - "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", "dev": true, "funding": [ "https://github.com/sponsors/broofa", @@ -35074,7 +32464,6 @@ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, - "license": "Apache-2.0", "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" @@ -35085,7 +32474,6 @@ "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz", "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==", "dev": true, - "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -35165,7 +32553,6 @@ "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.6.tgz", "integrity": "sha512-IeL5f8OO5nylsgzd9tq4qD2QqI0k2CQLGrWD0rCN0EQJZpBK5vJAx0I+GDkMOXxQX/OfFHMuLIx6ddAxGX/k+Q==", "dev": true, - "license": "MIT", "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", @@ -35244,74 +32631,6 @@ "url": "https://opencollective.com/vitest" } }, - "node_modules/vite/node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/vite/node_modules/@esbuild/darwin-arm64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", @@ -35320,7 +32639,6 @@ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "darwin" @@ -35329,319 +32647,12 @@ "node": ">=12" } }, - "node_modules/vite/node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/vite/node_modules/esbuild": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "dev": true, "hasInstallScript": true, - "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -35898,23 +32909,11 @@ "dev": true, "license": "ISC" }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "makeerror": "1.0.12" - } - }, "node_modules/watchpack": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", "dev": true, - "license": "MIT", "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -35928,7 +32927,6 @@ "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", "dev": true, - "license": "MIT", "dependencies": { "minimalistic-assert": "^1.0.0" } @@ -35937,7 +32935,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "license": "MIT", "dependencies": { "defaults": "^1.0.3" } @@ -35946,14 +32943,12 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz", "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "license": "BSD-2-Clause", "engines": { "node": ">=12" } @@ -35963,7 +32958,6 @@ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.97.1.tgz", "integrity": "sha512-EksG6gFY3L1eFMROS/7Wzgrii5mBAFe4rIr3r2BTfo7bcc+DWwFZ4OJ/miOuHJO/A85HwyI4eQ0F6IKXesO7Fg==", "dev": true, - "license": "MIT", "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.6", @@ -36010,7 +33004,6 @@ "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-6.0.1.tgz", "integrity": "sha512-MfwFQ6SfwinsUVi0rNJm7rHZ31GyTcpVE5pgVA3hwFRb7COD4TzjUUwhGWKfO50+xdc2MQPuEBBJoqIMGt3JDw==", "dev": true, - "license": "MIT", "dependencies": { "@discoveryjs/json-ext": "^0.6.1", "@webpack-cli/configtest": "^3.0.1", @@ -36048,32 +33041,40 @@ } } }, + "node_modules/webpack-cli/node_modules/@discoveryjs/json-ext": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz", + "integrity": "sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.17.0" + } + }, "node_modules/webpack-cli/node_modules/commander": { "version": "12.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", "dev": true, - "license": "MIT", "engines": { "node": ">=18" } }, "node_modules/webpack-dev-middleware": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz", - "integrity": "sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-6.1.3.tgz", + "integrity": "sha512-A4ChP0Qj8oGociTs6UdlRUGANIGrCDL3y+pmQMc+dSsraXHCatFpmMey4mYELA+juqwUqwQsUgJJISXl1KWmiw==", "dev": true, "license": "MIT", "dependencies": { "colorette": "^2.0.10", - "memfs": "^4.6.0", + "memfs": "^3.4.12", "mime-types": "^2.1.31", - "on-finished": "^2.4.1", "range-parser": "^1.2.1", "schema-utils": "^4.0.0" }, "engines": { - "node": ">= 18.12.0" + "node": ">= 14.15.0" }, "funding": { "type": "opencollective", @@ -36088,45 +33089,11 @@ } } }, - "node_modules/webpack-dev-middleware/node_modules/memfs": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.17.0.tgz", - "integrity": "sha512-4eirfZ7thblFmqFjywlTmuWVSvccHAJbn1r8qQLzmTO11qcqpohOjmY2mFce6x7x7WtskzRqApPD0hv+Oa74jg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jsonjoy.com/json-pack": "^1.0.3", - "@jsonjoy.com/util": "^1.3.0", - "tree-dump": "^1.0.1", - "tslib": "^2.0.0" - }, - "engines": { - "node": ">= 4.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - } - }, - "node_modules/webpack-dev-middleware/node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/webpack-dev-server": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.0.tgz", "integrity": "sha512-90SqqYXA2SK36KcT6o1bvwvZfJFcmoamqeJY7+boioffX9g9C0wjjJRGUrQIuh43pb0ttX7+ssavmj/WN2RHtA==", "dev": true, - "license": "MIT", "dependencies": { "@types/bonjour": "^3.5.13", "@types/connect-history-api-fallback": "^1.5.4", @@ -36178,63 +33145,11 @@ } } }, - "node_modules/webpack-dev-server/node_modules/@types/express": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/webpack-dev-server/node_modules/@types/express-serve-static-core": { - "version": "4.19.6", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", - "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "node_modules/webpack-dev-server/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, "node_modules/webpack-dev-server/node_modules/define-lazy-prop": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -36242,55 +33157,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/webpack-dev-server/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/webpack-dev-server/node_modules/ipaddr.js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, "engines": { - "node": ">= 6" - } - }, - "node_modules/webpack-dev-server/node_modules/http-proxy-middleware": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", - "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@types/express": "^4.17.13" - }, - "peerDependenciesMeta": { - "@types/express": { - "optional": true - } - } - }, - "node_modules/webpack-dev-server/node_modules/is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 10" } }, "node_modules/webpack-dev-server/node_modules/is-wsl": { @@ -36298,7 +33171,6 @@ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", "dev": true, - "license": "MIT", "dependencies": { "is-inside-container": "^1.0.0" }, @@ -36309,6 +33181,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/webpack-dev-server/node_modules/memfs": { + "version": "4.15.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.15.3.tgz", + "integrity": "sha512-vR/g1SgqvKJgAyYla+06G4p/EOcEmwhYuVb1yc1ixcKf8o/sh7Zngv63957ZSNd1xrZJoinmNyDf2LzuP8WJXw==", + "dev": true, + "dependencies": { + "@jsonjoy.com/json-pack": "^1.0.3", + "@jsonjoy.com/util": "^1.3.0", + "tree-dump": "^1.0.1", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">= 4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + } + }, "node_modules/webpack-dev-server/node_modules/open": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", @@ -36328,30 +33219,34 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/webpack-dev-server/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/webpack-dev-server/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "node_modules/webpack-dev-server/node_modules/webpack-dev-middleware": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz", + "integrity": "sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==", "dev": true, "license": "MIT", "dependencies": { - "picomatch": "^2.2.1" + "colorette": "^2.0.10", + "memfs": "^4.6.0", + "mime-types": "^2.1.31", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" }, "engines": { - "node": ">=8.10.0" + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + } } }, "node_modules/webpack-hot-middleware": { @@ -36371,7 +33266,6 @@ "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", "dev": true, - "license": "MIT", "dependencies": { "clone-deep": "^4.0.1", "flat": "^5.0.2", @@ -36430,19 +33324,11 @@ "dev": true, "license": "MIT" }, - "node_modules/webpack/node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", - "dev": true, - "license": "MIT" - }, "node_modules/webpack/node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -36459,15 +33345,14 @@ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "dev": true, - "license": "MIT", "peerDependencies": { "ajv": "^6.9.1" } }, "node_modules/webpack/node_modules/browserslist": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", - "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", "dev": true, "funding": [ { @@ -36485,9 +33370,9 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001688", - "electron-to-chromium": "^1.5.73", - "node-releases": "^2.0.19", + "caniuse-lite": "^1.0.30001669", + "electron-to-chromium": "^1.5.41", + "node-releases": "^2.0.18", "update-browserslist-db": "^1.1.1" }, "bin": { @@ -36516,7 +33401,6 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -36532,8 +33416,7 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/webpack/node_modules/schema-utils": { "version": "3.3.0", @@ -36554,6 +33437,20 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/webpack/node_modules/watchpack": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/websocket-driver": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", @@ -36629,84 +33526,33 @@ } }, "node_modules/which-boxed-primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", - "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-bigint": "^1.1.0", - "is-boolean-object": "^1.2.1", - "is-number-object": "^1.1.1", - "is-string": "^1.1.1", - "is-symbol": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-builtin-type": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", - "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "function.prototype.name": "^1.1.6", - "has-tostringtag": "^1.0.2", - "is-async-function": "^2.0.0", - "is-date-object": "^1.1.0", - "is-finalizationregistry": "^1.1.0", - "is-generator-function": "^1.0.10", - "is-regex": "^1.2.1", - "is-weakref": "^1.0.2", - "isarray": "^2.0.5", - "which-boxed-primitive": "^1.1.0", - "which-collection": "^1.0.2", - "which-typed-array": "^1.1.16" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-collection": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", - "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "dev": true, "license": "MIT", "dependencies": { - "is-map": "^2.0.3", - "is-set": "^2.0.3", - "is-weakmap": "^2.0.2", - "is-weakset": "^2.0.3" - }, - "engines": { - "node": ">= 0.4" + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/which-typed-array": { - "version": "1.1.18", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.18.tgz", - "integrity": "sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", "dev": true, "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "gopd": "^1.2.0", + "gopd": "^1.0.1", "has-tostringtag": "^1.0.2" }, "engines": { @@ -37034,7 +33880,6 @@ "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz", "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==", "dev": true, - "license": "MIT", "engines": { "node": ">=18" }, diff --git a/package.json b/package.json index b5bd19bdbe4..e691aac09b5 100644 --- a/package.json +++ b/package.json @@ -78,6 +78,8 @@ "@types/proper-lockfile": "4.1.4", "@types/retry": "0.12.5", "@types/zxcvbn": "4.4.5", + "@typescript-eslint/rule-tester": "8.22.0", + "@typescript-eslint/utils": "8.22.0", "@webcomponents/custom-elements": "1.6.0", "@yao-pkg/pkg": "5.16.1", "angular-eslint": "18.4.3", @@ -85,7 +87,7 @@ "babel-loader": "9.2.1", "base64-loader": "1.0.0", "browserslist": "4.23.2", - "chromatic": "11.20.2", + "chromatic": "11.25.2", "concurrently": "9.1.2", "copy-webpack-plugin": "12.0.2", "cross-env": "7.0.3", @@ -115,7 +117,7 @@ "lint-staged": "15.4.1", "mini-css-extract-plugin": "2.9.2", "node-ipc": "9.2.1", - "postcss": "8.4.49", + "postcss": "8.5.1", "postcss-loader": "8.1.1", "prettier": "3.4.2", "prettier-plugin-tailwindcss": "0.6.10", @@ -128,12 +130,12 @@ "style-loader": "4.0.0", "tailwindcss": "3.4.17", "ts-jest": "29.2.2", - "ts-loader": "9.5.1", + "ts-loader": "9.5.2", "tsconfig-paths-webpack-plugin": "4.2.0", "type-fest": "2.19.0", "typescript": "5.4.2", "typescript-eslint": "8.20.0", - "typescript-strict-plugin": "^2.4.4", + "typescript-strict-plugin": "2.4.4", "url": "0.11.4", "util": "0.12.5", "wait-on": "8.0.2", @@ -164,17 +166,17 @@ "argon2-browser": "1.18.0", "big-integer": "1.6.52", "bootstrap": "4.6.0", - "braintree-web-drop-in": "1.43.0", + "braintree-web-drop-in": "1.44.0", "buffer": "6.0.3", "bufferutil": "4.0.9", "chalk": "4.1.2", "commander": "11.1.0", - "core-js": "3.39.0", + "core-js": "3.40.0", "form-data": "4.0.1", "https-proxy-agent": "7.0.5", "inquirer": "8.2.6", "jquery": "3.7.1", - "jsdom": "25.0.1", + "jsdom": "26.0.0", "jszip": "3.10.1", "koa": "2.15.3", "koa-bodyparser": "4.4.1", @@ -189,7 +191,7 @@ "nord": "0.2.1", "oidc-client-ts": "2.4.1", "open": "8.4.2", - "papaparse": "5.4.1", + "papaparse": "5.5.2", "patch-package": "8.0.0", "popper.js": "1.16.1", "proper-lockfile": "4.1.2", diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json index 38561f48e04..7ffa34df58c 100644 --- a/tsconfig.eslint.json +++ b/tsconfig.eslint.json @@ -28,8 +28,8 @@ "@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/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/index,ts"], "@bitwarden/node/*": ["./libs/node/src/*"], @@ -40,12 +40,7 @@ "@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": [ - { - "transform": "typescript-transform-paths" - } - ] + } }, "files": [ ".storybook/main.ts", diff --git a/tsconfig.json b/tsconfig.json index a5c2640d29b..cfc33f572e8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -29,8 +29,8 @@ "@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/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/node/*": ["./libs/node/src/*"], @@ -44,9 +44,6 @@ "@bitwarden/web-vault/*": ["./apps/web/src/*"] }, "plugins": [ - { - "transform": "typescript-transform-paths" - }, { "name": "typescript-strict-plugin" }
diff --git a/apps/web/src/app/layouts/header/web-header.skip-stories.ts b/apps/web/src/app/layouts/header/web-header.skip-stories.ts deleted file mode 100644 index 8db4aea3061..00000000000 --- a/apps/web/src/app/layouts/header/web-header.skip-stories.ts +++ /dev/null @@ -1,232 +0,0 @@ -// import { CommonModule } from "@angular/common"; -// import { Component, importProvidersFrom, Injectable, Input } from "@angular/core"; -// import { RouterModule } from "@angular/router"; -// import { -// applicationConfig, -// componentWrapperDecorator, -// Meta, -// moduleMetadata, -// Story, -// } from "@storybook/angular"; -// import { BehaviorSubject, combineLatest, map, of } from "rxjs"; - -// import { JslibModule } from "@bitwarden/angular/jslib.module"; -// import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vault-timeout/vault-timeout-settings.service"; -// import { VaultTimeoutAction } from "@bitwarden/common/enums/vault-timeout-action.enum"; -// import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; -// import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -// import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; -// import { -// AvatarModule, -// BreadcrumbsModule, -// ButtonModule, -// IconButtonModule, -// IconModule, -// InputModule, -// MenuModule, -// NavigationModule, -// TabsModule, -// TypographyModule, -// } from "@bitwarden/components"; - -// import { DynamicAvatarComponent } from "../../components/dynamic-avatar.component"; -// import { PreloadedEnglishI18nModule } from "../../core/tests"; -// import { WebHeaderComponent } from "../header/web-header.component"; - -// import { WebLayoutMigrationBannerService } from "./web-layout-migration-banner.service"; - -// @Injectable({ -// providedIn: "root", -// }) -// class MockStateService { -// activeAccount$ = new BehaviorSubject("1").asObservable(); -// accounts$ = new BehaviorSubject({ "1": { profile: { name: "Foo" } } }).asObservable(); -// } - -// class MockMessagingService implements MessagingService { -// send(subscriber: string, arg?: any) { -// alert(subscriber); -// } -// } - -// class MockVaultTimeoutService { -// availableVaultTimeoutActions$() { -// return new BehaviorSubject([VaultTimeoutAction.Lock]).asObservable(); -// } -// } - -// class MockPlatformUtilsService { -// isSelfHost() { -// return false; -// } -// } - -// @Component({ -// selector: "product-switcher", -// template: ``, -// }) -// class MockProductSwitcher {} - -// @Component({ -// selector: "dynamic-avatar", -// template: ``, -// standalone: true, -// imports: [CommonModule, AvatarModule], -// }) -// class MockDynamicAvatar implements Partial { -// protected name$ = combineLatest([ -// this.stateService.accounts$, -// this.stateService.activeAccount$, -// ]).pipe( -// map( -// ([accounts, activeAccount]) => accounts[activeAccount as keyof typeof accounts].profile.name, -// ), -// ); - -// @Input() -// text: string; - -// constructor(private stateService: MockStateService) {} -// } - -// export default { -// title: "Web/Header", -// component: WebHeaderComponent, -// decorators: [ -// componentWrapperDecorator( -// (story) => `
${story}
`, -// ), -// moduleMetadata({ -// imports: [ -// JslibModule, -// AvatarModule, -// BreadcrumbsModule, -// ButtonModule, -// IconButtonModule, -// IconModule, -// InputModule, -// MenuModule, -// TabsModule, -// TypographyModule, -// NavigationModule, -// MockDynamicAvatar, -// ], -// declarations: [WebHeaderComponent, MockProductSwitcher], -// providers: [ -// { provide: StateService, useClass: MockStateService }, -// { -// provide: WebLayoutMigrationBannerService, -// useValue: { -// showBanner$: of(false), -// } as Partial, -// }, -// { provide: PlatformUtilsService, useClass: MockPlatformUtilsService }, -// { provide: VaultTimeoutSettingsService, useClass: MockVaultTimeoutService }, -// { -// provide: MessagingService, -// useFactory: () => { -// return new MockMessagingService(); -// }, -// }, -// ], -// }), -// applicationConfig({ -// providers: [ -// importProvidersFrom(RouterModule.forRoot([], { useHash: true })), -// importProvidersFrom(PreloadedEnglishI18nModule), -// ], -// }), -// ], -// } as Meta; - -// export const KitchenSink: Story = (args) => ({ -// props: args, -// template: ` -// -// -// Foo -// Bar -// -// -// -// -// -// Foo -// Bar -// -// -// `, -// }); - -// export const Basic: Story = (args) => ({ -// props: args, -// template: ` -// -// `, -// }); - -// export const WithLongTitle: Story = (args) => ({ -// props: args, -// template: ` -// -// `, -// }); - -// export const WithBreadcrumbs: Story = (args) => ({ -// props: args, -// template: ` -// -// -// Foo -// Bar -// -// -// `, -// }); - -// export const WithSearch: Story = (args) => ({ -// props: args, -// template: ` -// -// -// -// `, -// }); - -// export const WithSecondaryContent: Story = (args) => ({ -// props: args, -// template: ` -// -// -// -// `, -// }); - -// export const WithTabs: Story = (args) => ({ -// props: args, -// template: ` -// -// -// Foo -// Bar -// -// -// `, -// }); - -// export const WithTitleSuffixComponent: Story = (args) => ({ -// props: args, -// template: ` -// -// -// -// `, -// }); diff --git a/apps/web/src/app/layouts/header/web-header.stories.ts b/apps/web/src/app/layouts/header/web-header.stories.ts new file mode 100644 index 00000000000..80e98ba7a57 --- /dev/null +++ b/apps/web/src/app/layouts/header/web-header.stories.ts @@ -0,0 +1,260 @@ +import { CommonModule } from "@angular/common"; +import { Component, importProvidersFrom, Injectable, Input } from "@angular/core"; +import { RouterModule } from "@angular/router"; +import { + applicationConfig, + componentWrapperDecorator, + Meta, + moduleMetadata, + StoryObj, +} from "@storybook/angular"; +import { BehaviorSubject, combineLatest, map, of } from "rxjs"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vault-timeout/vault-timeout-settings.service"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { VaultTimeoutAction } from "@bitwarden/common/enums/vault-timeout-action.enum"; +import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; +import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; +import { + AvatarModule, + BreadcrumbsModule, + ButtonModule, + IconButtonModule, + IconModule, + InputModule, + MenuModule, + NavigationModule, + TabsModule, + TypographyModule, +} from "@bitwarden/components"; + +import { DynamicAvatarComponent } from "../../components/dynamic-avatar.component"; +import { PreloadedEnglishI18nModule } from "../../core/tests"; +import { WebHeaderComponent } from "../header/web-header.component"; + +import { WebLayoutMigrationBannerService } from "./web-layout-migration-banner.service"; + +@Injectable({ + providedIn: "root", +}) +class MockStateService { + activeAccount$ = new BehaviorSubject("1").asObservable(); + accounts$ = new BehaviorSubject({ "1": { profile: { name: "Foo" } } }).asObservable(); +} + +@Component({ + selector: "product-switcher", + template: ``, +}) +class MockProductSwitcher {} + +@Component({ + selector: "dynamic-avatar", + template: ``, + standalone: true, + imports: [CommonModule, AvatarModule], +}) +class MockDynamicAvatar implements Partial { + protected name$ = combineLatest([ + this.stateService.accounts$, + this.stateService.activeAccount$, + ]).pipe( + map( + ([accounts, activeAccount]) => accounts[activeAccount as keyof typeof accounts].profile.name, + ), + ); + + @Input() + text?: string; + + constructor(private stateService: MockStateService) {} +} + +export default { + title: "Web/Header", + component: WebHeaderComponent, + decorators: [ + componentWrapperDecorator( + (story) => `
${story}
`, + ), + moduleMetadata({ + imports: [ + JslibModule, + AvatarModule, + BreadcrumbsModule, + ButtonModule, + IconButtonModule, + IconModule, + InputModule, + MenuModule, + TabsModule, + TypographyModule, + NavigationModule, + MockDynamicAvatar, + ], + declarations: [WebHeaderComponent, MockProductSwitcher], + providers: [ + { provide: StateService, useClass: MockStateService }, + { + provide: AccountService, + useValue: { + activeAccount$: of({ + name: "Foobar Warden", + }), + } as Partial, + }, + { + provide: WebLayoutMigrationBannerService, + useValue: { + showBanner$: of(false), + } as Partial, + }, + { + provide: PlatformUtilsService, + useValue: { + isSelfHost() { + return false; + }, + } as Partial, + }, + { + provide: VaultTimeoutSettingsService, + useValue: { + availableVaultTimeoutActions$() { + return new BehaviorSubject([VaultTimeoutAction.Lock]).asObservable(); + }, + } as Partial, + }, + { + provide: MessagingService, + useValue: { + send: (...args: any[]) => { + // eslint-disable-next-line no-console + console.log("MessagingService.send", args); + }, + } as Partial, + }, + ], + }), + applicationConfig({ + providers: [ + importProvidersFrom(RouterModule.forRoot([], { useHash: true })), + importProvidersFrom(PreloadedEnglishI18nModule), + ], + }), + ], +} as Meta; + +type Story = StoryObj; + +export const KitchenSink: Story = { + render: (args) => ({ + props: args, + template: ` + + + Foo + Bar + + + + + + Foo + Bar + + + `, + }), +}; + +export const Basic: Story = { + render: (args: any) => ({ + props: args, + template: ` + + `, + }), +}; + +export const WithLongTitle: Story = { + render: (arg: any) => ({ + props: arg, + template: ` + + + + `, + }), +}; + +export const WithBreadcrumbs: Story = { + render: (args: any) => ({ + props: args, + template: ` + + + Foo + Bar + + + `, + }), +}; + +export const WithSearch: Story = { + render: (args: any) => ({ + props: args, + template: ` + + + + `, + }), +}; + +export const WithSecondaryContent: Story = { + render: (args) => ({ + props: args, + template: ` + + + + `, + }), +}; + +export const WithTabs: Story = { + render: (args) => ({ + props: args, + template: ` + + + Foo + Bar + + + `, + }), +}; + +export const WithTitleSuffixComponent: Story = { + render: (args) => ({ + props: args, + template: ` + + + + `, + }), +}; diff --git a/apps/web/src/app/layouts/product-switcher/navigation-switcher/navigation-switcher.stories.ts b/apps/web/src/app/layouts/product-switcher/navigation-switcher/navigation-switcher.stories.ts index 181779c7c2e..fca9063c8cf 100644 --- a/apps/web/src/app/layouts/product-switcher/navigation-switcher/navigation-switcher.stories.ts +++ b/apps/web/src/app/layouts/product-switcher/navigation-switcher/navigation-switcher.stories.ts @@ -10,6 +10,7 @@ import { Organization } from "@bitwarden/common/admin-console/models/domain/orga import { Provider } from "@bitwarden/common/admin-console/models/domain/provider"; import { AccountService, Account } from "@bitwarden/common/auth/abstractions/account.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { SyncService } from "@bitwarden/common/platform/sync"; import { UserId } from "@bitwarden/common/types/guid"; import { LayoutComponent, NavigationModule } from "@bitwarden/components"; @@ -68,6 +69,12 @@ class MockAccountService implements Partial { }); } +class MockPlatformUtilsService implements Partial { + isSelfHost() { + return false; + } +} + @Component({ selector: "story-layout", template: ``, @@ -105,6 +112,7 @@ export default { { provide: AccountService, useClass: MockAccountService }, { provide: ProviderService, useClass: MockProviderService }, { provide: SyncService, useClass: MockSyncService }, + { provide: PlatformUtilsService, useClass: MockPlatformUtilsService }, ProductSwitcherService, { provide: I18nPipe, diff --git a/apps/web/src/app/layouts/product-switcher/product-switcher.stories.ts b/apps/web/src/app/layouts/product-switcher/product-switcher.stories.ts index 44467bb2b29..ca27aae4581 100644 --- a/apps/web/src/app/layouts/product-switcher/product-switcher.stories.ts +++ b/apps/web/src/app/layouts/product-switcher/product-switcher.stories.ts @@ -10,6 +10,7 @@ import { Organization } from "@bitwarden/common/admin-console/models/domain/orga import { Provider } from "@bitwarden/common/admin-console/models/domain/provider"; import { AccountService, Account } from "@bitwarden/common/auth/abstractions/account.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { SyncService } from "@bitwarden/common/platform/sync"; import { UserId } from "@bitwarden/common/types/guid"; import { IconButtonModule, LinkModule, MenuModule } from "@bitwarden/components"; @@ -68,6 +69,12 @@ class MockAccountService implements Partial { }); } +class MockPlatformUtilsService implements Partial { + isSelfHost() { + return false; + } +} + @Component({ selector: "story-layout", template: ``, @@ -101,6 +108,8 @@ export default { { provide: ProviderService, useClass: MockProviderService }, MockProviderService, { provide: SyncService, useClass: MockSyncService }, + { provide: PlatformUtilsService, useClass: MockPlatformUtilsService }, + MockPlatformUtilsService, ProductSwitcherService, { provide: I18nService, diff --git a/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.spec.ts b/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.spec.ts index 4187900060b..a1ac434d590 100644 --- a/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.spec.ts +++ b/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.spec.ts @@ -11,6 +11,7 @@ import { ProviderService } from "@bitwarden/common/admin-console/abstractions/pr import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { Provider } from "@bitwarden/common/admin-console/models/domain/provider"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { SyncService } from "@bitwarden/common/platform/sync"; import { FakeAccountService, mockAccountServiceWith } from "@bitwarden/common/spec"; @@ -24,6 +25,7 @@ describe("ProductSwitcherService", () => { let organizationService: MockProxy; let providerService: MockProxy; let accountService: FakeAccountService; + let platformUtilsService: MockProxy; let activeRouteParams = convertToParamMap({ organizationId: "1234" }); const getLastSync = jest.fn().mockResolvedValue(new Date("2024-05-14")); const userId = Utils.newGuid() as UserId; @@ -43,11 +45,13 @@ describe("ProductSwitcherService", () => { organizationService = mock(); providerService = mock(); accountService = mockAccountServiceWith(userId); + platformUtilsService = mock(); router.url = "/"; router.events = of({}); organizationService.organizations$.mockReturnValue(of([{}] as Organization[])); providerService.getAll.mockResolvedValue([] as Provider[]); + platformUtilsService.isSelfHost.mockReturnValue(false); TestBed.configureTestingModule({ providers: [ @@ -55,6 +59,7 @@ describe("ProductSwitcherService", () => { { provide: OrganizationService, useValue: organizationService }, { provide: ProviderService, useValue: providerService }, { provide: AccountService, useValue: accountService }, + { provide: PlatformUtilsService, useValue: platformUtilsService }, { provide: ActivatedRoute, useValue: { @@ -138,11 +143,31 @@ describe("ProductSwitcherService", () => { }); describe("Admin/Organizations", () => { - it("includes Organizations in other when there are organizations", async () => { + it("includes Organizations with the internal route in other when there are organizations on cloud", async () => { initiateService(); const products = await firstValueFrom(service.products$); + const organizations = products.other.find((p) => p.name === "Organizations"); + expect(organizations).toBeDefined(); + expect(organizations.marketingRoute.route).toBe("/create-organization"); + expect(organizations.marketingRoute.external).toBe(false); + + expect(products.other.find((p) => p.name === "Organizations")).toBeDefined(); + expect(products.bento.find((p) => p.name === "Admin Console")).toBeUndefined(); + }); + + it("includes Organizations with the external route in other when there are organizations on Self-Host", async () => { + platformUtilsService.isSelfHost.mockReturnValue(true); + initiateService(); + + const products = await firstValueFrom(service.products$); + + const organizations = products.other.find((p) => p.name === "Organizations"); + expect(organizations).toBeDefined(); + expect(organizations.marketingRoute.route).toBe("https://bitwarden.com/products/business/"); + expect(organizations.marketingRoute.external).toBe(true); + expect(products.other.find((p) => p.name === "Organizations")).toBeDefined(); expect(products.bento.find((p) => p.name === "Admin Console")).toBeUndefined(); }); diff --git a/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.ts b/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.ts index f962879d61a..1cc5c92c120 100644 --- a/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.ts +++ b/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.ts @@ -21,6 +21,7 @@ import { import { ProviderService } from "@bitwarden/common/admin-console/abstractions/provider.service"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { SyncService } from "@bitwarden/common/platform/sync"; export type ProductSwitcherItem = { @@ -101,6 +102,7 @@ export class ProductSwitcherService { private i18n: I18nPipe, private syncService: SyncService, private accountService: AccountService, + private platformUtilsService: PlatformUtilsService, ) { this.pollUntilSynced(); } @@ -151,6 +153,16 @@ export class ProductSwitcherService { // TODO: This should be migrated to an Observable provided by the provider service and moved to the combineLatest above. See AC-2092. const providers = await this.providerService.getAll(); + const orgsMarketingRoute = this.platformUtilsService.isSelfHost() + ? { + route: "https://bitwarden.com/products/business/", + external: true, + } + : { + route: "/create-organization", + external: false, + }; + const products = { pm: { name: "Password Manager", @@ -197,10 +209,7 @@ export class ProductSwitcherService { orgs: { name: "Organizations", icon: "bwi-business", - marketingRoute: { - route: "https://bitwarden.com/products/business/", - external: true, - }, + marketingRoute: orgsMarketingRoute, otherProductOverrides: { name: "Share your passwords", supportingText: this.i18n.transform("protectYourFamilyOrBusiness"), diff --git a/apps/web/src/app/layouts/user-layout.component.ts b/apps/web/src/app/layouts/user-layout.component.ts index f0ac3ef9b48..e859993af32 100644 --- a/apps/web/src/app/layouts/user-layout.component.ts +++ b/apps/web/src/app/layouts/user-layout.component.ts @@ -31,7 +31,6 @@ import { WebLayoutModule } from "./web-layout.module"; }) export class UserLayoutComponent implements OnInit { protected readonly logo = PasswordManagerLogo; - isFreeFamilyFlagEnabled: boolean; protected hasFamilySponsorshipAvailable$: Observable; protected showSponsoredFamilies$: Observable; protected showSubscription$: Observable; diff --git a/apps/web/src/app/oss-routing.module.ts b/apps/web/src/app/oss-routing.module.ts index c43f94b8acf..5f2b839ae97 100644 --- a/apps/web/src/app/oss-routing.module.ts +++ b/apps/web/src/app/oss-routing.module.ts @@ -12,7 +12,6 @@ import { activeAuthGuard, } from "@bitwarden/angular/auth/guards"; import { canAccessFeature } from "@bitwarden/angular/platform/guard/feature-flag.guard"; -import { generatorSwap } from "@bitwarden/angular/tools/generator/generator-swap"; import { twofactorRefactorSwap } from "@bitwarden/angular/utils/two-factor-component-refactor-route-swap"; import { NewDeviceVerificationNoticeGuard } from "@bitwarden/angular/vault/guards"; import { @@ -90,10 +89,8 @@ import { SMLandingComponent } from "./secrets-manager/secrets-manager-landing/sm import { DomainRulesComponent } from "./settings/domain-rules.component"; import { PreferencesComponent } from "./settings/preferences.component"; import { CredentialGeneratorComponent } from "./tools/credential-generator/credential-generator.component"; -import { GeneratorComponent } from "./tools/generator.component"; import { ReportsModule } from "./tools/reports"; -import { AccessComponent } from "./tools/send/access.component"; -import { SendAccessExplainerComponent } from "./tools/send/send-access-explainer.component"; +import { AccessComponent, SendAccessExplainerComponent } from "./tools/send/send-access"; import { SendComponent } from "./tools/send/send.component"; import { VaultModule } from "./vault/individual-vault/vault.module"; @@ -187,7 +184,7 @@ const routes: Routes = [ data: { pageIcon: DevicesIcon, pageTitle: { - key: "loginInitiated", + key: "logInRequestSent", }, pageSubtitle: { key: "aNotificationWasSentToYourDevice", @@ -831,10 +828,11 @@ const routes: Routes = [ titleId: "exportVault", } satisfies RouteDataProperties, }, - ...generatorSwap(GeneratorComponent, CredentialGeneratorComponent, { + { path: "generator", + component: CredentialGeneratorComponent, data: { titleId: "generator" } satisfies RouteDataProperties, - }), + }, ], }, { diff --git a/apps/web/src/app/oss.module.ts b/apps/web/src/app/oss.module.ts index 0810a138de2..39d0a9ae202 100644 --- a/apps/web/src/app/oss.module.ts +++ b/apps/web/src/app/oss.module.ts @@ -4,7 +4,7 @@ import { AuthModule } from "./auth"; import { LoginModule } from "./auth/login/login.module"; import { TrialInitiationModule } from "./billing/trial-initiation/trial-initiation.module"; import { LooseComponentsModule, SharedModule } from "./shared"; -import { AccessComponent } from "./tools/send/access.component"; +import { AccessComponent } from "./tools/send/send-access/access.component"; import { OrganizationBadgeModule } from "./vault/individual-vault/organization-badge/organization-badge.module"; import { VaultFilterModule } from "./vault/individual-vault/vault-filter/vault-filter.module"; diff --git a/apps/web/src/app/shared/loose-components.module.ts b/apps/web/src/app/shared/loose-components.module.ts index 3176ac81c1a..b565621b776 100644 --- a/apps/web/src/app/shared/loose-components.module.ts +++ b/apps/web/src/app/shared/loose-components.module.ts @@ -20,7 +20,6 @@ import { WeakPasswordsReportComponent as OrgWeakPasswordsReportComponent } from import { HintComponent } from "../auth/hint.component"; import { RecoverDeleteComponent } from "../auth/recover-delete.component"; import { RecoverTwoFactorComponent } from "../auth/recover-two-factor.component"; -import { RegisterFormModule } from "../auth/register-form/register-form.module"; import { RemovePasswordComponent } from "../auth/remove-password.component"; import { SetPasswordComponent } from "../auth/set-password.component"; import { AccountComponent } from "../auth/settings/account/account.component"; @@ -36,7 +35,6 @@ import { EmergencyAccessAddEditComponent } from "../auth/settings/emergency-acce import { EmergencyAccessComponent } from "../auth/settings/emergency-access/emergency-access.component"; import { EmergencyAccessTakeoverComponent } from "../auth/settings/emergency-access/takeover/emergency-access-takeover.component"; import { EmergencyAccessViewComponent } from "../auth/settings/emergency-access/view/emergency-access-view.component"; -import { EmergencyAddEditCipherComponent } from "../auth/settings/emergency-access/view/emergency-add-edit-cipher.component"; import { ApiKeyComponent } from "../auth/settings/security/api-key.component"; import { ChangeKdfModule } from "../auth/settings/security/change-kdf/change-kdf.module"; import { SecurityKeysComponent } from "../auth/settings/security/security-keys.component"; @@ -67,8 +65,6 @@ import { ProductSwitcherModule } from "../layouts/product-switcher/product-switc import { UserLayoutComponent } from "../layouts/user-layout.component"; import { DomainRulesComponent } from "../settings/domain-rules.component"; import { PreferencesComponent } from "../settings/preferences.component"; -import { GeneratorComponent } from "../tools/generator.component"; -import { PasswordGeneratorHistoryComponent } from "../tools/password-generator-history.component"; import { AddEditComponent as SendAddEditComponent } from "../tools/send/add-edit.component"; import { PremiumBadgeComponent } from "../vault/components/premium-badge.component"; import { AddEditCustomFieldsComponent } from "../vault/individual-vault/add-edit-custom-fields.component"; @@ -90,7 +86,6 @@ import { SharedModule } from "./shared.module"; @NgModule({ imports: [ SharedModule, - RegisterFormModule, ProductSwitcherModule, UserVerificationModule, ChangeKdfModule, @@ -128,7 +123,6 @@ import { SharedModule } from "./shared.module"; EmergencyAccessConfirmComponent, EmergencyAccessTakeoverComponent, EmergencyAccessViewComponent, - EmergencyAddEditCipherComponent, FolderAddEditComponent, FrontendLayoutComponent, HintComponent, @@ -141,8 +135,6 @@ import { SharedModule } from "./shared.module"; OrgUnsecuredWebsitesReportComponent, OrgUserConfirmComponent, OrgWeakPasswordsReportComponent, - GeneratorComponent, - PasswordGeneratorHistoryComponent, PreferencesComponent, PremiumBadgeComponent, ProfileComponent, @@ -194,7 +186,6 @@ import { SharedModule } from "./shared.module"; EmergencyAccessConfirmComponent, EmergencyAccessTakeoverComponent, EmergencyAccessViewComponent, - EmergencyAddEditCipherComponent, FolderAddEditComponent, FrontendLayoutComponent, HintComponent, @@ -208,8 +199,6 @@ import { SharedModule } from "./shared.module"; OrgUnsecuredWebsitesReportComponent, OrgUserConfirmComponent, OrgWeakPasswordsReportComponent, - GeneratorComponent, - PasswordGeneratorHistoryComponent, PreferencesComponent, PremiumBadgeComponent, ProfileComponent, diff --git a/apps/web/src/app/tools/generator.component.html b/apps/web/src/app/tools/generator.component.html deleted file mode 100644 index d73fe377011..00000000000 --- a/apps/web/src/app/tools/generator.component.html +++ /dev/null @@ -1,479 +0,0 @@ - - - - - {{ "passwordGeneratorPolicyInEffect" | i18n }} - -
-
- -
-
-
- -
- - -
-
- -
- -
- - -
-
- -
-
- - -
-
- - -
-
- -
-
- - -
-
- - -
-
-
- -
-
- - -
-
- - - - {{ passwordOptionsMinLengthForReader$ | async }} - -
-
- - -
-
- - -
-
- -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
-
-
-
- - -
-
- -
-
-
- -
-
- - - - -
-
- - -
-
- -
- - -
-
-
- - -
-
- - -
-
-
-
- - -
-
-
-
- - -
-
- - -
-
- - -
-
-
-
- - -
-
-
-
- - -
-
-
-
- - -
-
- - -
-
-
-
-
- - -
-
-
-
- - -
-
- - -
-
-
- - -
-
- - -
-
-
-
-
- - -
-
- -
diff --git a/apps/web/src/app/tools/generator.component.ts b/apps/web/src/app/tools/generator.component.ts deleted file mode 100644 index a11c0c4a97b..00000000000 --- a/apps/web/src/app/tools/generator.component.ts +++ /dev/null @@ -1,73 +0,0 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore -import { Component, NgZone } from "@angular/core"; -import { ActivatedRoute } from "@angular/router"; - -import { GeneratorComponent as BaseGeneratorComponent } from "@bitwarden/angular/tools/generator/components/generator.component"; -import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { DialogService, ToastService } from "@bitwarden/components"; -import { - PasswordGenerationServiceAbstraction, - UsernameGenerationServiceAbstraction, -} from "@bitwarden/generator-legacy"; - -import { PasswordGeneratorHistoryComponent } from "./password-generator-history.component"; - -@Component({ - selector: "app-generator", - templateUrl: "generator.component.html", -}) -export class GeneratorComponent extends BaseGeneratorComponent { - constructor( - passwordGenerationService: PasswordGenerationServiceAbstraction, - usernameGenerationService: UsernameGenerationServiceAbstraction, - accountService: AccountService, - platformUtilsService: PlatformUtilsService, - i18nService: I18nService, - logService: LogService, - route: ActivatedRoute, - ngZone: NgZone, - private dialogService: DialogService, - toastService: ToastService, - ) { - super( - passwordGenerationService, - usernameGenerationService, - platformUtilsService, - accountService, - i18nService, - logService, - route, - ngZone, - window, - toastService, - ); - if (platformUtilsService.isSelfHost()) { - // Allow only valid email forwarders for self host - this.forwardOptions = this.forwardOptions.filter((forwarder) => forwarder.validForSelfHosted); - } - } - - get isSelfHosted(): boolean { - return this.platformUtilsService.isSelfHost(); - } - - async history() { - this.dialogService.open(PasswordGeneratorHistoryComponent); - } - - lengthChanged() { - document.getElementById("length").focus(); - } - - minNumberChanged() { - document.getElementById("min-number").focus(); - } - - minSpecialChanged() { - document.getElementById("min-special").focus(); - } -} diff --git a/apps/web/src/app/tools/import/import-collection-admin.service.ts b/apps/web/src/app/tools/import/import-collection-admin.service.ts index 9f34966a2cd..64050eb9c06 100644 --- a/apps/web/src/app/tools/import/import-collection-admin.service.ts +++ b/apps/web/src/app/tools/import/import-collection-admin.service.ts @@ -1,7 +1,7 @@ import { Injectable } from "@angular/core"; import { CollectionAdminService, CollectionAdminView } from "@bitwarden/admin-console/common"; -import { ImportCollectionServiceAbstraction } from "@bitwarden/importer/core"; +import { ImportCollectionServiceAbstraction } from "@bitwarden/importer-core"; @Injectable() export class ImportCollectionAdminService implements ImportCollectionServiceAbstraction { diff --git a/apps/web/src/app/tools/import/import-web.component.ts b/apps/web/src/app/tools/import/import-web.component.ts index 3f1d5155039..a527b9e71f4 100644 --- a/apps/web/src/app/tools/import/import-web.component.ts +++ b/apps/web/src/app/tools/import/import-web.component.ts @@ -1,7 +1,7 @@ import { Component } from "@angular/core"; import { Router } from "@angular/router"; -import { ImportComponent } from "@bitwarden/importer/ui"; +import { ImportComponent } from "@bitwarden/importer-ui"; import { HeaderModule } from "../../layouts/header/header.module"; import { SharedModule } from "../../shared"; diff --git a/apps/web/src/app/tools/password-generator-history.component.html b/apps/web/src/app/tools/password-generator-history.component.html deleted file mode 100644 index eabb45ece2d..00000000000 --- a/apps/web/src/app/tools/password-generator-history.component.html +++ /dev/null @@ -1,47 +0,0 @@ - - - {{ "passwordHistory" | i18n }} - - - - - - - - - {{ h.date | date: "medium" }} - - - - - - - - -
- {{ "noPasswordsInList" | i18n }} -
-
- - - - -
diff --git a/apps/web/src/app/tools/password-generator-history.component.ts b/apps/web/src/app/tools/password-generator-history.component.ts deleted file mode 100644 index 0c7c9c4e221..00000000000 --- a/apps/web/src/app/tools/password-generator-history.component.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Component } from "@angular/core"; - -import { PasswordGeneratorHistoryComponent as BasePasswordGeneratorHistoryComponent } from "@bitwarden/angular/tools/generator/components/password-generator-history.component"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { ToastService } from "@bitwarden/components"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; - -@Component({ - selector: "app-password-generator-history", - templateUrl: "password-generator-history.component.html", -}) -export class PasswordGeneratorHistoryComponent extends BasePasswordGeneratorHistoryComponent { - constructor( - passwordGenerationService: PasswordGenerationServiceAbstraction, - platformUtilsService: PlatformUtilsService, - i18nService: I18nService, - toastService: ToastService, - ) { - super(passwordGenerationService, platformUtilsService, i18nService, window, toastService); - } -} diff --git a/apps/web/src/app/tools/reports/pages/cipher-report.component.ts b/apps/web/src/app/tools/reports/pages/cipher-report.component.ts index f78b2920410..792563c4fab 100644 --- a/apps/web/src/app/tools/reports/pages/cipher-report.component.ts +++ b/apps/web/src/app/tools/reports/pages/cipher-report.component.ts @@ -1,12 +1,13 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore import { Directive, ViewChild, ViewContainerRef, OnDestroy } from "@angular/core"; -import { BehaviorSubject, Observable, Subject, switchMap, takeUntil } from "rxjs"; +import { BehaviorSubject, Observable, Subject, firstValueFrom, switchMap, takeUntil } from "rxjs"; import { ModalService } from "@bitwarden/angular/services/modal.service"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { OrganizationId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; @@ -51,8 +52,10 @@ export class CipherReportComponent implements OnDestroy { private syncService: SyncService, ) { this.organizations$ = this.accountService.activeAccount$.pipe( - switchMap((account) => this.organizationService.organizations$(account?.id)), + getUserId, + switchMap((userId) => this.organizationService.organizations$(userId)), ); + this.organizations$.pipe(takeUntil(this.destroyed$)).subscribe((orgs) => { this.organizations = orgs; }); @@ -182,7 +185,8 @@ export class CipherReportComponent implements OnDestroy { } protected async getAllCiphers(): Promise { - return await this.cipherService.getAllDecrypted(); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + return await this.cipherService.getAllDecrypted(activeUserId); } protected filterCiphersByOrg(ciphersList: CipherView[]) { diff --git a/apps/web/src/app/tools/reports/pages/exposed-passwords-report.component.spec.ts b/apps/web/src/app/tools/reports/pages/exposed-passwords-report.component.spec.ts index 16541bdc109..47e4a9d3652 100644 --- a/apps/web/src/app/tools/reports/pages/exposed-passwords-report.component.spec.ts +++ b/apps/web/src/app/tools/reports/pages/exposed-passwords-report.component.spec.ts @@ -25,15 +25,14 @@ describe("ExposedPasswordsReportComponent", () => { let auditService: MockProxy; let organizationService: MockProxy; let syncServiceMock: MockProxy; - let accountService: FakeAccountService; const userId = Utils.newGuid() as UserId; + const accountService: FakeAccountService = mockAccountServiceWith(userId); beforeEach(() => { syncServiceMock = mock(); auditService = mock(); organizationService = mock(); organizationService.organizations$.mockReturnValue(of([])); - accountService = mockAccountServiceWith(userId); // 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 TestBed.configureTestingModule({ diff --git a/apps/web/src/app/tools/reports/pages/inactive-two-factor-report.component.spec.ts b/apps/web/src/app/tools/reports/pages/inactive-two-factor-report.component.spec.ts index 385bda03f28..033b88ea34f 100644 --- a/apps/web/src/app/tools/reports/pages/inactive-two-factor-report.component.spec.ts +++ b/apps/web/src/app/tools/reports/pages/inactive-two-factor-report.component.spec.ts @@ -24,14 +24,13 @@ describe("InactiveTwoFactorReportComponent", () => { let fixture: ComponentFixture; let organizationService: MockProxy; let syncServiceMock: MockProxy; - let accountService: FakeAccountService; const userId = Utils.newGuid() as UserId; + const accountService: FakeAccountService = mockAccountServiceWith(userId); beforeEach(() => { organizationService = mock(); organizationService.organizations$.mockReturnValue(of([])); syncServiceMock = mock(); - accountService = mockAccountServiceWith(userId); // 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 TestBed.configureTestingModule({ diff --git a/apps/web/src/app/tools/reports/pages/reused-passwords-report.component.spec.ts b/apps/web/src/app/tools/reports/pages/reused-passwords-report.component.spec.ts index 6a26cd24fe5..7c895423159 100644 --- a/apps/web/src/app/tools/reports/pages/reused-passwords-report.component.spec.ts +++ b/apps/web/src/app/tools/reports/pages/reused-passwords-report.component.spec.ts @@ -23,15 +23,13 @@ describe("ReusedPasswordsReportComponent", () => { let fixture: ComponentFixture; let organizationService: MockProxy; let syncServiceMock: MockProxy; - let accountService: FakeAccountService; const userId = Utils.newGuid() as UserId; + const accountService: FakeAccountService = mockAccountServiceWith(userId); beforeEach(() => { organizationService = mock(); organizationService.organizations$.mockReturnValue(of([])); syncServiceMock = mock(); - accountService = mockAccountServiceWith(userId); - // 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 TestBed.configureTestingModule({ diff --git a/apps/web/src/app/tools/reports/pages/unsecured-websites-report.component.spec.ts b/apps/web/src/app/tools/reports/pages/unsecured-websites-report.component.spec.ts index 7cd159108b8..337aa41b56b 100644 --- a/apps/web/src/app/tools/reports/pages/unsecured-websites-report.component.spec.ts +++ b/apps/web/src/app/tools/reports/pages/unsecured-websites-report.component.spec.ts @@ -25,15 +25,14 @@ describe("UnsecuredWebsitesReportComponent", () => { let organizationService: MockProxy; let syncServiceMock: MockProxy; let collectionService: MockProxy; - let accountService: FakeAccountService; const userId = Utils.newGuid() as UserId; + const accountService: FakeAccountService = mockAccountServiceWith(userId); beforeEach(() => { organizationService = mock(); organizationService.organizations$.mockReturnValue(of([])); syncServiceMock = mock(); collectionService = mock(); - accountService = mockAccountServiceWith(userId); // 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 TestBed.configureTestingModule({ diff --git a/apps/web/src/app/tools/reports/pages/weak-passwords-report.component.html b/apps/web/src/app/tools/reports/pages/weak-passwords-report.component.html index 76d4398cc0f..9c5b587e60a 100644 --- a/apps/web/src/app/tools/reports/pages/weak-passwords-report.component.html +++ b/apps/web/src/app/tools/reports/pages/weak-passwords-report.component.html @@ -39,13 +39,7 @@ {{ "owner" | i18n }} - + {{ "weakness" | i18n }} diff --git a/apps/web/src/app/tools/reports/pages/weak-passwords-report.component.spec.ts b/apps/web/src/app/tools/reports/pages/weak-passwords-report.component.spec.ts index 578c220f396..3d19511a252 100644 --- a/apps/web/src/app/tools/reports/pages/weak-passwords-report.component.spec.ts +++ b/apps/web/src/app/tools/reports/pages/weak-passwords-report.component.spec.ts @@ -25,15 +25,14 @@ describe("WeakPasswordsReportComponent", () => { let passwordStrengthService: MockProxy; let organizationService: MockProxy; let syncServiceMock: MockProxy; - let accountService: FakeAccountService; const userId = Utils.newGuid() as UserId; + const accountService: FakeAccountService = mockAccountServiceWith(userId); beforeEach(() => { syncServiceMock = mock(); passwordStrengthService = mock(); organizationService = mock(); organizationService.organizations$.mockReturnValue(of([])); - accountService = mockAccountServiceWith(userId); // 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 TestBed.configureTestingModule({ diff --git a/apps/web/src/app/tools/reports/pages/weak-passwords-report.component.ts b/apps/web/src/app/tools/reports/pages/weak-passwords-report.component.ts index 8b781b77378..c374ecd0e4a 100644 --- a/apps/web/src/app/tools/reports/pages/weak-passwords-report.component.ts +++ b/apps/web/src/app/tools/reports/pages/weak-passwords-report.component.ts @@ -59,7 +59,6 @@ export class WeakPasswordsReportComponent extends CipherReportComponent implemen this.weakPasswordCiphers = []; this.filterStatus = [0]; this.findWeakPasswords(allCiphers); - this.weakPasswordCiphers = this.sortCiphers(this.weakPasswordCiphers, "score", false); } protected findWeakPasswords(ciphers: CipherView[]): void { @@ -113,29 +112,6 @@ export class WeakPasswordsReportComponent extends CipherReportComponent implemen this.filterCiphersByOrg(this.weakPasswordCiphers); } - onSortChange(field: string, event: Event) { - const target = event.target as HTMLInputElement; - const ascending = target.checked; - this.weakPasswordCiphers = this.sortCiphers(this.weakPasswordCiphers, field, ascending); - } - - protected sortCiphers( - ciphers: ReportResult[], - field: string, - ascending: boolean, - ): ReportResult[] { - return ciphers.sort((a, b) => { - const aValue = a[field as keyof ReportResult]; - const bValue = b[field as keyof ReportResult]; - - if (aValue === bValue) { - return 0; - } - const comparison = aValue > bValue ? 1 : -1; - return ascending ? comparison : -comparison; - }); - } - protected canManageCipher(c: CipherView): boolean { // this will only ever be false from the org view; return true; diff --git a/apps/web/src/app/tools/send/access.component.html b/apps/web/src/app/tools/send/send-access/access.component.html similarity index 100% rename from apps/web/src/app/tools/send/access.component.html rename to apps/web/src/app/tools/send/send-access/access.component.html diff --git a/apps/web/src/app/tools/send/access.component.ts b/apps/web/src/app/tools/send/send-access/access.component.ts similarity index 99% rename from apps/web/src/app/tools/send/access.component.ts rename to apps/web/src/app/tools/send/send-access/access.component.ts index b76c3853d52..da8c845dfe9 100644 --- a/apps/web/src/app/tools/send/access.component.ts +++ b/apps/web/src/app/tools/send/send-access/access.component.ts @@ -19,7 +19,7 @@ import { NoItemsModule, ToastService } from "@bitwarden/components"; import { KeyService } from "@bitwarden/key-management"; import { ExpiredSendIcon } from "@bitwarden/send-ui"; -import { SharedModule } from "../../shared"; +import { SharedModule } from "../../../shared"; import { SendAccessFileComponent } from "./send-access-file.component"; import { SendAccessPasswordComponent } from "./send-access-password.component"; diff --git a/apps/web/src/app/tools/send/send-access/index.ts b/apps/web/src/app/tools/send/send-access/index.ts new file mode 100644 index 00000000000..c9df5ce5193 --- /dev/null +++ b/apps/web/src/app/tools/send/send-access/index.ts @@ -0,0 +1,2 @@ +export { AccessComponent } from "./access.component"; +export { SendAccessExplainerComponent } from "./send-access-explainer.component"; diff --git a/apps/web/src/app/tools/send/send-access-explainer.component.html b/apps/web/src/app/tools/send/send-access/send-access-explainer.component.html similarity index 100% rename from apps/web/src/app/tools/send/send-access-explainer.component.html rename to apps/web/src/app/tools/send/send-access/send-access-explainer.component.html diff --git a/apps/web/src/app/tools/send/send-access-explainer.component.ts b/apps/web/src/app/tools/send/send-access/send-access-explainer.component.ts similarity index 84% rename from apps/web/src/app/tools/send/send-access-explainer.component.ts rename to apps/web/src/app/tools/send/send-access/send-access-explainer.component.ts index e7106110a65..ec39d970444 100644 --- a/apps/web/src/app/tools/send/send-access-explainer.component.ts +++ b/apps/web/src/app/tools/send/send-access/send-access-explainer.component.ts @@ -1,6 +1,6 @@ import { Component } from "@angular/core"; -import { SharedModule } from "../../shared"; +import { SharedModule } from "../../../shared"; @Component({ selector: "app-send-access-explainer", diff --git a/apps/web/src/app/tools/send/send-access-file.component.html b/apps/web/src/app/tools/send/send-access/send-access-file.component.html similarity index 100% rename from apps/web/src/app/tools/send/send-access-file.component.html rename to apps/web/src/app/tools/send/send-access/send-access-file.component.html diff --git a/apps/web/src/app/tools/send/send-access-file.component.ts b/apps/web/src/app/tools/send/send-access/send-access-file.component.ts similarity index 94% rename from apps/web/src/app/tools/send/send-access-file.component.ts rename to apps/web/src/app/tools/send/send-access/send-access-file.component.ts index b55e955f355..eec0bfd787b 100644 --- a/apps/web/src/app/tools/send/send-access-file.component.ts +++ b/apps/web/src/app/tools/send/send-access/send-access-file.component.ts @@ -2,7 +2,7 @@ // @ts-strict-ignore import { Component, Input } from "@angular/core"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; @@ -13,7 +13,7 @@ import { SendAccessView } from "@bitwarden/common/tools/send/models/view/send-ac import { SendApiService } from "@bitwarden/common/tools/send/services/send-api.service.abstraction"; import { ToastService } from "@bitwarden/components"; -import { SharedModule } from "../../shared"; +import { SharedModule } from "../../../shared"; @Component({ selector: "app-send-access-file", diff --git a/apps/web/src/app/tools/send/send-access-password.component.html b/apps/web/src/app/tools/send/send-access/send-access-password.component.html similarity index 100% rename from apps/web/src/app/tools/send/send-access-password.component.html rename to apps/web/src/app/tools/send/send-access/send-access-password.component.html diff --git a/apps/web/src/app/tools/send/send-access-password.component.ts b/apps/web/src/app/tools/send/send-access/send-access-password.component.ts similarity index 95% rename from apps/web/src/app/tools/send/send-access-password.component.ts rename to apps/web/src/app/tools/send/send-access/send-access-password.component.ts index bd98e9d18c8..0cfd93fcea0 100644 --- a/apps/web/src/app/tools/send/send-access-password.component.ts +++ b/apps/web/src/app/tools/send/send-access/send-access-password.component.ts @@ -4,7 +4,7 @@ import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from "@angu import { FormBuilder, Validators } from "@angular/forms"; import { Subject, takeUntil } from "rxjs"; -import { SharedModule } from "../../shared"; +import { SharedModule } from "../../../shared"; @Component({ selector: "app-send-access-password", diff --git a/apps/web/src/app/tools/send/send-access-text.component.html b/apps/web/src/app/tools/send/send-access/send-access-text.component.html similarity index 100% rename from apps/web/src/app/tools/send/send-access-text.component.html rename to apps/web/src/app/tools/send/send-access/send-access-text.component.html diff --git a/apps/web/src/app/tools/send/send-access-text.component.ts b/apps/web/src/app/tools/send/send-access/send-access-text.component.ts similarity index 97% rename from apps/web/src/app/tools/send/send-access-text.component.ts rename to apps/web/src/app/tools/send/send-access/send-access-text.component.ts index 6568fe482ad..6f9bc798d4b 100644 --- a/apps/web/src/app/tools/send/send-access-text.component.ts +++ b/apps/web/src/app/tools/send/send-access/send-access-text.component.ts @@ -8,7 +8,7 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl import { SendAccessView } from "@bitwarden/common/tools/send/models/view/send-access.view"; import { ToastService } from "@bitwarden/components"; -import { SharedModule } from "../../shared"; +import { SharedModule } from "../../../shared"; @Component({ selector: "app-send-access-text", diff --git a/apps/web/src/app/vault/components/collection-dialog/collection-dialog.component.html b/apps/web/src/app/vault/components/collection-dialog/collection-dialog.component.html index fbe0649c7aa..61fc290f6fe 100644 --- a/apps/web/src/app/vault/components/collection-dialog/collection-dialog.component.html +++ b/apps/web/src/app/vault/components/collection-dialog/collection-dialog.component.html @@ -70,11 +70,11 @@ - {{ "grantAddAccessCollectionWarning" | i18n }} + {{ "grantManageCollectionWarning" | i18n }} {{ "grantCollectionAccess" | i18n }} {{ diff --git a/apps/web/src/app/vault/components/vault-item-dialog/vault-item-dialog.component.ts b/apps/web/src/app/vault/components/vault-item-dialog/vault-item-dialog.component.ts index 0af0d720b0e..3dc3b8f9f84 100644 --- a/apps/web/src/app/vault/components/vault-item-dialog/vault-item-dialog.component.ts +++ b/apps/web/src/app/vault/components/vault-item-dialog/vault-item-dialog.component.ts @@ -12,6 +12,7 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions"; import { EventType } from "@bitwarden/common/enums"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; @@ -355,8 +356,8 @@ export class VaultItemDialogComponent implements OnInit, OnDestroy { this.formConfig.mode = "edit"; this.formConfig.initialValues = null; } - - let cipher = await this.cipherService.get(cipherView.id); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + let cipher = await this.cipherService.get(cipherView.id, activeUserId); // When the form config is used within the Admin Console, retrieve the cipher from the admin endpoint (if not found in local state) if (this.formConfig.isAdminConsole && (cipher == null || this.formConfig.admin)) { @@ -366,6 +367,9 @@ export class VaultItemDialogComponent implements OnInit, OnDestroy { const cipherData = new CipherData(cipherResponse); cipher = new Cipher(cipherData); + + // Update organizationUseTotp from server response + this.cipher.organizationUseTotp = cipher.organizationUseTotp; } // Store the updated cipher so any following edits use the most up to date cipher @@ -445,10 +449,13 @@ export class VaultItemDialogComponent implements OnInit, OnDestroy { result.action === AttachmentDialogResult.Removed || result.action === AttachmentDialogResult.Uploaded ) { - const updatedCipher = await this.cipherService.get(this.formConfig.originalCipher?.id); const activeUserId = await firstValueFrom( this.accountService.activeAccount$.pipe(map((a) => a?.id)), ); + const updatedCipher = await this.cipherService.get( + this.formConfig.originalCipher?.id, + activeUserId, + ); const updatedCipherView = await updatedCipher.decrypt( await this.cipherService.getKeyForCipherKeyDecryption(updatedCipher, activeUserId), @@ -487,9 +494,7 @@ export class VaultItemDialogComponent implements OnInit, OnDestroy { if (config.originalCipher == null) { return; } - const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), - ); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); return await config.originalCipher.decrypt( await this.cipherService.getKeyForCipherKeyDecryption(config.originalCipher, activeUserId), ); @@ -571,10 +576,14 @@ export class VaultItemDialogComponent implements OnInit, OnDestroy { // - The cipher is unassigned const asAdmin = this.organization?.canEditAllCiphers || cipherIsUnassigned; + const activeUserId = await firstValueFrom( + this.accountService.activeAccount$.pipe(map((a) => a?.id)), + ); + if (this.cipher.isDeleted) { - await this.cipherService.deleteWithServer(this.cipher.id, asAdmin); + await this.cipherService.deleteWithServer(this.cipher.id, activeUserId, asAdmin); } else { - await this.cipherService.softDeleteWithServer(this.cipher.id, asAdmin); + await this.cipherService.softDeleteWithServer(this.cipher.id, activeUserId, asAdmin); } } diff --git a/apps/web/src/app/vault/components/vault-items/vault-cipher-row.component.html b/apps/web/src/app/vault/components/vault-items/vault-cipher-row.component.html index 7e59853851c..befeee43f69 100644 --- a/apps/web/src/app/vault/components/vault-items/vault-cipher-row.component.html +++ b/apps/web/src/app/vault/components/vault-items/vault-cipher-row.component.html @@ -22,7 +22,7 @@ [routerLink]="[]" [queryParams]="{ itemId: cipher.id, action: clickAction }" queryParamsHandling="merge" - [replaceUrl]="extensionRefreshEnabled" + [replaceUrl]="true" title="{{ 'editItemWithName' | i18n: cipher.name }}" type="button" appStopProp diff --git a/apps/web/src/app/vault/components/vault-items/vault-cipher-row.component.ts b/apps/web/src/app/vault/components/vault-items/vault-cipher-row.component.ts index 556d3d54594..5f686fcec9c 100644 --- a/apps/web/src/app/vault/components/vault-items/vault-cipher-row.component.ts +++ b/apps/web/src/app/vault/components/vault-items/vault-cipher-row.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, EventEmitter, Input, OnInit, Output } from "@angular/core"; -import { firstValueFrom } from "rxjs"; import { CollectionView } from "@bitwarden/admin-console/common"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; -import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; -import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { CipherType } from "@bitwarden/common/vault/enums"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; @@ -25,11 +22,6 @@ import { RowHeightClass } from "./vault-items.component"; export class VaultCipherRowComponent implements OnInit { protected RowHeightClass = RowHeightClass; - /** - * Flag to determine if the extension refresh feature flag is enabled. - */ - protected extensionRefreshEnabled = false; - @Input() disabled: boolean; @Input() cipher: CipherView; @Input() showOwner: boolean; @@ -42,6 +34,7 @@ export class VaultCipherRowComponent implements OnInit { @Input() collections: CollectionView[]; @Input() viewingOrgVault: boolean; @Input() canEditCipher: boolean; + @Input() canAssignCollections: boolean; @Input() canManageCollection: boolean; @Output() onEvent = new EventEmitter(); @@ -52,27 +45,20 @@ export class VaultCipherRowComponent implements OnInit { protected CipherType = CipherType; private permissionList = getPermissionList(); private permissionPriority = [ - "canManage", - "canEdit", - "canEditExceptPass", - "canView", - "canViewExceptPass", + "manageCollection", + "editItems", + "editItemsHidePass", + "viewItems", + "viewItemsHidePass", ]; protected organization?: Organization; - constructor( - private configService: ConfigService, - private i18nService: I18nService, - ) {} + constructor(private i18nService: I18nService) {} /** * Lifecycle hook for component initialization. - * Checks if the extension refresh feature flag is enabled to provide to template. */ async ngOnInit(): Promise { - this.extensionRefreshEnabled = await firstValueFrom( - this.configService.getFeatureFlag$(FeatureFlag.ExtensionRefresh), - ); if (this.cipher.organizationId != null) { this.organization = this.organizations.find((o) => o.id === this.cipher.organizationId); } @@ -82,7 +68,7 @@ export class VaultCipherRowComponent implements OnInit { if (this.cipher.decryptionFailure) { return "showFailedToDecrypt"; } - return this.extensionRefreshEnabled ? "view" : null; + return "view"; } protected get showTotpCopyButton() { @@ -101,7 +87,7 @@ export class VaultCipherRowComponent implements OnInit { } protected get showAssignToCollections() { - return this.organizations?.length && this.canEditCipher && !this.cipher.isDeleted; + return this.organizations?.length && this.canAssignCollections && !this.cipher.isDeleted; } protected get showClone() { @@ -118,7 +104,7 @@ export class VaultCipherRowComponent implements OnInit { protected get permissionText() { if (!this.cipher.organizationId || this.cipher.collectionIds.length === 0) { - return this.i18nService.t("canManage"); + return this.i18nService.t("manageCollection"); } const filteredCollections = this.collections.filter((collection) => { @@ -208,6 +194,6 @@ export class VaultCipherRowComponent implements OnInit { return true; // Always show checkbox in individual vault or for non-org items } - return this.organization.canEditAllCiphers || this.cipher.edit; + return this.organization.canEditAllCiphers || (this.cipher.edit && this.cipher.viewPassword); } } diff --git a/apps/web/src/app/vault/components/vault-items/vault-collection-row.component.html b/apps/web/src/app/vault/components/vault-items/vault-collection-row.component.html index 2f9e84fc6d5..c7d16908241 100644 --- a/apps/web/src/app/vault/components/vault-items/vault-collection-row.component.html +++ b/apps/web/src/app/vault/components/vault-items/vault-collection-row.component.html @@ -11,7 +11,7 @@ /> -
diff --git a/apps/web/src/app/vault/org-vault/vault-header/vault-header.component.ts b/apps/web/src/app/vault/org-vault/vault-header/vault-header.component.ts index 7f118a48db3..e3c99231a86 100644 --- a/apps/web/src/app/vault/org-vault/vault-header/vault-header.component.ts +++ b/apps/web/src/app/vault/org-vault/vault-header/vault-header.component.ts @@ -13,7 +13,6 @@ import { import { JslibModule } from "@bitwarden/angular/jslib.module"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { ProductTierType } from "@bitwarden/common/billing/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 { CipherType } from "@bitwarden/common/vault/enums"; @@ -90,11 +89,6 @@ export class VaultHeaderComponent implements OnInit { protected CollectionDialogTabType = CollectionDialogTabType; - /** - * Whether the extension refresh feature flag is enabled. - */ - protected extensionRefreshEnabled = false; - /** The cipher type enum. */ protected CipherType = CipherType; @@ -106,11 +100,7 @@ export class VaultHeaderComponent implements OnInit { private configService: ConfigService, ) {} - async ngOnInit() { - this.extensionRefreshEnabled = await this.configService.getFeatureFlag( - FeatureFlag.ExtensionRefresh, - ); - } + async ngOnInit() {} get title() { const headerType = this.i18nService.t("collections").toLowerCase(); diff --git a/apps/web/src/app/vault/org-vault/vault.component.ts b/apps/web/src/app/vault/org-vault/vault.component.ts index fe76f9842e9..f14a8fcf5ee 100644 --- a/apps/web/src/app/vault/org-vault/vault.component.ts +++ b/apps/web/src/app/vault/org-vault/vault.component.ts @@ -1,15 +1,7 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore import { DialogRef } from "@angular/cdk/dialog"; -import { - ChangeDetectorRef, - Component, - NgZone, - OnDestroy, - OnInit, - ViewChild, - ViewContainerRef, -} from "@angular/core"; +import { ChangeDetectorRef, Component, NgZone, OnDestroy, OnInit } from "@angular/core"; import { ActivatedRoute, Params, Router } from "@angular/router"; import { BehaviorSubject, @@ -37,12 +29,10 @@ import { import { CollectionAdminService, CollectionAdminView, - CollectionService, CollectionView, Unassigned, } from "@bitwarden/admin-console/common"; import { SearchPipe } from "@bitwarden/angular/pipes/search.pipe"; -import { ModalService } from "@bitwarden/angular/services/modal.service"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service"; import { SearchService } from "@bitwarden/common/abstractions/search.service"; @@ -50,6 +40,7 @@ import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-conso import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { OrganizationBillingServiceAbstraction } from "@bitwarden/common/billing/abstractions"; import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions/billing-api.service.abstraction"; import { EventType } from "@bitwarden/common/enums"; @@ -62,7 +53,7 @@ import { MessagingService } from "@bitwarden/common/platform/abstractions/messag import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { SyncService } from "@bitwarden/common/platform/sync"; -import { CipherId, CollectionId, OrganizationId } from "@bitwarden/common/types/guid"; +import { CipherId, CollectionId, OrganizationId, UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { TotpService } from "@bitwarden/common/vault/abstractions/totp.service"; import { CipherType } from "@bitwarden/common/vault/enums"; @@ -127,7 +118,6 @@ import { import { VaultHeaderComponent } from "../org-vault/vault-header/vault-header.component"; import { getNestedCollectionTree } from "../utils/collection-utils"; -import { AddEditComponent } from "./add-edit.component"; import { BulkCollectionsDialogComponent, BulkCollectionsDialogResult, @@ -166,13 +156,6 @@ enum AddAccessStatusType { export class VaultComponent implements OnInit, OnDestroy { protected Unassigned = Unassigned; - @ViewChild("attachments", { read: ViewContainerRef, static: true }) - attachmentsModalRef: ViewContainerRef; - @ViewChild("cipherAddEdit", { read: ViewContainerRef, static: true }) - cipherAddEditModalRef: ViewContainerRef; - @ViewChild("collectionsModal", { read: ViewContainerRef, static: true }) - collectionsModalRef: ViewContainerRef; - trashCleanupWarning: string = null; activeFilter: VaultFilter = new VaultFilter(); @@ -210,7 +193,6 @@ export class VaultComponent implements OnInit, OnDestroy { private refresh$ = new BehaviorSubject(null); private destroy$ = new Subject(); protected addAccessStatus$ = new BehaviorSubject(0); - private extensionRefreshEnabled: boolean; private resellerManagedOrgAlert: boolean; private vaultItemDialogRef?: DialogRef | undefined; @@ -249,7 +231,6 @@ export class VaultComponent implements OnInit, OnDestroy { private changeDetectorRef: ChangeDetectorRef, private syncService: SyncService, private i18nService: I18nService, - private modalService: ModalService, private dialogService: DialogService, private messagingService: MessagingService, private broadcasterService: BroadcasterService, @@ -265,7 +246,6 @@ export class VaultComponent implements OnInit, OnDestroy { private eventCollectionService: EventCollectionService, private totpService: TotpService, private apiService: ApiService, - private collectionService: CollectionService, private toastService: ToastService, private configService: ConfigService, private cipherFormConfigService: CipherFormConfigService, @@ -278,10 +258,6 @@ export class VaultComponent implements OnInit, OnDestroy { ) {} async ngOnInit() { - this.extensionRefreshEnabled = await this.configService.getFeatureFlag( - FeatureFlag.ExtensionRefresh, - ); - this.resellerManagedOrgAlert = await this.configService.getFeatureFlag( FeatureFlag.ResellerManagedOrgAlert, ); @@ -555,7 +531,7 @@ export class VaultComponent implements OnInit, OnDestroy { firstSetup$ .pipe( switchMap(() => combineLatest([this.route.queryParams, allCipherMap$])), - filter(() => this.vaultItemDialogRef == undefined || !this.extensionRefreshEnabled), + filter(() => this.vaultItemDialogRef == undefined), switchMap(async ([qParams, allCiphersMap]) => { const cipherId = getCipherIdFromParams(qParams); @@ -586,15 +562,15 @@ export class VaultComponent implements OnInit, OnDestroy { return; } - // Default to "view" if extension refresh is enabled - if (action == null && this.extensionRefreshEnabled) { + // Default to "view" + if (action == null) { action = "view"; } if (action === "view") { await this.viewCipherById(cipher); } else { - await this.editCipherId(cipher, false); + await this.editCipher(cipher, false); } } else { this.toastService.showToast({ @@ -836,27 +812,8 @@ export class VaultComponent implements OnInit, OnDestroy { } } + /** Opens the Add/Edit Dialog */ async addCipher(cipherType?: CipherType) { - if (this.extensionRefreshEnabled) { - return this.addCipherV2(cipherType); - } - - let collections: CollectionView[] = []; - - // Admins limited to only adding items to collections they have access to. - collections = await firstValueFrom(this.editableCollections$); - - await this.editCipher(null, false, (comp) => { - comp.type = cipherType || this.activeFilter.cipherType; - comp.collections = collections; - if (this.activeFilter.collectionId) { - comp.collectionIds = [this.activeFilter.collectionId]; - } - }); - } - - /** Opens the Add/Edit Dialog. Only to be used when the BrowserExtension feature flag is active */ - async addCipherV2(cipherType?: CipherType) { const cipherFormConfig = await this.cipherFormConfigService.buildConfig( "add", null, @@ -877,24 +834,8 @@ export class VaultComponent implements OnInit, OnDestroy { * Edit the given cipher or add a new cipher * @param cipherView - When set, the cipher to be edited * @param cloneCipher - `true` when the cipher should be cloned. - * Used in place of the `additionalComponentParameters`, as - * the `editCipherIdV2` method has a differing implementation. - * @param defaultComponentParameters - A method that takes in an instance of - * the `AddEditComponent` to edit methods directly. */ - async editCipher( - cipher: CipherView | null, - cloneCipher: boolean, - additionalComponentParameters?: (comp: AddEditComponent) => void, - ) { - return this.editCipherId(cipher, cloneCipher, additionalComponentParameters); - } - - async editCipherId( - cipher: CipherView | null, - cloneCipher: boolean, - additionalComponentParameters?: (comp: AddEditComponent) => void, - ) { + async editCipher(cipher: CipherView | null, cloneCipher: boolean) { if ( cipher && cipher.reprompt !== 0 && @@ -905,55 +846,6 @@ export class VaultComponent implements OnInit, OnDestroy { return; } - if (this.extensionRefreshEnabled) { - await this.editCipherIdV2(cipher, cloneCipher); - return; - } - - const defaultComponentParameters = (comp: AddEditComponent) => { - comp.organization = this.organization; - comp.organizationId = this.organization.id; - comp.cipherId = cipher?.id; - comp.collectionId = this.activeFilter.collectionId; - comp.onSavedCipher.pipe(takeUntil(this.destroy$)).subscribe(() => { - modal.close(); - this.refresh(); - }); - comp.onDeletedCipher.pipe(takeUntil(this.destroy$)).subscribe(() => { - modal.close(); - this.refresh(); - }); - comp.onRestoredCipher.pipe(takeUntil(this.destroy$)).subscribe(() => { - modal.close(); - this.refresh(); - }); - }; - - const [modal, childComponent] = await this.modalService.openViewRef( - AddEditComponent, - this.cipherAddEditModalRef, - additionalComponentParameters == null - ? defaultComponentParameters - : (comp) => { - defaultComponentParameters(comp); - additionalComponentParameters(comp); - }, - ); - - // 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 - modal.onClosedPromise().then(() => { - this.go({ cipherId: null, itemId: null, action: null }); - }); - - return childComponent; - } - - /** - * Edit a cipher using the new AddEditCipherDialogV2 component. - * Only to be used behind the ExtensionRefresh feature flag. - */ - private async editCipherIdV2(cipher: CipherView | null, cloneCipher: boolean) { const cipherFormConfig = await this.cipherFormConfigService.buildConfig( cloneCipher ? "clone" : "edit", cipher?.id as CipherId | null, @@ -1038,16 +930,7 @@ export class VaultComponent implements OnInit, OnDestroy { } } - let collections: CollectionView[] = []; - - // Admins limited to only adding items to collections they have access to. - collections = await firstValueFrom(this.editableCollections$); - - await this.editCipher(cipher, true, (comp) => { - comp.cloneMode = true; - comp.collections = collections; - comp.collectionIds = cipher.collectionIds; - }); + await this.editCipher(cipher, true); } restore = async (c: CipherView): Promise => { @@ -1070,8 +953,9 @@ export class VaultComponent implements OnInit, OnDestroy { // Allow restore of an Unassigned Item try { + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); const asAdmin = this.organization?.canEditAnyCollection || c.isUnassigned; - await this.cipherService.restoreWithServer(c.id, asAdmin); + await this.cipherService.restoreWithServer(c.id, activeUserId, asAdmin); this.toastService.showToast({ variant: "success", title: null, @@ -1162,7 +1046,8 @@ export class VaultComponent implements OnInit, OnDestroy { } try { - await this.deleteCipherWithServer(c.id, permanent, c.isUnassigned); + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + await this.deleteCipherWithServer(c.id, activeUserId, permanent, c.isUnassigned); this.toastService.showToast({ variant: "success", title: null, @@ -1450,11 +1335,16 @@ export class VaultComponent implements OnInit, OnDestroy { }); } - protected deleteCipherWithServer(id: string, permanent: boolean, isUnassigned: boolean) { + protected deleteCipherWithServer( + id: string, + userId: UserId, + permanent: boolean, + isUnassigned: boolean, + ) { const asAdmin = this.organization?.canEditAllCiphers || isUnassigned; return permanent - ? this.cipherService.deleteWithServer(id, asAdmin) - : this.cipherService.softDeleteWithServer(id, asAdmin); + ? this.cipherService.deleteWithServer(id, userId, asAdmin) + : this.cipherService.softDeleteWithServer(id, userId, asAdmin); } protected async repromptCipher(ciphers: CipherView[]) { diff --git a/apps/web/src/app/vault/services/web-view-password-history.service.ts b/apps/web/src/app/vault/services/web-view-password-history.service.ts index 728a3b7e245..b1451b268de 100644 --- a/apps/web/src/app/vault/services/web-view-password-history.service.ts +++ b/apps/web/src/app/vault/services/web-view-password-history.service.ts @@ -1,11 +1,9 @@ import { Injectable } from "@angular/core"; +import { ViewPasswordHistoryService } from "@bitwarden/common/vault/abstractions/view-password-history.service"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { DialogService } from "@bitwarden/components"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { ViewPasswordHistoryService } from "../../../../../../libs/common/src/vault/abstractions/view-password-history.service"; import { openPasswordHistoryDialog } from "../individual-vault/password-history.component"; /** diff --git a/apps/web/src/locales/af/messages.json b/apps/web/src/locales/af/messages.json index 41f173c5854..6addd540801 100644 --- a/apps/web/src/locales/af/messages.json +++ b/apps/web/src/locales/af/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Wysig vouer" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Basisdomein", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "bv.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Log in initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Dien in" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "’n Kennisgewing is na u toestel gestuur." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "Weergawe $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Hergenereer wagwoord" - }, "length": { "message": "Lengte" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Gevaarsone" }, - "dangerZoneDesc": { - "message": "Versigtig, hierdie aksies is onomkeerbaar!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Deauthorize sessions" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Proceeding will also log you out of your current session, requiring you to log back in. You will also be prompted for two-step login again, if set up. Active sessions on other devices may continue to remain active for up to one hour." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "All sessions deauthorized" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Bestuur" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Deaktiveer" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "There was a problem reading the security key. Try again." }, - "twoFactorWebAuthnWarning": { - "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used. Supported platforms:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Web vault and browser extensions on a desktop/laptop with a WebAuthn supported browser (Chrome, Opera, Vivaldi, or Firefox with FIDO U2F turned on)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "U herstelkode vir Bitwarden-tweestapaantekening" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Stel minimum vereistes vir opstelling van wagwoordgenereerder." }, - "passwordGeneratorPolicyInEffect": { - "message": "Een of meer organisasiebeleide beïnvloed u genereerderinstellings." - }, "masterPasswordPolicyInEffect": { "message": "Een of meer organisasiebeleide stel die volgende eise aan u hoofwagwoord:" }, @@ -6666,15 +6717,6 @@ "message": "Genereerder", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "Wat wil u genereer?" - }, - "passwordType": { - "message": "Wagwoordtipe" - }, - "regenerateUsername": { - "message": "Hergenereer gebruikersnaam" - }, "generateUsername": { "message": "Genereer gebruikersnaam" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Gebruikersnaamtipe" - }, "plusAddressedEmail": { "message": "E-posadres met plus", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Gebruik u domein se opgestelde allesomvattende inmandjie." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Lukraak", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Gasheernaam", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API-toegangsteken" - }, "deviceVerification": { "message": "Toestelbevestiging" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "Geen versameling" }, - "canView": { - "message": "Kan bekyk" - }, - "canViewExceptPass": { - "message": "Kan bekyk, behalwe wagwoorde" - }, - "canEdit": { - "message": "Kan wysig" - }, - "canEditExceptPass": { - "message": "Kan wysig behalwe wagwoorde" - }, "noCollectionsAdded": { "message": "Geen versamelings toegevoeg" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domain" - }, "alreadyHaveAccount": { "message": "Already have an account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/ar/messages.json b/apps/web/src/locales/ar/messages.json index e2c95934b58..7cd5b2eef01 100644 --- a/apps/web/src/locales/ar/messages.json +++ b/apps/web/src/locales/ar/messages.json @@ -1,6 +1,6 @@ { "allApplications": { - "message": "All applications" + "message": "كل التطبيقات" }, "criticalApplications": { "message": "Critical applications" @@ -96,19 +96,19 @@ "message": "Apps marked as critical" }, "application": { - "message": "Application" + "message": "تطبيق" }, "atRiskPasswords": { "message": "At-risk passwords" }, "requestPasswordChange": { - "message": "Request password change" + "message": "طلب تغيير كلمة المرور" }, "totalPasswords": { "message": "Total passwords" }, "searchApps": { - "message": "Search applications" + "message": "البحث في التطبيقات" }, "atRiskMembers": { "message": "At-risk members" @@ -147,7 +147,7 @@ } }, "totalMembers": { - "message": "Total members" + "message": "إجمالي الأعضاء" }, "atRiskApplications": { "message": "At-risk applications" @@ -199,7 +199,7 @@ "message": "ملاحظات" }, "note": { - "message": "Note" + "message": "ملاحظة" }, "customFields": { "message": "حقول مخصصة" @@ -208,19 +208,19 @@ "message": "اسم حامل البطاقة" }, "loginCredentials": { - "message": "Login credentials" + "message": "معلومات الدخول" }, "personalDetails": { - "message": "Personal details" + "message": "البيانات الشخصية" }, "identification": { - "message": "Identification" + "message": "التعريف" }, "contactInfo": { - "message": "Contact info" + "message": "معلومات الاتصال" }, "cardDetails": { - "message": "Card details" + "message": "بيانات البطاقة" }, "cardBrandDetails": { "message": "$BRAND$ details", @@ -232,13 +232,13 @@ } }, "itemHistory": { - "message": "Item history" + "message": "تاريخ العنصر" }, "authenticatorKey": { - "message": "Authenticator key" + "message": "مفتاح المصادقة" }, "autofillOptions": { - "message": "Autofill options" + "message": "خيارات الملء التلقائي" }, "websiteUri": { "message": "Website (URI)" @@ -432,17 +432,17 @@ "message": "قيمة منطقية" }, "cfTypeCheckbox": { - "message": "Checkbox" + "message": "مربع اختيار" }, "cfTypeLinked": { "message": "مرتبط", "description": "This describes a field that is 'linked' (related) to another field." }, "fieldType": { - "message": "Field type" + "message": "نوع الحقل" }, "fieldLabel": { - "message": "Field label" + "message": "اسم الحقل" }, "remove": { "message": "إزالة" @@ -455,7 +455,7 @@ "description": "This is the folder for uncategorized items" }, "selfOwnershipLabel": { - "message": "You", + "message": "أنت", "description": "Used as a label to indicate that the user is the owner of an item." }, "addFolder": { @@ -464,6 +464,18 @@ "editFolder": { "message": "تعديل المجلد" }, + "newFolder": { + "message": "مجلد جديد" + }, + "folderName": { + "message": "اسم المجلد" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "هل أنت متأكد من أنك تريد حذف هذا المجلد بشكل دائم؟" + }, "baseDomain": { "message": "النطاق الأساسي", "description": "Domain name. Example: website.com" @@ -508,7 +520,7 @@ "message": "توليد كلمة مرور" }, "generatePassphrase": { - "message": "Generate passphrase" + "message": "توليد عبارة مرور" }, "checkPassword": { "message": "تحقق مما إذا تم الكشف عن كلمة المرور." @@ -611,7 +623,7 @@ "message": "ملاحظة سرية" }, "typeSshKey": { - "message": "SSH key" + "message": "مفتاح بروتوكول النقل الآمن" }, "typeLoginPlural": { "message": "تسجيلات الدخول" @@ -644,7 +656,7 @@ "message": "الاسم الكامل" }, "address": { - "message": "Address" + "message": "العنوان" }, "address1": { "message": "العنوان 1" @@ -723,19 +735,10 @@ "message": "عنصر" }, "itemDetails": { - "message": "Item details" + "message": "تفاصيل العنصر" }, "itemName": { - "message": "Item name" - }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } + "message": "اسم العنصر" }, "ex": { "message": "مثال.", @@ -761,7 +764,7 @@ } }, "copySuccessful": { - "message": "Copy Successful" + "message": "تم النسخ بنجاح" }, "copyValue": { "message": "نسخ القيمة", @@ -772,11 +775,11 @@ "description": "Copy password to clipboard" }, "copyPassphrase": { - "message": "Copy passphrase", + "message": "نسخ عبارة المرور", "description": "Copy passphrase to clipboard" }, "passwordCopied": { - "message": "Password copied" + "message": "تم نسخ كلمة المرور" }, "copyUsername": { "message": "نسخ اسم المستخدم", @@ -795,7 +798,7 @@ "description": "Copy URI to clipboard" }, "copyCustomField": { - "message": "Copy $FIELD$", + "message": "نسخ $FIELD$", "placeholders": { "field": { "content": "$1", @@ -804,34 +807,34 @@ } }, "copyWebsite": { - "message": "Copy website" + "message": "نسخ الموقع الإلكتروني" }, "copyNotes": { - "message": "Copy notes" + "message": "نسخ الملاحظات" }, "copyAddress": { - "message": "Copy address" + "message": "نسخ العنوان" }, "copyPhone": { "message": "Copy phone" }, "copyEmail": { - "message": "Copy email" + "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": "نسخ رقم الرخصة" }, "copyName": { - "message": "Copy name" + "message": "نسخ الاسم" }, "me": { "message": "أنا" @@ -991,22 +994,22 @@ "message": "تم تسجيل الخروج" }, "loggedOutDesc": { - "message": "You have been logged out of your account." + "message": "لقد تم تسجيل خروجك من الحساب." }, "loginExpired": { "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": "هل أنت متأكد من أنك تريد تسجيل الخروج؟" @@ -1033,7 +1036,7 @@ "message": "تسجيل الدخول باستخدام الجهاز يجب أن يتم إعداده في إعدادات تطبيق Bitwarden. هل تحتاج إلى خيار آخر؟" }, "needAnotherOptionV1": { - "message": "Need another option?" + "message": "هل تحتاج إلى خيار آخر؟" }, "loginWithMasterPassword": { "message": "تسجيل الدخول باستخدام كلمة المرور الرئيسية" @@ -1048,13 +1051,13 @@ "message": "استخدم طريقة أخرى للولوج" }, "logInWithPasskey": { - "message": "Log in with passkey" + "message": "تسجيل الدخول باستخدام مفتاح المرور" }, "useSingleSignOn": { "message": "Use single sign-on" }, "welcomeBack": { - "message": "Welcome back" + "message": "مرحباً بعودتك" }, "invalidPasskeyPleaseTryAgain": { "message": "مفتاح المرور غير صالح. الرجاء المحاولة مرة أخرى." @@ -1078,13 +1081,13 @@ "message": "Keep this window open and follow prompts from your browser." }, "errorCreatingPasskey": { - "message": "Error creating passkey" + "message": "خطأ في إنشاء مفتاح المرور" }, "errorCreatingPasskeyInfo": { "message": "There was a problem creating your passkey." }, "passkeySuccessfullyCreated": { - "message": "Passkey successfully created!" + "message": "تم إنشاء مفتاح المرور بنجاح!" }, "customPasskeyNameInfo": { "message": "Name your passkey to help you identify it." @@ -1132,16 +1135,16 @@ "message": "Passkey limit reached. Remove a passkey to add another." }, "tryAgain": { - "message": "Try again" + "message": "حاول مرة أخرى" }, "createAccount": { "message": "إنشاء حساب" }, "newToBitwarden": { - "message": "New to Bitwarden?" + "message": "هل أنت جديد في بيتواردن؟" }, "setAStrongPassword": { - "message": "Set a strong password" + "message": "تعيين كلمة مرور قوية" }, "finishCreatingYourAccountBySettingAPassword": { "message": "Finish creating your account by setting a password" @@ -1156,16 +1159,16 @@ "message": "تسجيل الدخول" }, "logInToBitwarden": { - "message": "Log in to Bitwarden" + "message": "تسجيل الدخول إلى بيتواردن" }, "authenticationTimeout": { - "message": "Authentication timeout" + "message": "مهلة المصادقة" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." }, "verifyIdentity": { - "message": "Verify your Identity" + "message": "قم بتأكيد هويتك" }, "weDontRecognizeThisDevice": { "message": "We don't recognize this device. Enter the code sent to your email to verify your identity." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "بَدْء تسجيل الدخول" }, + "logInRequestSent": { + "message": "تم إرسال الطلب" + }, "submit": { "message": "قدِّم" }, @@ -1235,7 +1241,7 @@ "message": "الإعدادات" }, "accountEmail": { - "message": "Account email" + "message": "البريد الإلكتروني للحساب" }, "requestHint": { "message": "Request hint" @@ -1287,7 +1293,7 @@ "message": "Your new account has been created!" }, "youHaveBeenLoggedIn": { - "message": "You have been logged in!" + "message": "لقد قمت بتسجيل الدخول!" }, "trialAccountCreated": { "message": "تم إنشاء الحساب بنجاح." @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "تم إرسال إشعار إلى جهازك." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "هل تحاول الوصول إلى حسابك؟" + }, + "accessAttemptBy": { + "message": "محاولة تسجيل الدخول بواسطة $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "تأكيد الوصول" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "الإصدار $VERSION_NUMBER$", "placeholders": { @@ -1414,7 +1447,7 @@ "message": "إرسال رمز التحقق إلى البريد الإلكتروني مرة أخرى" }, "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" + "message": "استخدام طريقة أخرى لتسجيل الدخول بخطوتين" }, "insertYubiKey": { "message": "Insert your YubiKey into your computer's USB port, then touch its button." @@ -1468,7 +1501,7 @@ "message": "FIDO U2F security a key" }, "webAuthnTitle": { - "message": "Passkey" + "message": "مفتاح المرور" }, "webAuthnDesc": { "message": "Use your device's biometrics or a FIDO2 compatible security key." @@ -1480,7 +1513,7 @@ "message": "البريد الإلكتروني" }, "emailDescV2": { - "message": "Enter a code sent to your email." + "message": "أدخل الرمز الذي تم إرساله إلى بريدك الإلكتروني." }, "continue": { "message": "استمرار" @@ -1587,7 +1620,7 @@ "message": "تصدير" }, "exportFrom": { - "message": "Export from" + "message": "التصدير من" }, "exportVault": { "message": "تصدير الخزانة" @@ -1611,10 +1644,10 @@ "message": "تأكيد التنسيق" }, "filePassword": { - "message": "File password" + "message": "كلمة مرور الملف" }, "confirmFilePassword": { - "message": "Confirm file password" + "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." @@ -1626,7 +1659,7 @@ "message": "نوع التصدير" }, "accountRestricted": { - "message": "Account restricted" + "message": "تم تقييد الحساب" }, "passwordProtected": { "message": "Password protected" @@ -1664,38 +1697,35 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "إعادة توليد كلمة المرور" - }, "length": { "message": "الطول" }, "passwordMinLength": { - "message": "Minimum password length" + "message": "الحد الأدنى لطول كلمة المرور" }, "uppercase": { - "message": "Uppercase (A-Z)", + "message": "أحرف كبيرة (من A إلى Z)", "description": "deprecated. Use uppercaseLabel instead." }, "lowercase": { - "message": "Lowercase (a-z)", + "message": "أحرف صغيرة (من a إلى z)", "description": "deprecated. Use lowercaseLabel instead." }, "numbers": { - "message": "Numbers (0-9)", + "message": "أرقام (من 0 إلى 9)", "description": "deprecated. Use numbersLabel instead." }, "specialCharacters": { - "message": "Special characters (!@#$%^&*)" + "message": "أحرف خاصة (!@#$%^&*)" }, "numWords": { "message": "عدد الكلمات" }, "wordSeparator": { - "message": "Word separator" + "message": "فاصل الكلمات" }, "capitalize": { - "message": "Capitalize", + "message": "كبِّر الحروف", "description": "Make the first letter of a word uppercase." }, "includeNumber": { @@ -1709,7 +1739,7 @@ "message": "سجل كلمات المرور" }, "generatorHistory": { - "message": "Generator history" + "message": "سجل المولد" }, "clearGeneratorHistoryTitle": { "message": "Clear generator history" @@ -1718,16 +1748,16 @@ "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" }, "noPasswordsInList": { - "message": "There are no passwords to list." + "message": "لا توجد كلمات مرور للعرض." }, "clearHistory": { - "message": "Clear history" + "message": "مسح السجل" }, "nothingToShow": { - "message": "Nothing to show" + "message": "لا يوجد شيء لعرضه" }, "nothingGeneratedRecently": { - "message": "You haven't generated anything recently" + "message": "لم تقم بتوليد أي شيء مؤخراً" }, "clear": { "message": "مسح", @@ -1767,10 +1797,10 @@ "message": "الرجاء تسجيل الدخول مرة أخرى." }, "currentSession": { - "message": "Current session" + "message": "الجلسة الحالية" }, "requestPending": { - "message": "Request pending" + "message": "الطلب معلًق" }, "logBackInOthersToo": { "message": "Please log back in. If you are using other Bitwarden applications log out and back in to those as well." @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "منطقة خطرة" }, - "dangerZoneDesc": { - "message": "احذر، لن تستطيع التراجع عن هذه الإجراءات!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Deauthorize sessions" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Proceeding will also log you out of your current session, requiring you to log back in. You will also be prompted for two-step login again, if set up. Active sessions on other devices may continue to remain active for up to one hour." }, + "newDeviceLoginProtection": { + "message": "تسجيل الدخول لجهاز جديد" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "All sessions deauthorized" }, @@ -1894,13 +1939,13 @@ "message": "Proceed below to delete your account and all vault data." }, "deleteAccountWarning": { - "message": "Deleting your account is permanent. It cannot be undone." + "message": "حذف حسابك بشكل نهائي. لا يمكن التراجع عنه." }, "accountDeleted": { - "message": "Account deleted" + "message": "تم حذف الحساب" }, "accountDeletedDesc": { - "message": "Your account has been closed and all associated data has been deleted." + "message": "لقد تم إغلاق حسابك وتم حذف جميع البيانات المرتبطة به." }, "deleteOrganizationWarning": { "message": "Deleting your organization is permanent. It cannot be undone." @@ -1919,11 +1964,11 @@ "description": "This will be part of a larger sentence, that will read like this: If you don't have any data to import, you can create a new item instead. (Optional second half: You may need to wait until your administrator confirms your organization membership.)" }, "onboardingImportDataDetailsLink": { - "message": "new item", + "message": "عنصر جديد", "description": "This will be part of a larger sentence, that will read like this: If you don't have any data to import, you can create a new item instead. (Optional second half: You may need to wait until your administrator confirms your organization membership.)" }, "onboardingImportDataDetailsLoginLink": { - "message": "new login", + "message": "تسجيل دخول جديد", "description": "This will be part of a larger sentence, that will read like this: If you don't have any data to import, you can create a new login instead. (Optional second half: You may need to wait until your administrator confirms your organization membership.)" }, "onboardingImportDataDetailsPartTwoNoOrgs": { @@ -1968,22 +2013,22 @@ "message": "Data is not formatted correctly. Please check your import file and try again." }, "importNothingError": { - "message": "Nothing was imported." + "message": "لم يتم استيراد أي شيء." }, "importEncKeyError": { "message": "Error decrypting the exported file. Your encryption key does not match the encryption key used export the data." }, "destination": { - "message": "Destination" + "message": "الوجهة" }, "learnAboutImportOptions": { "message": "Learn about your import options" }, "selectImportFolder": { - "message": "Select a folder" + "message": "تحديد المجلد" }, "selectImportCollection": { - "message": "Select a collection" + "message": "اختر مجموعة" }, "importTargetHint": { "message": "Select this option if you want the imported file contents moved to a $DESTINATION$", @@ -2008,13 +2053,13 @@ "message": "اختيار ملف" }, "noFileChosen": { - "message": "No file chosen" + "message": "لم يتم اختيار ملف" }, "orCopyPasteFileContents": { "message": "او قم بنسخ ولصق محتويات مِلَفّ الاستيراد" }, "instructionsFor": { - "message": "$NAME$ Instructions", + "message": "تعليمات $NAME$", "description": "The title for the import tool instructions.", "placeholders": { "name": { @@ -2033,7 +2078,7 @@ "message": "تخصيص تجرِبة خزانة الويب الخاصة بك." }, "preferencesUpdated": { - "message": "Preferences saved" + "message": "تم حفظ التفضيلات" }, "language": { "message": "اللّغة" @@ -2048,7 +2093,7 @@ "message": "Show a recognizable image next to each login." }, "default": { - "message": "Default" + "message": "الافتراضي" }, "domainRules": { "message": "قواعد النطاق" @@ -2063,13 +2108,13 @@ "message": "Custom equivalent domains" }, "exclude": { - "message": "Exclude" + "message": "استثناء" }, "include": { - "message": "Include" + "message": "تضمين" }, "customize": { - "message": "Customize" + "message": "تخصيص" }, "newCustomDomain": { "message": "New custom domain" @@ -2121,17 +2166,17 @@ "message": "View recovery code" }, "providers": { - "message": "Providers", + "message": "المزودون", "description": "Two-step login providers such as YubiKey, Duo, Authenticator apps, Email, etc." }, "enable": { - "message": "Turn on" + "message": "تفعيل" }, "enabled": { - "message": "Turned on" + "message": "تم التفعيل" }, "restoreAccess": { - "message": "Restore access" + "message": "استعادة الوصول" }, "premium": { "message": "بريميوم", @@ -2155,14 +2200,26 @@ "manage": { "message": "إدارة" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "عرض العناصر" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "تعديل العناصر" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { - "message": "Turn off" + "message": "إيقاف" }, "revokeAccess": { - "message": "Revoke access" + "message": "إلغاء الوصول" }, "twoStepLoginProviderEnabled": { "message": "This two-step login provider is active on your account." @@ -2174,16 +2231,16 @@ "message": "Download an authenticator app such as" }, "twoStepAuthenticatorInstructionInfix1": { - "message": "," + "message": "،" }, "twoStepAuthenticatorInstructionInfix2": { - "message": "or" + "message": "أو" }, "twoStepAuthenticatorInstructionSuffix": { "message": "." }, "continueToExternalUrlTitle": { - "message": "Continue to $URL$?", + "message": "هل تريد المتابعة إلى $URL$؟", "placeholders": { "url": { "content": "$1", @@ -2195,7 +2252,7 @@ "message": "You are leaving Bitwarden and launching an external website in a new window." }, "twoStepContinueToBitwardenUrlTitle": { - "message": "Continue to bitwarden.com?" + "message": "هل تريد المتابعة إلى bitwarden.com؟" }, "twoStepContinueToBitwardenUrlDesc": { "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." @@ -2207,10 +2264,10 @@ "message": "Could not load QR code. Try again or use the key below." }, "key": { - "message": "Key" + "message": "المفتاح" }, "twoStepAuthenticatorEnterCodeV2": { - "message": "Verification code" + "message": "رمز التحقق" }, "twoStepAuthenticatorReaddDesc": { "message": "In case you need to add it to another device, below is the QR code (or key) required by your authenticator app." @@ -2234,7 +2291,7 @@ "message": "Touch the YubiKey's button." }, "twoFactorYubikeySaveForm": { - "message": "Save the form." + "message": "حفظ النموذج." }, "twoFactorYubikeyWarning": { "message": "Due to platform limitations, YubiKeys cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when YubiKeys cannot be used. Supported platforms:" @@ -2291,7 +2348,7 @@ "message": "Enter the Bitwarden application information from your Duo Admin panel." }, "twoFactorDuoClientId": { - "message": "Client Id" + "message": "معرّف العميل" }, "twoFactorDuoClientSecret": { "message": "Client Secret" @@ -2336,7 +2393,7 @@ "message": "If the security key has a button, touch it." }, "twoFactorU2fSaveForm": { - "message": "Save the form." + "message": "حفظ النموذج." }, "twoFactorU2fWarning": { "message": "Due to platform limitations, FIDO U2F cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when FIDO U2F cannot be used. Supported platforms:" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "There was a problem reading the security key. Try again." }, - "twoFactorWebAuthnWarning": { - "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used. Supported platforms:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Web vault and browser extensions on a desktop/laptop with a WebAuthn supported browser (Chrome, Opera, Vivaldi, or Firefox with FIDO U2F turned on)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Your Bitwarden two-step login recovery code" @@ -2366,7 +2420,7 @@ "message": "You have not set up any two-step login providers yet. After you have set up a two-step login provider you can check back here for your recovery code." }, "printCode": { - "message": "Print code", + "message": "طباعة الرمز", "description": "Print 2FA recovery code" }, "reports": { @@ -2381,13 +2435,13 @@ "description": "Vault health reports can be used to evaluate the security of your Bitwarden individual or organization vault." }, "unsecuredWebsitesReport": { - "message": "Unsecure websites" + "message": "مواقع الويب غير الآمنة" }, "unsecuredWebsitesReportDesc": { "message": "URLs that start with http:// don’t use the best available encryption. Change the login URIs for these accounts to https:// for safer browsing." }, "unsecuredWebsitesFound": { - "message": "Unsecured websites found" + "message": "تم العثور على مواقع ويب غير آمنة" }, "unsecuredWebsitesFoundReportDesc": { "message": "We found $COUNT$ items in your $VAULT$ with unsecured URIs. You should change their URI scheme to https:// if the website allows it.", @@ -2431,7 +2485,7 @@ "message": "No websites were found in your vault with a missing two-step login configuration." }, "instructions": { - "message": "Instructions" + "message": "التعليمات" }, "exposedPasswordsReport": { "message": "Exposed passwords" @@ -2474,13 +2528,13 @@ } }, "weakPasswordsReport": { - "message": "Weak passwords" + "message": "كلمات المرور الضعيفة" }, "weakPasswordsReportDesc": { "message": "Weak passwords can be easily guessed by attackers. Change these passwords to strong ones using the password generator." }, "weakPasswordsFound": { - "message": "Weak passwords found" + "message": "تم العثور على كلمات مرور ضعيفة" }, "weakPasswordsFoundReportDesc": { "message": "We found $COUNT$ items in your $VAULT$ with passwords that are not strong. You should update them to use stronger passwords.", @@ -2527,10 +2581,10 @@ "message": "No logins in your vault have passwords that are being reused." }, "timesReused": { - "message": "Times reused" + "message": "عدد مرات إعادة الاستخدام" }, "reusedXTimes": { - "message": "Reused $COUNT$ times", + "message": "تمت إعادة الاستخدام $COUNT$ مرة", "placeholders": { "count": { "content": "$1", @@ -2560,7 +2614,7 @@ } }, "goodNews": { - "message": "Good news", + "message": "أخبار جيدة!", "description": "ex. Good News, No Breached Accounts Found!" }, "breachUsernameFound": { @@ -2586,7 +2640,7 @@ "message": "موقع الويب" }, "affectedUsers": { - "message": "Affected users" + "message": "المستخدمون المتأثرون" }, "breachOccurred": { "message": "Breach occurred" @@ -2598,24 +2652,24 @@ "message": "An error occurred trying to load the report. Try again" }, "billing": { - "message": "Billing" + "message": "الفوترة" }, "billingPlanLabel": { - "message": "Billing plan" + "message": "خطة الفوترة" }, "paymentType": { - "message": "Payment type" + "message": "طريقة الدفع" }, "accountCredit": { "message": "Account credit", "description": "Financial term. In the case of Bitwarden, a positive balance means that you owe money, while a negative balance means that you have a credit (Bitwarden owes you money)." }, "accountBalance": { - "message": "Account balance", + "message": "رصيد الحساب", "description": "Financial term. In the case of Bitwarden, a positive balance means that you owe money, while a negative balance means that you have a credit (Bitwarden owes you money)." }, "addCredit": { - "message": "Add credit", + "message": "إضافة رصيد", "description": "Add more credit to your account's balance." }, "amount": { @@ -2688,10 +2742,10 @@ "message": "Bitwarden Families plan." }, "addons": { - "message": "Add-ons" + "message": "الإضافات" }, "premiumAccess": { - "message": "Premium access" + "message": "الوصول المميز" }, "premiumAccessDesc": { "message": "You can add Premium access to all members of your organization for $PRICE$ /$INTERVAL$.", @@ -2739,13 +2793,13 @@ "message": "سنة" }, "yr": { - "message": "yr" + "message": "سنة" }, "month": { "message": "شهر" }, "monthAbbr": { - "message": "mo.", + "message": "شهر", "description": "Short abbreviation for 'month'" }, "paymentChargedAnnually": { @@ -2767,10 +2821,10 @@ "message": "Your plan comes with a free 7 day trial. Your payment method will not be charged until the trial has ended. You may cancel at any time." }, "paymentInformation": { - "message": "Payment information" + "message": "معلومات الدفع" }, "billingInformation": { - "message": "Billing information" + "message": "معلومات الفوترة" }, "billingTrialSubLabel": { "message": "Your payment method will not be charged during the 7 day free trial." @@ -2782,13 +2836,13 @@ "message": "Select the PayPal button to log into your PayPal account, then click the Submit button below to continue." }, "cancelSubscription": { - "message": "Cancel subscription" + "message": "إلغاء الاشتراك" }, "subscriptionExpiration": { - "message": "Subscription expiration" + "message": "تاريخ انتهاء الاشتراك" }, "subscriptionCanceled": { - "message": "The subscription has been canceled." + "message": "تم إلغاء الاشتراك." }, "pendingCancellation": { "message": "Pending cancellation" @@ -2809,40 +2863,40 @@ "message": "Are you sure you want to cancel? You will lose access to all of this subscription's features at the end of this billing cycle." }, "canceledSubscription": { - "message": "Subscription canceled" + "message": "تم إلغاء الإشتراك" }, "neverExpires": { - "message": "Never expires" + "message": "صلاحية غير محدودة" }, "status": { - "message": "Status" + "message": "الحالة" }, "nextCharge": { - "message": "Next charge" + "message": "الدفعة القادمة" }, "details": { "message": "التفاصيل" }, "downloadLicense": { - "message": "Download license" + "message": "تنزيل الرخصة" }, "viewBillingToken": { "message": "View Billing Token" }, "updateLicense": { - "message": "Update license" + "message": "تحديث الرخصة" }, "manageSubscription": { - "message": "Manage subscription" + "message": "إدارة الاشتراك" }, "launchCloudSubscription": { "message": "Launch Cloud Subscription" }, "storage": { - "message": "Storage" + "message": "مساحة التخزين" }, "addStorage": { - "message": "Add storage" + "message": "إضافة مساحة تخزين" }, "removeStorage": { "message": "Remove storage" @@ -2861,47 +2915,47 @@ } }, "paymentMethod": { - "message": "Payment method" + "message": "طريقة الدفع" }, "noPaymentMethod": { "message": "No payment method on file." }, "addPaymentMethod": { - "message": "Add payment method" + "message": "إضافة طريقة دفع" }, "changePaymentMethod": { - "message": "Change payment method" + "message": "تغيير طريقة الدفع" }, "invoices": { - "message": "Invoices" + "message": "الفواتير" }, "noUnpaidInvoices": { - "message": "No unpaid invoices." + "message": "لا يوجد فواتير غير مدفوعة." }, "noPaidInvoices": { - "message": "No paid invoices." + "message": "لا يوجد فواتير مدفوعة." }, "paid": { - "message": "Paid", + "message": "مدفوع", "description": "Past tense status of an invoice. ex. Paid or unpaid." }, "unpaid": { - "message": "Unpaid", + "message": "غير مدفوع", "description": "Past tense status of an invoice. ex. Paid or unpaid." }, "transactions": { - "message": "Transactions", + "message": "الحركات المالية", "description": "Payment/credit transactions." }, "noTransactions": { - "message": "No transactions." + "message": "لا يوجد حركات مالية." }, "chargeNoun": { "message": "Charge", "description": "Noun. A charge from a payment method." }, "refundNoun": { - "message": "Refund", + "message": "استرداد مالي", "description": "Noun. A refunded payment that was charged." }, "chargesStatement": { @@ -2938,7 +2992,7 @@ "message": "Contact customer support" }, "contactSupportShort": { - "message": "Contact Support" + "message": "الاتصال بالدعم الفني" }, "updatedPaymentMethod": { "message": "Updated payment method." @@ -2983,7 +3037,7 @@ "message": "البريد الإلكتروني للفوترة" }, "businessName": { - "message": "Business name" + "message": "الاسم التجاري" }, "chooseYourPlan": { "message": "اختر خِطَّة اشتراكك" @@ -3030,7 +3084,7 @@ } }, "planNameFamilies": { - "message": "Families" + "message": "العائلات" }, "planDescFamilies": { "message": "For personal use, to share with family & friends." @@ -3063,7 +3117,7 @@ } }, "additionalUsers": { - "message": "Additional users" + "message": "مستخدمين إضافيين" }, "costPerUser": { "message": "$COST$ per user", @@ -3180,13 +3234,13 @@ "message": "شهريا" }, "annually": { - "message": "Annually" + "message": "سنويّاً" }, "annual": { - "message": "Annual" + "message": "سنوي" }, "basePrice": { - "message": "Base price" + "message": "السعر الأساسي" }, "organizationCreated": { "message": "Organization created" @@ -3198,7 +3252,7 @@ "message": "Organization upgraded" }, "leave": { - "message": "Leave" + "message": "خروج" }, "leaveOrganizationConfirmation": { "message": "Are you sure you want to leave this organization?" @@ -3282,25 +3336,25 @@ "message": "Access control" }, "readOnly": { - "message": "Read only" + "message": "للقراءة فقط" }, "newCollection": { - "message": "New collection" + "message": "مجموعة جديدة" }, "addCollection": { - "message": "Add collection" + "message": "إضافة مجموعة" }, "editCollection": { - "message": "Edit collection" + "message": "تعديل المجموعة" }, "collectionInfo": { - "message": "Collection info" + "message": "بيانات المجموعة" }, "deleteCollectionConfirmation": { - "message": "Are you sure you want to delete this collection?" + "message": "هل أنت متأكد من أنك تريد حذف هذه المجموعة؟" }, "editMember": { - "message": "Edit member" + "message": "تعديل العضو" }, "fieldOnTabRequiresAttention": { "message": "A field on the '$TAB$' tab requires your attention.", @@ -3324,10 +3378,10 @@ } }, "inviteSingleEmailDesc": { - "message": "You have 1 invite remaining." + "message": "تبقى لك دعوة واحدة." }, "inviteZeroEmailDesc": { - "message": "You have 0 invites remaining." + "message": "لم يتبق لك أي دعوات." }, "userUsingTwoStep": { "message": "This user is using two-step login to protect their account." @@ -3384,10 +3438,10 @@ "message": "Event" }, "unknown": { - "message": "Unknown" + "message": "مجهول" }, "loadMore": { - "message": "Load more" + "message": "تحميل المزيد" }, "mobile": { "message": "Mobile", @@ -3444,7 +3498,7 @@ "message": "Incorrect PIN" }, "pin": { - "message": "PIN", + "message": "رقم التعريف الشخصي", "description": "PIN code. Ex. The short code (often numeric) that you use to unlock a device." }, "exportedVault": { @@ -3616,10 +3670,10 @@ } }, "deletedCollections": { - "message": "Deleted collections" + "message": "المجموعات المحذوفة" }, "deletedCollectionId": { - "message": "Deleted collection $ID$.", + "message": "المجموعة المحذوفة $ID$.", "placeholders": { "id": { "content": "$1", @@ -3917,13 +3971,13 @@ "message": "No email?" }, "goBack": { - "message": "Go back" + "message": "الرجوع إلى الخلف" }, "toEditYourEmailAddress": { "message": "to edit your email address." }, "view": { - "message": "View" + "message": "عرض" }, "invalidDateRange": { "message": "Invalid date range." @@ -3932,10 +3986,10 @@ "message": "لقد حدث خطأ." }, "userAccess": { - "message": "User access" + "message": "وصول المستخدم" }, "userType": { - "message": "User type" + "message": "نوع المستخدم" }, "groupAccess": { "message": "Group access" @@ -3950,7 +4004,7 @@ "message": "Resend invitation" }, "resendEmail": { - "message": "Resend email" + "message": "إعادة إرسال البريد الإلكتروني" }, "hasBeenReinvited": { "message": "$USER$ reinvited", @@ -3962,10 +4016,10 @@ } }, "confirm": { - "message": "Confirm" + "message": "تأكيد" }, "confirmUser": { - "message": "Confirm user" + "message": "تأكيد المستخدم" }, "hasBeenConfirmed": { "message": "$USER$ confirmed.", @@ -3977,7 +4031,7 @@ } }, "confirmUsers": { - "message": "Confirm members" + "message": "تأكيد الأعضاء" }, "usersNeedConfirmed": { "message": "You have members that have accepted their invitation, but still need to be confirmed. Members will not have access to the organization until they are confirmed." @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Set requirements for password generator." }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organization policies are affecting your generator settings." - }, "masterPasswordPolicyInEffect": { "message": "One or more organization policies require your master password to meet the following requirements:" }, @@ -6666,15 +6717,6 @@ "message": "المولّد", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "ما الذي ترغب في توليده؟" - }, - "passwordType": { - "message": "نوع كلمة المرور" - }, - "regenerateUsername": { - "message": "إعادة توليد اسم المستخدم" - }, "generateUsername": { "message": "Generate username" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Use your domain's configured catch-all inbox." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Random", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "اسم المضيف", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API access token" - }, "deviceVerification": { "message": "Device verification" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "No collection" }, - "canView": { - "message": "Can view" - }, - "canViewExceptPass": { - "message": "Can view, except passwords" - }, - "canEdit": { - "message": "Can edit" - }, - "canEditExceptPass": { - "message": "Can edit, except passwords" - }, "noCollectionsAdded": { "message": "No collections added" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domain" - }, "alreadyHaveAccount": { "message": "Already have an account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/az/messages.json b/apps/web/src/locales/az/messages.json index 279fc202748..4c49936c88e 100644 --- a/apps/web/src/locales/az/messages.json +++ b/apps/web/src/locales/az/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Qovluğa düzəliş et" }, + "newFolder": { + "message": "Yeni qovluq" + }, + "folderName": { + "message": "Qovluq adı" + }, + "folderHintText": { + "message": "Ana qovluğun adından sonra \"/\" əlavə edərək qovluğu ardıcıl yerləşdirin. Nümunə: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Bu qovluğu həmişəlik silmək istədiyinizə əminsiniz?" + }, "baseDomain": { "message": "Baza domeni", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Element adı" }, - "cannotRemoveViewOnlyCollections": { - "message": "\"Yalnız baxma\" icazələrinə sahib kolleksiyaları silə bilməzsiniz: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "məs.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Giriş etmə başladıldı" }, + "logInRequestSent": { + "message": "Tələb göndərildi" + }, "submit": { "message": "Göndər" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "Cihazınıza bir bildiriş göndərildi." }, + "notificationSentDevicePart1": { + "message": "Cihazınızda Bitwarden kilidini açın, ya da " + }, + "areYouTryingToAccessYourAccount": { + "message": "Hesabınıza müraciət etməyə çalışırsınız?" + }, + "accessAttemptBy": { + "message": "$EMAIL$ ilə müraciət cəhdi", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Müraciəti təsdiqlə" + }, + "denyAccess": { + "message": "Müraciətə rədd cavabı ver" + }, + "notificationSentDeviceAnchor": { + "message": "veb tətbiqinizdə" + }, + "notificationSentDevicePart2": { + "message": "Təsdiqləməzdən əvvəl Barmaq izi ifadəsinin aşağıdakı ifadə ilə uyuşduğuna əmin olun." + }, + "notificationSentDeviceComplete": { + "message": "Cihazınızda Bitwarden-in kilidini açın. Təsdiqləməzdən əvvəl Barmaq izi ifadəsinin aşağıdakı ifadə ilə uyuşduğuna əmin olun." + }, "aNotificationWasSentToYourDevice": { "message": "Cihazınıza bir bildiriş göndərildi" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Hesabınızın kilidinin açıq olduğuna və barmaq izi ifadəsinin digər cihazda uyuşduğuna əmin olun" - }, "versionNumber": { "message": "Versiya $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Anlaşılmaz xarakterlərdən çəkin", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Parolu yenidən yarat" - }, "length": { "message": "Uzunluq" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Təhlükəli zona" }, - "dangerZoneDesc": { - "message": "Diqqətli olun, bu əməliyyatları geri qaytara bilməzsiniz!" - }, - "dangerZoneDescSingular": { - "message": "Diqqətli olun, bu əməliyyatı geri qaytara bilməzsiniz!" - }, "deauthorizeSessions": { "message": "Seansların səlahiyyətlərini götür" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Davam etsəniz, hazırkı seansınız bitəcək, təkrar giriş etməyiniz tələb olunacaq. Fəallaşdırılıbsa, iki addımlı giriş üçün yenidən soruşulacaq. Digər cihazlardakı aktiv seanslar, bir saata qədər aktiv qalmağa davam edə bilər." }, + "newDeviceLoginProtection": { + "message": "Yeni cihaz girişi" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Yeni cihaz girişi qorumasını söndür" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Yeni cihaz girişi qorumasını işə sal" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Yeni bir cihazdan giriş etdiyiniz zaman Bitwarden göndərən doğrulama e-poçtlarını dayandırmaq üçün aşağıdakı addımları izləyin." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Yeni bir cihazdan giriş etdiyiniz zaman Bitwarden-in sizə doğrulama e-poçtlarını göndərməsi üçün aşağıdakı addımları izləyin." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "Yeni cihaz girişi qorumasını söndürsəniz, ana parolunuzu bilən hər kəs, istənilən cihazdan hesabınıza müraciət edə bilər. Hesabınızı doğrulama e-poçtları olmadan qorumaq üçün iki addımlı girişi qurun." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "Yeni cihaz girişi qoruması dəyişiklikləri saxlanıldı" + }, "sessionsDeauthorized": { "message": "Bütün seansların səlahiyyəti götürüldü" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "İdarə et" }, - "canManage": { - "message": "İdarə edə bilər" + "manageCollection": { + "message": "Kolleksiyanı idarə et" + }, + "viewItems": { + "message": "Elementlərə bax" + }, + "viewItemsHidePass": { + "message": "Elementlərə, gizli parollara bax" + }, + "editItems": { + "message": "Elementlərə düzəliş et" + }, + "editItemsHidePass": { + "message": "Elementlərə, gizli parollara düzəliş et" }, "disable": { "message": "Sıradan çıxart" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "Güvənlik açarı oxunarkən problem yarandı. Yenidən sınayın." }, - "twoFactorWebAuthnWarning": { - "message": "Platforma məhdudiyyətlərinə görə, WebAuthn bütün Bitwarden tətbiqlərində istifadə edilə bilmir. WebAuthn istifadə edilə bilməyəndə, hesabınıza müraciət edə bilməyiniz üçün başqa bir iki addımlı giriş provayderini fəallaşdırmalısınız. Dəstəklənən platformalar:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "WebAuthn dəstəkli brauzerə sahib masaüstü/dizüstü kompüterdə veb seyf və brauzer uzantıları (FIDO U2F açıq olan Chrome, Opera, Vivaldi və ya Firefox)." + "twoFactorWebAuthnWarning1": { + "message": "Platforma məhdudiyyətlərinə görə, WebAuthn bütün Bitwarden tətbiqlərində istifadə edilə bilmir. WebAuthn istifadə edilə bilməyəndə, hesabınıza müraciət edə bilməyiniz üçün başqa bir iki addımlı giriş provayderini fəallaşdırmalısınız." }, "twoFactorRecoveryYourCode": { "message": "Bitwarden iki addımlı giriş üçün geri qaytarma kodunuz" @@ -2998,7 +3052,7 @@ "message": "Əlavə istifadəçi yerləri" }, "userSeatsDesc": { - "message": "İstifadəçi sayı" + "message": "# / istifadəçi yeri" }, "userSeatsAdditionalDesc": { "message": "Planınızda $BASE_SEATS$ istifadəçi yeri var. İstifadəçiləri, istifadəçi/ay başına $SEAT_PRICE$ qarşılığında əlavə edə bilərsiniz.", @@ -4269,7 +4323,7 @@ "message": "Sirr Menecerinə abunəliyiniz üçün bir limit müəyyən edin. Bu limitə çatanda, yeni istifadəçiləri dəvət edə bilməyəcəksiniz." }, "maxSeatLimit": { - "message": "Maksimum yer limiti (ixtiyari)", + "message": "Yer limiti (ixtiyari)", "description": "Upper limit of seats to allow through autoscaling" }, "maxSeatCost": { @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Parol yaradıcı üçün tələbləri ayarla." }, - "passwordGeneratorPolicyInEffect": { - "message": "Bir və ya daha çox təşkilat siyasətləri yaradıcı seçimlərinizə təsir edir." - }, "masterPasswordPolicyInEffect": { "message": "Bir və ya daha çox təşkilat siyasəti, aşağıdakı tələbləri qarşılamaq üçün ana parolunuzu tələb edir:" }, @@ -6666,15 +6717,6 @@ "message": "Yaradıcı", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "Nə yaratmaq istəyirsiniz?" - }, - "passwordType": { - "message": "Parol növü" - }, - "regenerateUsername": { - "message": "İstifadəçi adını yenidən yarat" - }, "generateUsername": { "message": "İstifadəçi adı yarat" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "İstifadəçi adı növü" - }, "plusAddressedEmail": { "message": "Plyus ünvanlı e-poçt", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Domeninizin konfiqurasiya edilmiş hamısını yaxalama gələn qutusunu istifadə edin." }, + "useThisEmail": { + "message": "Bu e-poçtu istifadə et" + }, "random": { "message": "Təsadüfi", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Host adı", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API müraciət tokeni" - }, "deviceVerification": { "message": "Cihaz doğrulaması" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "Kolleksiya yoxdur" }, - "canView": { - "message": "Baxa bilər" - }, - "canViewExceptPass": { - "message": "Parollar istisna olmaqla baxa bilər" - }, - "canEdit": { - "message": "Düzəliş edə bilər" - }, - "canEditExceptPass": { - "message": "Parollar istisna olmaqla düzəliş edə bilər" - }, "noCollectionsAdded": { "message": "Heç bir kolleksiya əlavə edilmədi" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Kolleksiya silinməsini sahibləri və adminləri ilə məhdudlaşdır" }, + "limitItemDeletionDesc": { + "message": "Elementin silinməsini \"İdarə edə bilər\" icazəsinə sahib üzvlərlə məhdudlaşdır" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Sahiblər və adminlər bütün kolleksiyaları və elementləri idarə edə bilər" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL-si", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Domen ləqəbi" - }, "alreadyHaveAccount": { "message": "Artıq bir hesabınız var?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "Bu kolleksiyanı idarə etmək üçün müraciətiniz yoxdur." }, - "grantAddAccessCollectionWarningTitle": { - "message": "İdarə edə bilər icazələri əskikdir" + "grantManageCollectionWarningTitle": { + "message": "\"Kolleksiyanı idarə etmə\" icazələri əskikdir" }, - "grantAddAccessCollectionWarning": { - "message": "Kolleksiyanın silinməsi daxil olmaqla tam kolleksiya idarəetməsinə icazə vermək üçün \"İdarə edə bilər\" icazələrini verin." + "grantManageCollectionWarning": { + "message": "Kolleksiyanın silinməsi daxil olmaqla tam kolleksiya idarəetməsinə icazə vermək üçün \"Kolleksiyanı idarə etmə\" icazələrini verin." }, "grantCollectionAccess": { "message": "Qrup və ya üzvlərin bu kolleksiyaya müraciətinə icazə verin." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Açıqlayıcı kod" }, + "cannotRemoveViewOnlyCollections": { + "message": "\"Yalnız baxma\" icazələrinə sahib kolleksiyaları silə bilməzsiniz: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Vacib bildiriş" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "İnzibatçılar, artıq götürülmüş domenlərə aid üzv hesablarını silmə imkanına sahibdir." + }, + "deleteManagedUserWarningDesc": { + "message": "Bu əməliyyat, seyfdəki bütün elementlər daxil olmaqla üzv hesabını siləcək. Bu, əvvəlki Sil əməliyyatını əvəz edir." + }, + "deleteManagedUserWarning": { + "message": "Silmək, yeni bir əməliyyatdır!" + }, + "seatsRemaining": { + "message": "Bu təşkilata təyin edilmiş $TOTAL$ yerdən $REMAINING$ yeriniz qalıb. Abunəliyinizi idarə etmək üçün provayderinizlə əlaqə saxlayın.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Mövcud təşkilat" + }, + "selectOrganizationProviderPortal": { + "message": "Provayder Portalınıza əlavə ediləcək təşkilatı seçin." + }, + "noOrganizations": { + "message": "Sadalanacaq heç bir təşkilat yoxdur." + }, + "yourProviderSubscriptionCredit": { + "message": "Provayder abunəliyiniz, təşkilatınızın abunəliyində qalan vaxt üçün bir kredit alacaq." + }, + "doYouWantToAddThisOrg": { + "message": "Bu təşkilatı bura əlavə etmək istəyirsiniz: $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Mövcud təşkilat əlavə edildi" + }, + "assignedExceedsAvailable": { + "message": "Təyin edilmiş yer sayı, boş yer sayından çoxdur." } } diff --git a/apps/web/src/locales/be/messages.json b/apps/web/src/locales/be/messages.json index d6162821907..8dcb31a1d0f 100644 --- a/apps/web/src/locales/be/messages.json +++ b/apps/web/src/locales/be/messages.json @@ -1,24 +1,24 @@ { "allApplications": { - "message": "All applications" + "message": "Усе праграмы" }, "criticalApplications": { - "message": "Critical applications" + "message": "Крытычныя праграмы" }, "accessIntelligence": { - "message": "Access Intelligence" + "message": "Кіраванне доступам" }, "riskInsights": { - "message": "Risk Insights" + "message": "Разуменне рызык" }, "passwordRisk": { - "message": "Password Risk" + "message": "Рызыка пароля" }, "reviewAtRiskPasswords": { - "message": "Review at-risk passwords (weak, exposed, or reused) across applications. Select your most critical applications to prioritize security actions for your users to address at-risk passwords." + "message": "Праглядайце паролі, якія знаходзяцца ў зоне рызыкі (ненадзейныя, скампраметаваныя або паўторна выкарыстаныя) ва ўсіх вашых праграмах. Выберыце найбольш крытычныя праграмы для вызначэння прыярытэту бяспекі дзеянняў для вашых карыстальнікаў, якія выкарыстоўваюць рызыкоўныя паролі." }, "dataLastUpdated": { - "message": "Data last updated: $DATE$", + "message": "Апошняе абнаўленне даных: $DATE$", "placeholders": { "date": { "content": "$1", @@ -27,19 +27,19 @@ } }, "notifiedMembers": { - "message": "Notified members" + "message": "Апавешчаныя ўдзельнікі" }, "revokeMembers": { - "message": "Revoke members" + "message": "Адклікаць удзельнікаў" }, "restoreMembers": { - "message": "Restore members" + "message": "Аднавіць удзельнікаў" }, "cannotRestoreAccessError": { - "message": "Cannot restore organization access" + "message": "Немагчыма аднавіць доступ да арганізацыі" }, "allApplicationsWithCount": { - "message": "All applications ($COUNT$)", + "message": "Усе праграмы ($COUNT$)", "placeholders": { "count": { "content": "$1", @@ -48,10 +48,10 @@ } }, "createNewLoginItem": { - "message": "Create new login item" + "message": "Стварыць новы элемент запісу ўваходу" }, "criticalApplicationsWithCount": { - "message": "Critical applications ($COUNT$)", + "message": "Крытычныя праграмы ($COUNT$)", "placeholders": { "count": { "content": "$1", @@ -60,7 +60,7 @@ } }, "notifiedMembersWithCount": { - "message": "Notified members ($COUNT$)", + "message": "Апавешчаныя ўдзельнікі ($COUNT$)", "placeholders": { "count": { "content": "$1", @@ -69,7 +69,7 @@ } }, "noAppsInOrgTitle": { - "message": "No applications found in $ORG NAME$", + "message": "Праграмы ў $ORG NAME$ не знойдзены", "placeholders": { "org name": { "content": "$1", @@ -78,43 +78,43 @@ } }, "noAppsInOrgDescription": { - "message": "As users save logins, applications appear here, showing any at-risk passwords. Mark critical apps and notify users to update passwords." + "message": "Тут будуць адлюстроўвацца праграмы па меры таго, як карыстальнікі будуць захоўваць запісы ўваходу, якія знаходзяцца ў зоне рызыкі. Пазначце крытычныя праграмы і апавяшчайце карыстальнікаў аб неабходнасці абнавіць паролі." }, "noCriticalAppsTitle": { - "message": "You haven't marked any applications as a Critical" + "message": "Вы не пазначылі ніводную праграму ў якасці кратычнай" }, "noCriticalAppsDescription": { - "message": "Select your most critical applications to discover at-risk passwords, and notify users to change those passwords." + "message": "Выберыце найбольш крытычныя праграмы для выяўлення пароляў, якія знаходзяцца ў зоне рызыкі. Апавяшчайце карыстальнікаў аб неабходнасці змяніць іх." }, "markCriticalApps": { - "message": "Mark critical apps" + "message": "Пазначыць крытычныя праграмы" }, "markAppAsCritical": { - "message": "Mark app as critical" + "message": "Пазначыць праграму як крытычную" }, "appsMarkedAsCritical": { - "message": "Apps marked as critical" + "message": "Праграмы пазначаныя як крытычныя" }, "application": { - "message": "Application" + "message": "Праграма" }, "atRiskPasswords": { - "message": "At-risk passwords" + "message": "Паролі ў зоне рызыкі" }, "requestPasswordChange": { - "message": "Request password change" + "message": "Запытаць змену пароля" }, "totalPasswords": { - "message": "Total passwords" + "message": "Усяго пароляў" }, "searchApps": { - "message": "Search applications" + "message": "Пошук праграм" }, "atRiskMembers": { - "message": "At-risk members" + "message": "Удзельнікі ў зоне рызыкі" }, "atRiskMembersWithCount": { - "message": "At-risk members ($COUNT$)", + "message": "Удзельнікі ў зоне рызыкі ($COUNT$)", "placeholders": { "count": { "content": "$1", @@ -123,7 +123,7 @@ } }, "atRiskApplicationsWithCount": { - "message": "At-risk applications ($COUNT$)", + "message": "Праграмы ў зоне рызыкі ($COUNT$)", "placeholders": { "count": { "content": "$1", @@ -132,13 +132,13 @@ } }, "atRiskMembersDescription": { - "message": "These members are logging into applications with weak, exposed, or reused passwords." + "message": "Гэтыя ўдзельнікі ўваходзяць у праграму з ненадзейнымі, скампраметаванымі або паўторна выкарыстанымі паролямі." }, "atRiskApplicationsDescription": { - "message": "These applications have weak, exposed, or reused passwords." + "message": "Гэтыя праграмы маюць ненадзейныя, скампраметаваныя або паўторна выкарыстаныя паролі." }, "atRiskMembersDescriptionWithApp": { - "message": "These members are logging into $APPNAME$ with weak, exposed, or reused passwords.", + "message": "Гэтыя ўдзельнікі ўваходзяць у праграму $APPNAME$ з ненадзейнымі, скампраметаванымі або паўторна выкарыстанымі паролямі.", "placeholders": { "appname": { "content": "$1", @@ -147,19 +147,19 @@ } }, "totalMembers": { - "message": "Total members" + "message": "Усяго ўдзельнікаў" }, "atRiskApplications": { - "message": "At-risk applications" + "message": "Праграмы ў зоне рызыкі" }, "totalApplications": { - "message": "Total applications" + "message": "Усяго праграм" }, "unmarkAsCriticalApp": { - "message": "Unmark as critical app" + "message": "Зняць пазнаку крытычнай праграмы" }, "criticalApplicationSuccessfullyUnmarked": { - "message": "Critical application successfully unmarked" + "message": "Пазнака з крытычнай праграмы паспяхова знята" }, "whatTypeOfItem": { "message": "Які гэта элемент запісу?" @@ -260,10 +260,10 @@ "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": { @@ -273,7 +273,7 @@ } }, "showMatchDetection": { - "message": "Show match detection $WEBSITE$", + "message": "Паказаць выяўленне супадзенняў $WEBSITE$", "placeholders": { "website": { "content": "$1", @@ -282,7 +282,7 @@ } }, "hideMatchDetection": { - "message": "Hide match detection $WEBSITE$", + "message": "Схаваць выяўленне супадзенняў $WEBSITE$", "placeholders": { "website": { "content": "$1", @@ -291,7 +291,7 @@ } }, "autoFillOnPageLoad": { - "message": "Autofill on page load?" + "message": "Аўтазапаўняць пры загрузцы старонкі?" }, "number": { "message": "Нумар" @@ -306,7 +306,7 @@ "message": "Код бяспекі (CVV)" }, "securityCodeSlashCVV": { - "message": "Security code / CVV" + "message": "Код бяспекі (CVV)" }, "identityName": { "message": "Імя пасведчання" @@ -384,10 +384,10 @@ "message": "Доктар" }, "cardExpiredTitle": { - "message": "Expired card" + "message": "Картка пратэрмінавана" }, "cardExpiredMessage": { - "message": "If you've renewed it, update the card's information" + "message": "Калі вы падаўжалі картку, то абнавіце яе звесткі" }, "expirationMonth": { "message": "Месяц завяршэння" @@ -399,7 +399,7 @@ "message": "Ключ аўтэнтыфікацыі (TOTP)" }, "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." @@ -464,6 +464,18 @@ "editFolder": { "message": "Рэдагаваць папку" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Асноўны дамен", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "напр.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Ініцыяваны ўваход" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Адправіць" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "Апавяшчэнне было адпраўлена на вашу прыладу." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "Версія $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Паўторна генерыраваць пароль" - }, "length": { "message": "Даўжыня" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Небяспечная зона" }, - "dangerZoneDesc": { - "message": "Асцярожна, гэтыя дзеянні з'яўляюцца незваротнымі!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Скасаваць аўтарызацыю сеанса" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Працягваючы, вы таксама выйдзіце з бягучага сеанса і вам неабходна будзе ўвайсці паўторна. Вы таксама атрымаеце паўторны запыт двухэтапнага ўваходу, калі гэта функцыя ў вас уключана. Сеансы на іншых прыладах могуць заставацца актыўнымі на працягу адной гадзіны." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "Аўтарызацыя ўсіх сеансаў скасавана" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Кіраванне" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Адключыць" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "Праблема чытання ключа бяспекі. Паспрабуйце яшчэ раз." }, - "twoFactorWebAuthnWarning": { - "message": "У сувязі з абмежаваннямі платформы, WebAuthn немагчыма выкарыстоўваць ва ўсіх праграмах Bitwarden. Вам неабходна актываваць іншага пастаўшчыка двухэтапнага ўваходу, каб вы маглі атрымаць доступ да свайго ўліковага запісу, калі немагчыма скарыстацца WebAuthn. Платформы, які падтрымліваюцца:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Вэб-сховішча і пашырэнні браўзера на камп'ютары/ноўтбуку з браўзерам, які падтрымлівае WebAuthn (Chrome, Opera, Vivaldi або Firefox з уключаным FIDO U2F)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Ваш код аднаўлення двухэтапнага ўваходу Bitwarden" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Прызначыць патрабаванні для генератара пароляў." }, - "passwordGeneratorPolicyInEffect": { - "message": "Адна або больш палітык арганізацыі ўплывае на налады генератара." - }, "masterPasswordPolicyInEffect": { "message": "Адна або больш палітык арганізацыі патрабуе, каб ваш асноўны пароль адпавядаў наступным патрабаванням:" }, @@ -6666,15 +6717,6 @@ "message": "Генератар", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "Што вы хочаце генерыраваць?" - }, - "passwordType": { - "message": "Тып пароля" - }, - "regenerateUsername": { - "message": "Паўторна генерыраваць імя карыстальніка" - }, "generateUsername": { "message": "Генерыраваць імя карыстальніка" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Тып імя карыстальніка" - }, "plusAddressedEmail": { "message": "Адрасы электроннай пошты з плюсам", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Выкарыстоўвайце сваю сканфігураваную скрыню для ўсёй пошты дамена." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Выпадкова", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Назва вузла", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "Токен доступу да API" - }, "deviceVerification": { "message": "Праверка прылады" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "Няма калекцый" }, - "canView": { - "message": "Можа праглядаць" - }, - "canViewExceptPass": { - "message": "Можа праглядаць (без пароляў)" - }, - "canEdit": { - "message": "Можа рэдагаваць" - }, - "canEditExceptPass": { - "message": "Можа рэдагаваць (без пароляў)" - }, "noCollectionsAdded": { "message": "Няма дадзеных калекцый" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Мянушка дамена" - }, "alreadyHaveAccount": { "message": "Ужо маеце ўліковы запіс?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/bg/messages.json b/apps/web/src/locales/bg/messages.json index 4101445cc7b..c985e4eb74e 100644 --- a/apps/web/src/locales/bg/messages.json +++ b/apps/web/src/locales/bg/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Редактиране на папка" }, + "newFolder": { + "message": "Нова папка" + }, + "folderName": { + "message": "Име на папката" + }, + "folderHintText": { + "message": "Можете да вложите една папка в друга като въведете името на горната папка, а след това „/“. Пример: Социални/Форуми" + }, + "deleteFolderPermanently": { + "message": "Наистина ли искате да изтриете тази папка окончателно?" + }, "baseDomain": { "message": "Основен домейн", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Име на елемента" }, - "cannotRemoveViewOnlyCollections": { - "message": "Не можете да премахвате колекции с права „Само за преглед“: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "напр.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Вписването е стартирано" }, + "logInRequestSent": { + "message": "Заявката е изпратена" + }, "submit": { "message": "Подаване" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "Към устройството Ви е изпратено известие." }, + "notificationSentDevicePart1": { + "message": "Отключете Битоурден на устройството си или в " + }, + "areYouTryingToAccessYourAccount": { + "message": "Опитвате ли се да получите достъп до акаунта си?" + }, + "accessAttemptBy": { + "message": "Опит за достъп от $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Разрешаване на достъпа" + }, + "denyAccess": { + "message": "Отказване на достъпа" + }, + "notificationSentDeviceAnchor": { + "message": "приложението по уеб" + }, + "notificationSentDevicePart2": { + "message": "Уверете се, че уникалната фраза съвпада с тази по-долу, преди да одобрите." + }, + "notificationSentDeviceComplete": { + "message": "Отключете Битоурден на устройството си. Уверете се, че уникалната фраза съвпада с тази по-долу, преди да одобрите." + }, "aNotificationWasSentToYourDevice": { "message": "Към устройството Ви е изпратено известие" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Уверете се, че регистрацията Ви е отключена и че уникалната фраза съвпада с другото устройство" - }, "versionNumber": { "message": "Версия $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Без нееднозначни знаци", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Друга парола" - }, "length": { "message": "Дължина" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "ОПАСНО" }, - "dangerZoneDesc": { - "message": "Внимание, тези действия са необратими!" - }, - "dangerZoneDescSingular": { - "message": "Внимание, това действие е необратимо!" - }, "deauthorizeSessions": { "message": "Прекратяване на сесии" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Действието ще прекрати и текущата ви сесия, след което ще се наложи отново да се впишете. Ако сте включили двустепенна идентификация, ще се наложи да повторите и нея. Активните сесии на другите устройства може да останат такива до един час." }, + "newDeviceLoginProtection": { + "message": "Вписване от ново устройство" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Изключване на защитата за вписване от ново устройство" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Включване на защитата за вписване от ново устройство" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Продължете по-долу, за да изключите е-писмата за потвърждение, които Битуорден изпраща, когато се вписвате от ново устройство." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Продължете по-долу, за да посочите, че искате Биуорден да изпраща е-писма за потвърждение, когато се вписвате от ново устройство." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "Ако защитата за вписване от ново устройство е изключена, всеки, който знае главната Ви парола, ще може да получи достъп до акаунта Ви от всяко устройство. Ако искате да защитите акаунта си без потвърждение чрез е-поща, настройте двустепенното удостоверяване." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "Промените на защитата за вписване от ново устройство са запазени" + }, "sessionsDeauthorized": { "message": "Всички сесии са прекратени" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Управление" }, - "canManage": { - "message": "Може да управлява" + "manageCollection": { + "message": "Управление на колекцията" + }, + "viewItems": { + "message": "Преглед на елементите" + }, + "viewItemsHidePass": { + "message": "Преглед на елементите, със скрити пароли" + }, + "editItems": { + "message": "Редактиране на елементите" + }, + "editItemsHidePass": { + "message": "Редактиране на елементите, със скрити пароли" }, "disable": { "message": "Изключване" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "Проблем при изчитането на ключа за сигурност. Пробвайте отново." }, - "twoFactorWebAuthnWarning": { - "message": "Поради платформени ограничения устройствата на WebAuthn не могат да се използват с всички приложения на Битуорден. В такъв случай ще трябва да добавите друг доставчик на двустепенно удостоверяване, за да имате достъп до абонамента си, дори когато WebAuthn не работи. Поддържани платформи:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Трезорът по уеб както и разширенията за браузърите с поддръжка на WebAuthn (Chrome, Opera, Vivaldi и Firefox с поддръжка на FIDO U2F)." + "twoFactorWebAuthnWarning1": { + "message": "Поради платформени ограничения устройствата на WebAuthn не могат да се използват с всички приложения на Битуорден. Ще трябва да настроите друг доставчик на двустепенно удостоверяване, за да имате достъп до акаунта си, когато WebAuthn не може да се ползва." }, "twoFactorRecoveryYourCode": { "message": "Код за възстановяване на достъпа до Битуорден при двустепенна идентификация" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Задаване на минимална сила на генератора на пароли." }, - "passwordGeneratorPolicyInEffect": { - "message": "Поне една политика на организация влияе на настройките на генерирането на паролите." - }, "masterPasswordPolicyInEffect": { "message": "Поне една политика на организация има следните изисквания към главната ви парола:" }, @@ -6666,15 +6717,6 @@ "message": "Генератор", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "Какво бихте искали да генерирате?" - }, - "passwordType": { - "message": "Тип парола" - }, - "regenerateUsername": { - "message": "Повторно генериране на потр. име" - }, "generateUsername": { "message": "Генериране на потр. име" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Тип потребителско име" - }, "plusAddressedEmail": { "message": "Адрес на е-поща с плюс", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Use your domain's configured catch-all inbox." }, + "useThisEmail": { + "message": "Използване на тази е-поща" + }, "random": { "message": "Произволно", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Име на сървъра", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "Идентификатор за достъп до API" - }, "deviceVerification": { "message": "Потвърждаване на устройствата" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "Няма колекция" }, - "canView": { - "message": "Може да преглежда" - }, - "canViewExceptPass": { - "message": "Може да преглежда, без пароли" - }, - "canEdit": { - "message": "Може да редактира" - }, - "canEditExceptPass": { - "message": "Може да редактира, без пароли" - }, "noCollectionsAdded": { "message": "Няма добавени колекции" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Ограничаване на изтриването на колекции, така че да може да се извършва само от собствениците и администраторите" }, + "limitItemDeletionDesc": { + "message": "Ограничаване на изтриването на елементи, така че да може да се извършва само от членове с правомощие за управление" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Собствениците и администраторите могат да управляват всички колекции и елементи" }, @@ -8656,9 +8686,6 @@ "message": "Адрес на собствения сървър", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Псевдонимен домейн" - }, "alreadyHaveAccount": { "message": "Вече имате регистрация?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "Нямате достъп за управление на тази колекция." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Липсват правомощия за управление" + "grantManageCollectionWarningTitle": { + "message": "Липсват правомощия за управление на колекции" }, - "grantAddAccessCollectionWarning": { - "message": "Дайте правомощия за управление, за да позволите пълното управление на колекции, включително изтриването им." + "grantManageCollectionWarning": { + "message": "Дайте правомощия за управление на колекциите, за да позволите пълното управление на колекции, включително изтриването им." }, "grantCollectionAccess": { "message": "Дайте права на групи и членове до тази колекция." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Код от описанието" }, + "cannotRemoveViewOnlyCollections": { + "message": "Не можете да премахвате колекции с права „Само за преглед“: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Важно съобщение" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Администраторите вече имат възможността да изтриват акаунтите на членовете, които принадлежат към присвоен домейн." + }, + "deleteManagedUserWarningDesc": { + "message": "Това действие ще изтрие акаунта на члена, включително всички елементи в неговия трезор. Това заменя предишното действие за Премахване." + }, + "deleteManagedUserWarning": { + "message": "Изтриването е ново действие!" + }, + "seatsRemaining": { + "message": "Остават Ви $REMAINING$ от общо $TOTAL$ места в тази организация. Свържете се с доставчика си, ако искате да управлявате абонамента си.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Съществуваща организация" + }, + "selectOrganizationProviderPortal": { + "message": "Изберете организацията, която искате да добавите към своя Портал за доставчици." + }, + "noOrganizations": { + "message": "Няма организации за показване" + }, + "yourProviderSubscriptionCredit": { + "message": "Вашият абонамент за доставчик ще получи кредит за оставащото време в абонамента на организацията, ако има такова." + }, + "doYouWantToAddThisOrg": { + "message": "Искате ли да добавите тази организация към $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Добавена е съществуваща организация" + }, + "assignedExceedsAvailable": { + "message": "Назначените места превишават наличния брой." } } diff --git a/apps/web/src/locales/bn/messages.json b/apps/web/src/locales/bn/messages.json index b8e792b4466..c2b6fdf4671 100644 --- a/apps/web/src/locales/bn/messages.json +++ b/apps/web/src/locales/bn/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "ফোল্ডার সম্পাদনা" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "ভিত্তি ডোমেইন", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "উদাহরণ", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Log in initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Submit" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "সংস্করণ $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Regenerate password" - }, "length": { "message": "Length" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Danger zone" }, - "dangerZoneDesc": { - "message": "Careful, these actions are not reversible!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Deauthorize sessions" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Proceeding will also log you out of your current session, requiring you to log back in. You will also be prompted for two-step login again, if set up. Active sessions on other devices may continue to remain active for up to one hour." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "All sessions deauthorized" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Manage" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Turn off" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "There was a problem reading the security key. Try again." }, - "twoFactorWebAuthnWarning": { - "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used. Supported platforms:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Web vault and browser extensions on a desktop/laptop with a WebAuthn supported browser (Chrome, Opera, Vivaldi, or Firefox with FIDO U2F turned on)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Your Bitwarden two-step login recovery code" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "পাসওয়ার্ড উৎপাদকের কনফিগারেশনের জন্য ন্যূনতম প্রয়োজনীয়তা সেট করুন।" }, - "passwordGeneratorPolicyInEffect": { - "message": "এক বা একাধিক সংস্থার নীতিগুলি আপনার উৎপাদকের সেটিংসকে প্রভাবিত করছে।" - }, "masterPasswordPolicyInEffect": { "message": "One or more organization policies require your master password to meet the following requirements:" }, @@ -6666,15 +6717,6 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Use your domain's configured catch-all inbox." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Random", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Hostname", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API access token" - }, "deviceVerification": { "message": "Device verification" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "No collection" }, - "canView": { - "message": "Can view" - }, - "canViewExceptPass": { - "message": "Can view, except passwords" - }, - "canEdit": { - "message": "Can edit" - }, - "canEditExceptPass": { - "message": "Can edit, except passwords" - }, "noCollectionsAdded": { "message": "No collections added" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domain" - }, "alreadyHaveAccount": { "message": "Already have an account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/bs/messages.json b/apps/web/src/locales/bs/messages.json index 242679272f8..a4750d36eac 100644 --- a/apps/web/src/locales/bs/messages.json +++ b/apps/web/src/locales/bs/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Uredite folder" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Osnovni domen", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "npr.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Log in initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Submit" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "Verzija $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Regenerate password" - }, "length": { "message": "Length" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Danger zone" }, - "dangerZoneDesc": { - "message": "Careful, these actions are not reversible!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Deauthorize sessions" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Proceeding will also log you out of your current session, requiring you to log back in. You will also be prompted for two-step login again, if set up. Active sessions on other devices may continue to remain active for up to one hour." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "All sessions deauthorized" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Manage" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Turn off" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "There was a problem reading the security key. Try again." }, - "twoFactorWebAuthnWarning": { - "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used. Supported platforms:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Web vault and browser extensions on a desktop/laptop with a WebAuthn supported browser (Chrome, Opera, Vivaldi, or Firefox with FIDO U2F turned on)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Your Bitwarden two-step login recovery code" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Set requirements for password generator." }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organization policies are affecting your generator settings." - }, "masterPasswordPolicyInEffect": { "message": "One or more organization policies require your master password to meet the following requirements:" }, @@ -6666,15 +6717,6 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Use your domain's configured catch-all inbox." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Random", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Hostname", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API access token" - }, "deviceVerification": { "message": "Device verification" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "No collection" }, - "canView": { - "message": "Can view" - }, - "canViewExceptPass": { - "message": "Can view, except passwords" - }, - "canEdit": { - "message": "Can edit" - }, - "canEditExceptPass": { - "message": "Can edit, except passwords" - }, "noCollectionsAdded": { "message": "No collections added" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domain" - }, "alreadyHaveAccount": { "message": "Already have an account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/ca/messages.json b/apps/web/src/locales/ca/messages.json index 1eaa7fcea95..b9e8f0f2336 100644 --- a/apps/web/src/locales/ca/messages.json +++ b/apps/web/src/locales/ca/messages.json @@ -3,22 +3,22 @@ "message": "Totes les aplicacions" }, "criticalApplications": { - "message": "Critical applications" + "message": "Aplicacions crítiques" }, "accessIntelligence": { - "message": "Access Intelligence" + "message": "Intel·ligència d'accés" }, "riskInsights": { - "message": "Risk Insights" + "message": "Coneixements de risc" }, "passwordRisk": { - "message": "Password Risk" + "message": "Risc de contrasenya" }, "reviewAtRiskPasswords": { - "message": "Review at-risk passwords (weak, exposed, or reused) across applications. Select your most critical applications to prioritize security actions for your users to address at-risk passwords." + "message": "Reviseu les contrasenyes de risc (febles, exposades o reutilitzades) a totes les aplicacions. Seleccioneu les aplicacions més crítiques per prioritzar les accions de seguretat perquè els usuaris aborden les contrasenyes de risc." }, "dataLastUpdated": { - "message": "Data last updated: $DATE$", + "message": "Última actualització de les dades: $DATE$", "placeholders": { "date": { "content": "$1", @@ -27,19 +27,19 @@ } }, "notifiedMembers": { - "message": "Notified members" + "message": "Membres notificats" }, "revokeMembers": { - "message": "Revoke members" + "message": "Revoca membres" }, "restoreMembers": { - "message": "Restore members" + "message": "Restaura membres" }, "cannotRestoreAccessError": { - "message": "Cannot restore organization access" + "message": "No es pot restaurar l'accés a l'organització" }, "allApplicationsWithCount": { - "message": "All applications ($COUNT$)", + "message": "Totes les aplicacions ($COUNT$)", "placeholders": { "count": { "content": "$1", @@ -48,10 +48,10 @@ } }, "createNewLoginItem": { - "message": "Create new login item" + "message": "Crea un nou element d'inici de sessió" }, "criticalApplicationsWithCount": { - "message": "Critical applications ($COUNT$)", + "message": "Aplicacions crítiques ($COUNT$)", "placeholders": { "count": { "content": "$1", @@ -60,7 +60,7 @@ } }, "notifiedMembersWithCount": { - "message": "Notified members ($COUNT$)", + "message": "Membres notificats ($COUNT$)", "placeholders": { "count": { "content": "$1", @@ -102,13 +102,13 @@ "message": "At-risk passwords" }, "requestPasswordChange": { - "message": "Request password change" + "message": "Sol·licita canvi de contrasenya" }, "totalPasswords": { - "message": "Total passwords" + "message": "Contrasenyes totals" }, "searchApps": { - "message": "Search applications" + "message": "Cerca d'aplicacions" }, "atRiskMembers": { "message": "At-risk members" @@ -147,7 +147,7 @@ } }, "totalMembers": { - "message": "Total members" + "message": "Nombre total de membres" }, "atRiskApplications": { "message": "At-risk applications" @@ -232,7 +232,7 @@ } }, "itemHistory": { - "message": "Item history" + "message": "Historial d'elements" }, "authenticatorKey": { "message": "Clau autenticadora" @@ -432,17 +432,17 @@ "message": "Booleà" }, "cfTypeCheckbox": { - "message": "Checkbox" + "message": "Casella de selecció" }, "cfTypeLinked": { "message": "Enllaçat", "description": "This describes a field that is 'linked' (related) to another field." }, "fieldType": { - "message": "Field type" + "message": "Tipus de camp" }, "fieldLabel": { - "message": "Field label" + "message": "Etiqueta del camp" }, "remove": { "message": "Suprimeix" @@ -464,6 +464,18 @@ "editFolder": { "message": "Edita la carpeta" }, + "newFolder": { + "message": "Carpeta nova" + }, + "folderName": { + "message": "Nom de la carpeta" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Domini base", "description": "Domain name. Example: website.com" @@ -508,7 +520,7 @@ "message": "Genera contrasenya" }, "generatePassphrase": { - "message": "Generate passphrase" + "message": "Genera frase de pas" }, "checkPassword": { "message": "Comprova si la contrasenya ha estat exposada." @@ -611,7 +623,7 @@ "message": "Nota segura" }, "typeSshKey": { - "message": "SSH key" + "message": "Clau SSH" }, "typeLoginPlural": { "message": "Inicis de sessió" @@ -644,7 +656,7 @@ "message": "Nom complet" }, "address": { - "message": "Address" + "message": "Adreça" }, "address1": { "message": "Adreça 1" @@ -689,7 +701,7 @@ "message": "Visualitza l'element" }, "newItemHeader": { - "message": "New $TYPE$", + "message": "Nou $TYPE$", "placeholders": { "type": { "content": "$1", @@ -698,7 +710,7 @@ } }, "editItemHeader": { - "message": "Edit $TYPE$", + "message": "Edita $TYPE$", "placeholders": { "type": { "content": "$1", @@ -707,7 +719,7 @@ } }, "viewItemType": { - "message": "View $ITEMTYPE$", + "message": "Mostra $ITEMTYPE$", "placeholders": { "itemtype": { "content": "$1", @@ -728,15 +740,6 @@ "itemName": { "message": "Nom d'element" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "ex.", "description": "Short abbreviation for 'example'." @@ -761,7 +764,7 @@ } }, "copySuccessful": { - "message": "Copy Successful" + "message": "Còpia correcta" }, "copyValue": { "message": "Copia el valor", @@ -772,11 +775,11 @@ "description": "Copy password to clipboard" }, "copyPassphrase": { - "message": "Copy passphrase", + "message": "Copia frase de pas", "description": "Copy passphrase to clipboard" }, "passwordCopied": { - "message": "Password copied" + "message": "S'ha copiat la contrasenya" }, "copyUsername": { "message": "Copia el nom d'usuari", @@ -795,7 +798,7 @@ "description": "Copy URI to clipboard" }, "copyCustomField": { - "message": "Copy $FIELD$", + "message": "Copia $FIELD$", "placeholders": { "field": { "content": "$1", @@ -804,31 +807,31 @@ } }, "copyWebsite": { - "message": "Copy website" + "message": "Copia el lloc web" }, "copyNotes": { - "message": "Copy notes" + "message": "Copia notes" }, "copyAddress": { - "message": "Copy address" + "message": "Copia l'adreça" }, "copyPhone": { - "message": "Copy phone" + "message": "Copia telèfon" }, "copyEmail": { - "message": "Copy email" + "message": "Copia el correu electrònic" }, "copyCompany": { - "message": "Copy company" + "message": "Copia empresa" }, "copySSN": { - "message": "Copy Social Security number" + "message": "Copia número de la Seguretat Social" }, "copyPassportNumber": { - "message": "Copy passport number" + "message": "Copia el número de passaport" }, "copyLicenseNumber": { - "message": "Copy license number" + "message": "Copia el número de llicència" }, "copyName": { "message": "Copia el nom" @@ -922,7 +925,7 @@ } }, "itemsMovedToOrg": { - "message": "Items moved to $ORGNAME$", + "message": "S'han desplaçat elements a $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -931,7 +934,7 @@ } }, "itemMovedToOrg": { - "message": "Item moved to $ORGNAME$", + "message": "S'ha desplaçat un element a $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -985,25 +988,25 @@ "message": "Nivell d'accés" }, "accessing": { - "message": "Accessing" + "message": "Accedint a" }, "loggedOut": { "message": "Sessió tancada" }, "loggedOutDesc": { - "message": "You have been logged out of your account." + "message": "Heu tancat la sessió del compte." }, "loginExpired": { "message": "La vostra sessió ha caducat." }, "restartRegistration": { - "message": "Restart registration" + "message": "Reinicia el registre" }, "expiredLink": { "message": "Enllaç caducat" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Reinicieu el registre o proveu d'iniciar sessió." }, "youMayAlreadyHaveAnAccount": { "message": "És possible que ja tingueu un compte" @@ -1033,7 +1036,7 @@ "message": "L'inici de sessió amb el dispositiu ha d'estar activat a la configuració de l'aplicació Bitwarden. Necessiteu una altra opció?" }, "needAnotherOptionV1": { - "message": "Need another option?" + "message": "Necessiteu una altra opció?" }, "loginWithMasterPassword": { "message": "Inici de sessió amb contrasenya mestra" @@ -1048,13 +1051,13 @@ "message": "Utilitzeu un mètode d'inici de sessió diferent" }, "logInWithPasskey": { - "message": "Log in with passkey" + "message": "Inicieu sessió amb la clau de pas" }, "useSingleSignOn": { - "message": "Use single sign-on" + "message": "Usa inici de sessió únic" }, "welcomeBack": { - "message": "Welcome back" + "message": "Benvingut/da de nou" }, "invalidPasskeyPleaseTryAgain": { "message": "Clau d'accés no vàlida. Torneu-ho a provar." @@ -1138,7 +1141,7 @@ "message": "Crea un compte" }, "newToBitwarden": { - "message": "New to Bitwarden?" + "message": "Nou a Bitwarden?" }, "setAStrongPassword": { "message": "Estableix una contrasenya segura" @@ -1156,32 +1159,35 @@ "message": "Inicia sessió" }, "logInToBitwarden": { - "message": "Log in to Bitwarden" + "message": "Inicia sessió a Bitwarden" }, "authenticationTimeout": { - "message": "Authentication timeout" + "message": "Temps d'espera d'autenticació" }, "authenticationSessionTimedOut": { - "message": "The authentication session timed out. Please restart the login process." + "message": "La sessió d'autenticació s'ha esgotat. Reinicieu el procés d'inici de sessió." }, "verifyIdentity": { "message": "Verificació de la vostra identitat" }, "weDontRecognizeThisDevice": { - "message": "We don't recognize this device. Enter the code sent to your email to verify your identity." + "message": "No reconeixem aquest dispositiu. Introduïu el codi que us hem enviat al correu electrònic per verificar la identitat." }, "continueLoggingIn": { - "message": "Continue logging in" + "message": "Continua l'inici de sessió" }, "whatIsADevice": { - "message": "What is a device?" + "message": "Què és un dispositiu?" }, "aDeviceIs": { - "message": "A device is a unique installation of the Bitwarden app where you have logged in. Reinstalling, clearing app data, or clearing your cookies could result in a device appearing multiple times." + "message": "Un dispositiu és una instal·lació única de l'aplicació Bitwarden on heu iniciat la sessió. Si torneu a instal·lar, suprimir les dades de l'aplicació o suprimir les galetes, pot ser que un dispositiu aparega diverses vegades." }, "logInInitiated": { "message": "S'ha iniciat la sessió" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Envia" }, @@ -1213,7 +1219,7 @@ "message": "Pista de la contrasenya mestra (opcional)" }, "newMasterPassHint": { - "message": "New master password hint (optional)" + "message": "Pista de la contrasenya mestra (opcional)" }, "masterPassHintLabel": { "message": "Pista de la contrasenya mestra" @@ -1235,16 +1241,16 @@ "message": "Configuració" }, "accountEmail": { - "message": "Account email" + "message": "Correu electrònic del compte" }, "requestHint": { - "message": "Request hint" + "message": "Sol·licita pista" }, "requestPasswordHint": { - "message": "Request password hint" + "message": "Sol·licita pista de la contrasenya" }, "enterYourAccountEmailAddressAndYourPasswordHintWillBeSentToYou": { - "message": "Enter your account email address and your password hint will be sent to you" + "message": "Introduïu l'adreça de correu electrònic del compte i se us enviarà la pista de contrasenya" }, "passwordHint": { "message": "Pista de la contrasenya" @@ -1284,10 +1290,10 @@ "message": "El vostre compte s'ha creat correctament. Ara ja podeu entrar." }, "newAccountCreated2": { - "message": "Your new account has been created!" + "message": "S'ha creat el vostre compte nou!" }, "youHaveBeenLoggedIn": { - "message": "You have been logged in!" + "message": "Heu iniciat sessió!" }, "trialAccountCreated": { "message": "Compte creat amb èxit." @@ -1308,7 +1314,7 @@ "message": "La caixa forta està bloquejada" }, "yourAccountIsLocked": { - "message": "Your account is locked" + "message": "El compte està bloquejat" }, "uuid": { "message": "UUID" @@ -1371,11 +1377,38 @@ "notificationSentDevice": { "message": "S'ha enviat una notificació al vostre dispositiu." }, - "aNotificationWasSentToYourDevice": { - "message": "A notification was sent to your device" + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirmeu l'accés" + }, + "denyAccess": { + "message": "Denega l'accés" + }, + "notificationSentDeviceAnchor": { + "message": "aplicació web" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, + "aNotificationWasSentToYourDevice": { + "message": "S'ha enviat una notificació al vostre dispositiu" }, "versionNumber": { "message": "Versió $VERSION_NUMBER$", @@ -1480,7 +1513,7 @@ "message": "Correu electrònic" }, "emailDescV2": { - "message": "Enter a code sent to your email." + "message": "Introduïu el codi que us hem enviat al correu electrònic." }, "continue": { "message": "Continua" @@ -1661,12 +1694,9 @@ "description": "deprecated. Use avoidAmbiguous instead." }, "avoidAmbiguous": { - "message": "Avoid ambiguous characters", + "message": "Eviteu caràcters ambigus", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Regenera contrasenya" - }, "length": { "message": "Longitud" }, @@ -1702,29 +1732,29 @@ "message": "Inclou número" }, "generatorPolicyInEffect": { - "message": "Enterprise policy requirements have been applied to your generator options.", + "message": "Els requisits de la política empresarial s'han aplicat a les opcions del generador.", "description": "Indicates that a policy limits the credential generator screen." }, "passwordHistory": { "message": "Historial de les contrasenyes" }, "generatorHistory": { - "message": "Generator history" + "message": "Historial del generador" }, "clearGeneratorHistoryTitle": { - "message": "Clear generator history" + "message": "Neteja l'historial del generador" }, "cleargGeneratorHistoryDescription": { - "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + "message": "Si continueu, totes les entrades se suprimiran permanentment de l'historial del generador. Esteu segur que voleu continuar?" }, "noPasswordsInList": { "message": "No hi ha cap contrasenya a llistar." }, "clearHistory": { - "message": "Clear history" + "message": "Neteja l'historial" }, "nothingToShow": { - "message": "Nothing to show" + "message": "Res a mostrar" }, "nothingGeneratedRecently": { "message": "You haven't generated anything recently" @@ -1767,10 +1797,10 @@ "message": "Torneu a iniciar sessió." }, "currentSession": { - "message": "Current session" + "message": "Sessió actual" }, "requestPending": { - "message": "Request pending" + "message": "Sol·licitud pendent" }, "logBackInOthersToo": { "message": "Torneu a iniciar la sessió. Si esteu utilitzant altres aplicacions Bitwarden, tanqueu-les i torneu-les a obrir també." @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Zona perillosa" }, - "dangerZoneDesc": { - "message": "Aneu amb compte, aquestes accions no són reversibles!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Desautoritza sessions" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "El procediment també tancarà la sessió actual, i l'heu de tornar a iniciar. També demanarà iniciar la sessió en dues passes, si està habilitada. Les sessions actives d'altres dispositius poden mantenir-se actives fins a una hora." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "Totes les sessions estan desautoritzades" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Administra" }, - "canManage": { - "message": "Pot gestionar" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edita elements" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Inhabilita" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "Hi ha hagut un problema en llegir la clau de seguretat. Torneu-ho a provar." }, - "twoFactorWebAuthnWarning": { - "message": "A causa de les limitacions de la plataforma, WebAuthn no es pot utilitzar en totes les aplicacions Bitwarden. Heu d’habilitar un altre proveïdor d’inici de sessió en dos passos perquè pugueu accedir al vostre compte quan no es puga utilitzar WebAuthn. Plataformes compatibles:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Caixa forta web i extensions de navegador en un escriptori/portàtil amb un navegador compatible amb WebAuthn (Chrome, Opera, Vivaldi, o Firefox amb FIDO U2F activat)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "El codi de recuperació d'inici de sessió en dues passes de Bitwarden" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Estableix els requisits mínims per a la configuració del generador de contrasenyes." }, - "passwordGeneratorPolicyInEffect": { - "message": "Una o més polítiques d’organització afecten la configuració del generador." - }, "masterPasswordPolicyInEffect": { "message": "Una o més polítiques d’organització requereixen que la vostra contrasenya principal complisca els requisits següents:" }, @@ -6666,15 +6717,6 @@ "message": "Generador", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "Què voleu generar?" - }, - "passwordType": { - "message": "Tipus de contrasenya" - }, - "regenerateUsername": { - "message": "Regenera el nom d'usuari" - }, "generateUsername": { "message": "Genera un nom d'usuari" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Tipus de nom d'usuari" - }, "plusAddressedEmail": { "message": "Adreça amb sufix", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Utilitzeu la safata d'entrada global configurada del vostre domini." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Aleatori", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Nom de l'amfitrió", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "Token d'accés a l'API" - }, "deviceVerification": { "message": "Verificació del dispositiu" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "Cap col·lecció" }, - "canView": { - "message": "Pot veure" - }, - "canViewExceptPass": { - "message": "Pot veure, excepte les contrasenyes" - }, - "canEdit": { - "message": "Pot editar" - }, - "canEditExceptPass": { - "message": "Pot editar, excepte les contrasenyes" - }, "noCollectionsAdded": { "message": "No s'han afegit col·leccions" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Els propietaris i els administradors poden gestionar totes les col·leccions i articles" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alies de domini" - }, "alreadyHaveAccount": { "message": "Ja tens un compte?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "No teniu accés per gestionar aquesta col·lecció." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Concedeix als grups o membres l'accés a aquesta col·lecció." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/cs/messages.json b/apps/web/src/locales/cs/messages.json index ef9d0e5968c..4fa1a50512c 100644 --- a/apps/web/src/locales/cs/messages.json +++ b/apps/web/src/locales/cs/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Upravit složku" }, + "newFolder": { + "message": "Nová složka" + }, + "folderName": { + "message": "Název složky" + }, + "folderHintText": { + "message": "Vnořte složku přidáním názvu nadřazené složky následovaného znakem \"/\". Příklad: Sociální/Fóra" + }, + "deleteFolderPermanently": { + "message": "Opravdu chcete trvale smazat tuto složku?" + }, "baseDomain": { "message": "Základní doména", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Název položky" }, - "cannotRemoveViewOnlyCollections": { - "message": "Nemůžete odebrat kolekce s oprávněními jen pro zobrazení: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "např.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Bylo zahájeno přihlášení" }, + "logInRequestSent": { + "message": "Požadavek odeslán" + }, "submit": { "message": "Odeslat" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "Na Vaše zařízení bylo odesláno oznámení." }, + "notificationSentDevicePart1": { + "message": "Odemknout Bitwarden na Vašem zařízení nebo na " + }, + "areYouTryingToAccessYourAccount": { + "message": "Pokoušíte se získat přístup k Vašemu účtu?" + }, + "accessAttemptBy": { + "message": "Pokus o přístup z $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Potvrdit přístup" + }, + "denyAccess": { + "message": "Zamítnout přístup" + }, + "notificationSentDeviceAnchor": { + "message": "webová aplikace" + }, + "notificationSentDevicePart2": { + "message": "Před schválením se ujistěte, že fráze otisku prstu odpovídá frázi níže." + }, + "notificationSentDeviceComplete": { + "message": "Odemkněte Bitwarden na Vašem zařízení. Před schválením se ujistěte, že fráze otisku prstu odpovídá frázi níže." + }, "aNotificationWasSentToYourDevice": { "message": "Na Vaše zařízení bylo odesláno oznámení" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Ujistěte se, že je Váš trezor odemčen a fráze otisku prstu se shodují s druhým zařízením" - }, "versionNumber": { "message": "Verze $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Nepoužívat zaměnitelné znaky", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Vygenerovat jiné heslo" - }, "length": { "message": "Délka" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Nebezpečná zóna" }, - "dangerZoneDesc": { - "message": "Opatrně. Tyto akce se nedají vrátit!" - }, - "dangerZoneDescSingular": { - "message": "Opatrně, tato akce je nevratná!" - }, "deauthorizeSessions": { "message": "Zrušit autorizaci relací" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Pokud chcete pokračovat, budete také odhlášeni z aktuální relace a bude nutné se znovu přihlásit. Pokud používáte dvoufázové přihlášení, bude také vyžadováno. Aktivní relace na jiných zařízeních mohou nadále zůstat aktivní po dobu až jedné hodiny." }, + "newDeviceLoginProtection": { + "message": "Nové přihlášení do zařízení" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Vypnout ochranu pro přihlášení z nového zařízení" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Zapnout ochranu pro přihlášení z nového zařízení" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Pokračujte níže a vypněte ověřovací e-maily od Bitwardenu, když se přihlásíte z nového zařízení." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Níže postupujte tak, aby Vám Bitwarden zasílal ověřovací e-maily při přihlášení z nového zařízení." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "Pokud je ochrana přihlášení z nového zařízení vypnutá, může kdokoli s Vaším hlavním heslem přistupovat k Vašemu účtu z libovolného zařízení. Chcete-li svůj účet chránit bez ověřovacích e-mailů, nastavte dvoufázové přihlašování." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "Změny ochrany přihlášení z nového zařízení byly uloženy" + }, "sessionsDeauthorized": { "message": "Všechny relace byly zrušeny" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Spravovat" }, - "canManage": { - "message": "Může spravovat" + "manageCollection": { + "message": "Spravovat kolekci" + }, + "viewItems": { + "message": "Zobrazit položky" + }, + "viewItemsHidePass": { + "message": "Zobrazit položky, skrytá hesla" + }, + "editItems": { + "message": "Upravit položky" + }, + "editItemsHidePass": { + "message": "Upravit položky, skrytá hesla" }, "disable": { "message": "Vypnout" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "Při čtení bezpečnostního klíče došlo k potížím. Zkuste to znovu." }, - "twoFactorWebAuthnWarning": { - "message": "Z důvodu omezení platformy nelze WebAuthn použít ve všech aplikacích Bitwarden. Měli byste využít i jiného poskytovatele dvoufaktorového přihlášení, abyste měli přístup ke svému účtu, když nelze použít WebAuthn. Podporované platformy:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Webový trezor a rozšíření pro prohlížeče na počítači/notebooku s podporou WebAuthn (Chrome, Opera, Vivaldi nebo Firefox se zapnutým FIDO U2F)." + "twoFactorWebAuthnWarning1": { + "message": "Z důvodu omezení platformy nelze WebAuthn použít ve všech aplikacích Bitwarden. Měli byste využít i jiného poskytovatele dvoufaktorového přihlášení, abyste měli přístup ke svému účtu, když nelze použít WebAuthn." }, "twoFactorRecoveryYourCode": { "message": "Váš kód pro obnovení dvoufázového přihlášení" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Nastaví požadavky pro generátor hesel." }, - "passwordGeneratorPolicyInEffect": { - "message": "Jedna nebo více zásad organizace ovlivňují nastavení generátoru." - }, "masterPasswordPolicyInEffect": { "message": "Jedna nebo více zásad organizace vyžaduje, aby hlavní heslo splňovalo následující požadavky:" }, @@ -6666,15 +6717,6 @@ "message": "Generátor", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "Co chcete vygenerovat?" - }, - "passwordType": { - "message": "Typ hesla" - }, - "regenerateUsername": { - "message": "Znovu vygenerovat uživatelské jméno" - }, "generateUsername": { "message": "Vygenerovat uživatelské jméno" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Typ uživatelského jména" - }, "plusAddressedEmail": { "message": "E-mailová adresa s plusem", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Použijte nakonfigurovanou univerzální schránku své domény." }, + "useThisEmail": { + "message": "Použít tento e-mail" + }, "random": { "message": "Náhodně", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Název hostitele", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "Přístupový token API" - }, "deviceVerification": { "message": "Ověřování zařízení" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "Žádná kolekce" }, - "canView": { - "message": "Může zobrazit" - }, - "canViewExceptPass": { - "message": "Může zobrazit kromě hesel" - }, - "canEdit": { - "message": "Může upravovat" - }, - "canEditExceptPass": { - "message": "Může upravovat kromě hesel" - }, "noCollectionsAdded": { "message": "Nebyly přidány žádné kolekce" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Omezí mazání kolekce na vlastníky a správce" }, + "limitItemDeletionDesc": { + "message": "Omezit smazání položky na členy s oprávněním ke správě" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Vlastníci a správci mohou spravovat všechny kolekce a předměty" }, @@ -8656,9 +8686,6 @@ "message": "Adresa URL serveru vlastního hostování", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Doména aliasu" - }, "alreadyHaveAccount": { "message": "Už máte účet?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "Nemáte přístup ke správě této kolekce." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Chybějící oprávnění \"Může spravovat\"" + "grantManageCollectionWarningTitle": { + "message": "Chybějící oprávnění pro správu kolekcí" }, - "grantAddAccessCollectionWarning": { - "message": "Udělte oprávnění \"Může spravovat\" pro úplnou správu kolekce, včetně jejího smazání." + "grantManageCollectionWarning": { + "message": "Udělte oprávnění \"Spravovat kolekci\" pro úplnou správu kolekce, včetně jejího smazání." }, "grantCollectionAccess": { "message": "Udělí skupinám nebo členům přístup k této kolekci." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Kód z popisu" }, + "cannotRemoveViewOnlyCollections": { + "message": "Nemůžete odebrat kolekce s oprávněními jen pro zobrazení: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Důležité upozornění" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Správci mají nyní možnost smazat účty členů, které patří k nárokované doméně." + }, + "deleteManagedUserWarningDesc": { + "message": "Tato akce smaže účet uživatele včetně všech jeho položek v trezoru. Tím se nahradí předchozí akce odebrání." + }, + "deleteManagedUserWarning": { + "message": "Smazat je nová akce!" + }, + "seatsRemaining": { + "message": "Máte zbývajících $REMAINING$ uživatelů z $TOTAL$ uživatelů přidělených této organizaci. Kontaktujte svého poskytovatele pro správu předplatného.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existující organizace" + }, + "selectOrganizationProviderPortal": { + "message": "Vyberte organizaci pro přidání do portálu poskytovatele." + }, + "noOrganizations": { + "message": "Žádné organizace k zobrazení" + }, + "yourProviderSubscriptionCredit": { + "message": "Předplatné poskytovatele obdrží kredit za zbývající čas v předplatném organizace." + }, + "doYouWantToAddThisOrg": { + "message": "Chcete přidat tuto organizaci do $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Přidána existující organizace" + }, + "assignedExceedsAvailable": { + "message": "Přiřazení uživatelé překračují dostupné uživatele." } } diff --git a/apps/web/src/locales/cy/messages.json b/apps/web/src/locales/cy/messages.json index 3c5141cdf79..01c4f390ddc 100644 --- a/apps/web/src/locales/cy/messages.json +++ b/apps/web/src/locales/cy/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Edit folder" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Base domain", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "ex.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Log in initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Submit" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "Version $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Regenerate password" - }, "length": { "message": "Length" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Danger zone" }, - "dangerZoneDesc": { - "message": "Careful, these actions are not reversible!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Deauthorize sessions" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Proceeding will also log you out of your current session, requiring you to log back in. You will also be prompted for two-step login again, if set up. Active sessions on other devices may continue to remain active for up to one hour." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "All sessions deauthorized" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Manage" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Turn off" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "There was a problem reading the security key. Try again." }, - "twoFactorWebAuthnWarning": { - "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used. Supported platforms:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Web vault and browser extensions on a desktop/laptop with a WebAuthn supported browser (Chrome, Opera, Vivaldi, or Firefox with FIDO U2F turned on)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Your Bitwarden two-step login recovery code" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Set requirements for password generator." }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organization policies are affecting your generator settings." - }, "masterPasswordPolicyInEffect": { "message": "One or more organization policies require your master password to meet the following requirements:" }, @@ -6666,15 +6717,6 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Use your domain's configured catch-all inbox." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Random", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Hostname", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API access token" - }, "deviceVerification": { "message": "Device verification" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "No collection" }, - "canView": { - "message": "Can view" - }, - "canViewExceptPass": { - "message": "Can view, except passwords" - }, - "canEdit": { - "message": "Can edit" - }, - "canEditExceptPass": { - "message": "Can edit, except passwords" - }, "noCollectionsAdded": { "message": "No collections added" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domain" - }, "alreadyHaveAccount": { "message": "Already have an account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/da/messages.json b/apps/web/src/locales/da/messages.json index 4f05af78def..bd357b4cba4 100644 --- a/apps/web/src/locales/da/messages.json +++ b/apps/web/src/locales/da/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Redigér mappe" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Basisdomæne", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Emnenavn" }, - "cannotRemoveViewOnlyCollections": { - "message": "Samlinger med kun tilladelsen Vis kan ikke fjernes: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "eks.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Indlogning påbegyndt" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Indsend" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "En notifikation er sendt til din enhed." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "En notifikation er sendt til enheden" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Sørg for, at boksen er oplåst, samt at fingeraftrykssætningen matcher på den anden enhed" - }, "versionNumber": { "message": "Version $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Undgå tvetydige tegn", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Regenerér adgangskode" - }, "length": { "message": "Længde" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Farezone" }, - "dangerZoneDesc": { - "message": "Pas på, disse handlinger er irreversible!" - }, - "dangerZoneDescSingular": { - "message": "Forsigtig, denne handling er irreversibel!" - }, "deauthorizeSessions": { "message": "Fjern sessionsgodkendelser" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Fortsættes, logges man også ud af denne session og vil skulle logge ind igen. Der anmodes også om totrins-login igen, såfremt funktionen er opsat. Aktive sessioner på andre enheder kan forblive aktive i op til én time." }, + "newDeviceLoginProtection": { + "message": "Nyt enheds-login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Slå nyt enheds-login beskyttelse fra" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Slå nyt enheds-login beskyttelse til" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Fortsæt nedenfor for at deaktivere Bitwarden-bekræftelsesmails ved indlogning fra en ny enhed." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Fortsæt nedenfor for at få tilsendt Bitwarden-bekræftelsesmails ved indlogning fra en ny enhed." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "Med den nye enheds-login beskyttelse slået fra kan alle med hovedadgangskoden tilgå brugerkontoen fra enhver enhed. For at beskytte brugerkontoen uden bekræftelsesmails, opsæt totrins-login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "Ændringer i ny enheds-login beskyttelse er gemt" + }, "sessionsDeauthorized": { "message": "Godkendelser for alle sessioner fjernet" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Håndtér" }, - "canManage": { - "message": "Kan håndtere" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Deaktivér" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "Problem med at læse sikkerhedsnøglen. Forsøg igen." }, - "twoFactorWebAuthnWarning": { - "message": "Grundet platformsbegrænsninger kan WebAuthn ikke bruges i alle Bitwarden-applikationer. Man bør opsætte en anden totrins-loginudbyder, så man kan tilgå sin konto, når WebAuthn ikke kan benyttes. Understøttede platforme:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Web-boks og browserudvidelser på en stationær/bærbar computer med en WebAuthn-aktiveret browser (Chrome, Opera, Vivaldi eller Firefox med FIDO U2F aktiveret)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Gendannelseskoden til Bitwarden totrins-login" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Angiv krav til adgangskodegenerator." }, - "passwordGeneratorPolicyInEffect": { - "message": "Én eller flere organisationspolitikker påvirker dine generatorindstillinger." - }, "masterPasswordPolicyInEffect": { "message": "Én eller flere organisationspolitikker kræver din hovedadgangskode opfylder følgende krav:" }, @@ -6666,15 +6717,6 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "Hvad ønskes genereret?" - }, - "passwordType": { - "message": "Adgangskodetype" - }, - "regenerateUsername": { - "message": "Regenerér brugernavn" - }, "generateUsername": { "message": "Generér brugernavn" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Brugernavnstype" - }, "plusAddressedEmail": { "message": "Plus adresseret e-mail", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Brug den for domænet opsatte Fang-alle indbakke." }, + "useThisEmail": { + "message": "Benyt denne e-mail" + }, "random": { "message": "Tilfældig", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Værtsnavn", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API-adgangstoken" - }, "deviceVerification": { "message": "Enhedsbekræftelse" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "Ingen samling" }, - "canView": { - "message": "Kan se" - }, - "canViewExceptPass": { - "message": "Kan se, undtagen adgangskoder" - }, - "canEdit": { - "message": "Kan redigere" - }, - "canEditExceptPass": { - "message": "Kan redigere, undtagen adgangskoder" - }, "noCollectionsAdded": { "message": "Ingen samlinger tilføjet" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Begræns samlingsslettelse til ejere og admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Ejere og admins kan håndtere alle samlinger og emner" }, @@ -8656,9 +8686,6 @@ "message": "URL til selv-hostet server", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Aliasdomæne" - }, "alreadyHaveAccount": { "message": "Har allerede en konto?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "Du har ikke adgang til at håndtere denne samling." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Manglende Kan håndtere tilladelser" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Tildel Kan håndtere tilladelser for at tillade fuld samlingshåndtering, herunder sletning af samling." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Tildel grupper eller medlemmer adgang til denne samling." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Beskrivelseskode" }, + "cannotRemoveViewOnlyCollections": { + "message": "Samlinger med kun tilladelsen Vis kan ikke fjernes: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Vigtig notits" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/de/messages.json b/apps/web/src/locales/de/messages.json index 4f250187b74..ffc65be543c 100644 --- a/apps/web/src/locales/de/messages.json +++ b/apps/web/src/locales/de/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Ordner bearbeiten" }, + "newFolder": { + "message": "Neuer Ordner" + }, + "folderName": { + "message": "Ordnername" + }, + "folderHintText": { + "message": "Verschachtel einen Ordner, indem du den Namen des übergeordneten Ordners hinzufügst, gefolgt von einem „/“. Beispiel: Sozial/Foren" + }, + "deleteFolderPermanently": { + "message": "Bist du sicher, dass du diesen Ordner dauerhaft löschen willst?" + }, "baseDomain": { "message": "Basisdomäne", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Eintrags-Name" }, - "cannotRemoveViewOnlyCollections": { - "message": "Du kannst Sammlungen mit Leseberechtigung nicht entfernen: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "Bsp.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Anmeldung eingeleitet" }, + "logInRequestSent": { + "message": "Anfrage gesendet" + }, "submit": { "message": "Absenden" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "Eine Benachrichtigung wurde an dein Gerät gesendet." }, + "notificationSentDevicePart1": { + "message": "Entsperre Bitwarden auf deinem Gerät oder mit der " + }, + "areYouTryingToAccessYourAccount": { + "message": "Versuchst du auf dein Konto zuzugreifen?" + }, + "accessAttemptBy": { + "message": "Zugriffsversuch von $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Zugriff bestätigen" + }, + "denyAccess": { + "message": "Zugriff ablehnen" + }, + "notificationSentDeviceAnchor": { + "message": "Web-App" + }, + "notificationSentDevicePart2": { + "message": "Stelle vor der Genehmigung sicher, dass die Fingerabdruck-Phrase mit der unten stehenden übereinstimmt." + }, + "notificationSentDeviceComplete": { + "message": "Entsperre Bitwarden auf deinem Gerät. Stelle vor der Genehmigung sicher, dass die Fingerabdruck-Phrase mit der unten stehenden übereinstimmt." + }, "aNotificationWasSentToYourDevice": { "message": "Eine Benachrichtigung wurde an dein Gerät gesendet" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Stelle sicher, dass dein Konto entsperrt ist und die Fingerabdruck-Phrase mit der vom anderen Gerät übereinstimmt" - }, "versionNumber": { "message": "Version $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Mehrdeutige Zeichen vermeiden", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Passwort neu generieren" - }, "length": { "message": "Länge" }, @@ -1839,21 +1869,36 @@ "dangerZone": { "message": "Gefahrenzone" }, - "dangerZoneDesc": { - "message": "Vorsicht, diese Aktionen sind nicht umkehrbar!" - }, - "dangerZoneDescSingular": { - "message": "Vorsicht, diese Aktion ist nicht mehr rückgängig zu machen!" - }, "deauthorizeSessions": { "message": "Sitzungen abmelden" }, "deauthorizeSessionsDesc": { - "message": "Bist du besorgt, dass dein Konto auf einem anderen Gerät angemeldet ist? Fahre unten fort, um alle Computer oder Geräte, die du zuvor verwendet hast, zu deaktivieren. Dieser Sicherheitsschritt wird empfohlen, wenn du zuvor einen öffentlichen Computer verwendet oder dein Passwort versehentlich auf einem Gerät gespeichert hast, das dir nicht gehört. Dieser Schritt löscht auch alle zuvor gespeicherten zweistufigen Anmeldesitzungen." + "message": "Bist du besorgt, dass dein Konto auf einem anderen Gerät angemeldet ist? Fahre unten fort, um dich von allen Computern oder Geräten, die du zuvor verwendet hast, abzumelden. Dieser Sicherheitsschritt wird empfohlen, wenn du zuvor einen öffentlichen Computer verwendet oder dein Passwort versehentlich auf einem Gerät gespeichert hast, das dir nicht gehört. Dieser Schritt löscht auch alle zuvor gespeicherten zweistufigen Anmeldesitzungen." }, "deauthorizeSessionsWarning": { "message": "Wenn du fortfährst, wirst du auch von deiner aktuellen Sitzung abgemeldet, so dass du dich erneut anmelden musst. Du wirst auch aufgefordert, dich erneut in zwei Schritten anzumelden, falls dies eingerichtet ist. Aktive Sitzungen auf anderen Geräten können noch bis zu einer Stunde lang aktiv bleiben." }, + "newDeviceLoginProtection": { + "message": "Neue Geräteanmeldung" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Neuen Geräte-Anmeldeschutz deaktivieren" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Neuen Geräte-Anmeldeschutz aktivieren" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Fahre unten fort, um die Verifizierungs-E-Mails von Bitwarden zu deaktivieren, wenn du dich von einem neuen Gerät aus anmeldest." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Fahre unten fort, um Verifizierungs-E-Mails von Bitwarden zu erhalten, wenn du dich von einem neuen Gerät aus anmeldest." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "Wenn der neue Geräte-Anmeldeschutz ausgeschaltet ist, kann jeder mit deinem Master-Passwort von jedem Gerät aus auf dein Konto zugreifen. Um dein Konto ohne Verifizierungs-E-Mails zu schützen, richte die Zwei-Faktor-Authentifizierung ein." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "Änderungen am neuen Geräte-Anmeldeschutz gespeichert" + }, "sessionsDeauthorized": { "message": "Alle Sitzungen wurden abgemeldet" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Verwalten" }, - "canManage": { - "message": "Darf verwalten" + "manageCollection": { + "message": "Sammlung verwalten" + }, + "viewItems": { + "message": "Einträge anzeigen" + }, + "viewItemsHidePass": { + "message": "Einträge anzeigen, versteckte Passwörter" + }, + "editItems": { + "message": "Einträge bearbeiten" + }, + "editItemsHidePass": { + "message": "Einträge bearbeiten, versteckte Passwörter" }, "disable": { "message": "Deaktivieren" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "Es gab ein Problem beim Lesen des Sicherheitsschlüssels, bitte versuche es erneut." }, - "twoFactorWebAuthnWarning": { - "message": "Aufgrund von Plattformbeschränkungen kann WebAuthn nicht in allen Bitwarden-Anwendungen verwendet werden. Du solltest einen anderen Zwei-Faktor-Authentifizierungsanbieter aktivieren, damit du auf dein Konto zugreifen kannst, wenn WebAuthn nicht verwendet werden kann. Unterstützte Plattformen:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Web-Tresor und Browser-Erweiterungen auf einem Desktop/Laptop mit einem WebAuthn-fähigen Browser (Chrome, Opera, Vivaldi oder Firefox mit aktiviertem FIDO U2F)." + "twoFactorWebAuthnWarning1": { + "message": "Aufgrund von Plattformbeschränkungen kann WebAuthn nicht in allen Bitwarden-Anwendungen verwendet werden. Du solltest einen anderen Zwei-Faktor-Authentifizierungsanbieter einrichten, damit du auf dein Konto zugreifen kannst, wenn WebAuthn nicht verwendet werden kann." }, "twoFactorRecoveryYourCode": { "message": "Ihr Wiederherstellungsschlüssel für die Zwei-Faktor-Anmeldung in Bitwarden" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Mindestanforderungen für den Passwort-Generator festlegen." }, - "passwordGeneratorPolicyInEffect": { - "message": "Eine oder mehrere Organisationsrichtlinien beeinflussen deine Generator-Einstellungen." - }, "masterPasswordPolicyInEffect": { "message": "Eine oder mehrere Organisationsrichtlinien erfordern, dass dein Master-Passwort die folgenden Anforderungen erfüllt:" }, @@ -6666,15 +6717,6 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "Was möchtest du generieren?" - }, - "passwordType": { - "message": "Passworttyp" - }, - "regenerateUsername": { - "message": "Benutzername neu generieren" - }, "generateUsername": { "message": "Benutzername generieren" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Benutzernamenstyp" - }, "plusAddressedEmail": { "message": "Plus-adressierte E-Mail-Adresse", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Verwende den konfigurierten Catch-All-Posteingang deiner Domain." }, + "useThisEmail": { + "message": "Diese E-Mail-Adresse verwenden" + }, "random": { "message": "Zufällig", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Hostname", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API-Zugriffstoken" - }, "deviceVerification": { "message": "Geräteverifizierung" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "Keine Sammlung" }, - "canView": { - "message": "Darf anzeigen" - }, - "canViewExceptPass": { - "message": "Darf anzeigen, Passwörter ausgenommen" - }, - "canEdit": { - "message": "Darf bearbeiten" - }, - "canEditExceptPass": { - "message": "Darf bearbeiten, Passwörter ausgenommen" - }, "noCollectionsAdded": { "message": "Keine Sammlungen hinzugefügt" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Das Löschen von Sammlungen auf Eigentümer und Administratoren beschränken" }, + "limitItemDeletionDesc": { + "message": "Löschung von Einträgen auf Mitglieder mit der \"Darf verwalten\"-Berechtigung beschränken" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Besitzer und Administratoren können alle Sammlungen und Einträge verwalten" }, @@ -8656,9 +8686,6 @@ "message": "Selbst gehostete Server-URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias-Domain" - }, "alreadyHaveAccount": { "message": "Hast du bereits ein Konto?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "Du hast keinen Zugriff zur Verwaltung dieser Sammlung." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Fehlende \"Darf verwalten\"-Berechtigungen" + "grantManageCollectionWarningTitle": { + "message": "Berechtigungen zur Verwaltung von Sammlungen fehlen" }, - "grantAddAccessCollectionWarning": { - "message": "\"Darf verwalten\"-Berechtigungen gewähren, um die vollständige Sammlungsverwaltung einschließlich der Löschung von Sammlungen zu ermöglichen." + "grantManageCollectionWarning": { + "message": "Berechtigungen zur Verwaltung von Sammlungen gewähren, um die vollständige Verwaltung von Sammlungen, einschließlich der Löschung von Sammlungen, zu erlauben." }, "grantCollectionAccess": { "message": "Gewähre Gruppen oder Mitgliedern Zugriff auf diese Sammlung." @@ -9286,7 +9313,7 @@ "message": "Monat pro Mitglied" }, "monthPerMemberBilledAnnually": { - "message": "month per member billed annually" + "message": "Monat pro Mitglied jährlich in Rechnung gestellt" }, "seats": { "message": "Benutzerplätze" @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Beschreibungscode" }, + "cannotRemoveViewOnlyCollections": { + "message": "Du kannst Sammlungen mit Leseberechtigung nicht entfernen: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Wichtiger Hinweis" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administratoren haben nun die Möglichkeit, Mitgliedskonten, die zu einer beanspruchten Domain gehören, zu löschen." + }, + "deleteManagedUserWarningDesc": { + "message": "Diese Aktion löscht das Mitgliedskonto, einschließlich aller Einträge in seinem Tresor. Dies ersetzt die vorherige Entfernen-Aktion." + }, + "deleteManagedUserWarning": { + "message": "Löschen ist eine neue Aktion!" + }, + "seatsRemaining": { + "message": "Du hast $REMAINING$ Plätze von $TOTAL$ dieser Organisation zugewiesenen Plätzen verfügbar. Kontaktiere deinen Anbieter, um dein Abonnement zu verwalten.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Vorhandene Organisation" + }, + "selectOrganizationProviderPortal": { + "message": "Wähle eine Organisation aus, um sie deinem Anbieterportal hinzuzufügen." + }, + "noOrganizations": { + "message": "Keine Sammlungen vorhanden" + }, + "yourProviderSubscriptionCredit": { + "message": "Dein Anbieterabonnement erhält ein Guthaben für jede verbleibende Zeit im Abonnement der Organisation." + }, + "doYouWantToAddThisOrg": { + "message": "Möchtest du diese Organisation zu $PROVIDER$ hinzufügen?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Vorhandene Organisation hinzugefügt" + }, + "assignedExceedsAvailable": { + "message": "Die zugewiesenen Plätze überschreiten die verfügbaren Plätze." } } diff --git a/apps/web/src/locales/el/messages.json b/apps/web/src/locales/el/messages.json index e13bd4ee5ea..ea5f11e9162 100644 --- a/apps/web/src/locales/el/messages.json +++ b/apps/web/src/locales/el/messages.json @@ -3,22 +3,22 @@ "message": "Όλες οι εφαρμογές" }, "criticalApplications": { - "message": "Critical applications" + "message": "Κρίσιμες εφαρμογές" }, "accessIntelligence": { - "message": "Access Intelligence" + "message": "Πληροφορίες Πρόσβασης" }, "riskInsights": { - "message": "Risk Insights" + "message": "Insights Κινδύνου" }, "passwordRisk": { - "message": "Password Risk" + "message": "Ρίσκος Κωδικού Πρόσβασης" }, "reviewAtRiskPasswords": { - "message": "Review at-risk passwords (weak, exposed, or reused) across applications. Select your most critical applications to prioritize security actions for your users to address at-risk passwords." + "message": "Ελέξτε τους κωδικούς πρόσβασης (αδύναμους, εκτεθειμένους ή επαναχρησιμοποιούμενους) σε όλες τις εφαρμογές. Επιλέξτε τις πιο κρίσιμες εφαρμογές σας για να δώσετε προτεραιότητα στις ενέργειες ασφαλείας για τους χρήστες σας ώστε να αντιμετωπίσουν τους εκτεθειμένους κωδικούς πρόσβασης." }, "dataLastUpdated": { - "message": "Data last updated: $DATE$", + "message": "Τελευταία ενημέρωση δεδομένων: $DATE$", "placeholders": { "date": { "content": "$1", @@ -464,6 +464,18 @@ "editFolder": { "message": "Επεξεργασία Φακέλου" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Βασικός τομέας", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Όνομα αντικειμένου" }, - "cannotRemoveViewOnlyCollections": { - "message": "Δεν μπορείτε να αφαιρέσετε συλλογές που έχουν μόνο δικαιώματα Προβολής: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "πχ.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Η σύνδεση ξεκίνησε" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Υποβολή" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "Μια ειδοποίηση έχει σταλεί στη συσκευή σας." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "Έκδοση $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Επαναδημιουργία Κωδικού" - }, "length": { "message": "Μήκος" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Επικίνδυνη Ζώνη" }, - "dangerZoneDesc": { - "message": "Προσοχή, αυτές οι ενέργειες είναι μη αναστρέψιμες!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Κατάργηση Εξουσιοδότησης Συνεδριών" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Η διαδικασία θα σας αποσυνδέσει από την τρέχουσα συνεδρία και θα σας ζητήσει να συνδεθείτε ξανά. Οι ενεργές συνεδρίες σε άλλες συσκευές ενδέχεται να παραμείνουν ενεργοποιημένες για έως και μία ώρα." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "Η Ανακληθεί η Πρόσβαση από Όλες τις Συνεδρίες" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Διαχείριση" }, - "canManage": { - "message": "Δυνατότητα διαχείρισης" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Απενεργοποίηση" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "Παρουσιάστηκε πρόβλημα κατά την ανάγνωση του κλειδιού ασφαλείας. Προσπάθησε ξανά." }, - "twoFactorWebAuthnWarning": { - "message": "Λόγω περιορισμών της πλατφόρμας, το WebAuthn δεν μπορεί να χρησιμοποιηθεί σε όλες τις εφαρμογές Bitwarden. Θα πρέπει να ενεργοποιήσετε έναν άλλο πάροχο σύνδεσης δύο βημάτων, ώστε να έχετε πρόσβαση στο λογαριασμό σας όταν δεν μπορεί να χρησιμοποιηθεί το WebAuthn. Υποστηριζόμενες πλατφόρμες:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Web vault και επεκτάσεις browser σε έναν σταθερό / φορητό υπολογιστή με ένα πρόγραμμα περιήγησης WebAuthn (Chrome, Opera, Vivaldi, ή Firefox με FIDO U2F ενεργοποιημένο)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Ο Bitwarden κωδικός ανάκτησης, εισόδου δύο βημάτων" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Ελάχιστες απαιτήσεις διαμόρφωσης γεννήτριας κωδικών." }, - "passwordGeneratorPolicyInEffect": { - "message": "Μία ή περισσότερες πολιτικές του οργανισμού επηρεάζουν τις ρυθμίσεις της γεννήτριας." - }, "masterPasswordPolicyInEffect": { "message": "Σε μία ή περισσότερες πολιτικές του οργανισμού απαιτείται ο κύριος κωδικός να πληρεί τις ακόλουθες απαιτήσεις:" }, @@ -6666,15 +6717,6 @@ "message": "Γεννήτρια", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "Τι θα θέλατε να δημιουργήσετε;" - }, - "passwordType": { - "message": "Τύπος Κωδικού" - }, - "regenerateUsername": { - "message": "Επαναδημιουργία Ονόματος Χρήστη" - }, "generateUsername": { "message": "Δημιουργία Ονόματος Χρήστη" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Τύπος Ονόματος Χρήστη" - }, "plusAddressedEmail": { "message": "Συν Διεύθυνση Email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Χρησιμοποιήστε τα διαμορφωμένα εισερχόμενα catch-all του domain σας." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Τυχαίο", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Όνομα κεντρικού υπολογιστή", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "Διακριτικό πρόσβασης API" - }, "deviceVerification": { "message": "Επαλήθευση συσκευής" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "Καμία συλλογή" }, - "canView": { - "message": "Δυνατότητα προβολής" - }, - "canViewExceptPass": { - "message": "Δυνατότητα προβολής, εκτός των κωδικών πρόσβασης" - }, - "canEdit": { - "message": "Δυνατότητα επεξεργασίας" - }, - "canEditExceptPass": { - "message": "Δυνατότητα επεξεργασίας, εκτός των κωδικών πρόσβασης" - }, "noCollectionsAdded": { "message": "Δεν προστέθηκαν συλλογές" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Οι ιδιοκτήτες και οι διαχειριστές μπορούν να διαχειριστούν όλες τις συλλογές και τα στοιχεία" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Ψευδώνυμο τομέα" - }, "alreadyHaveAccount": { "message": "Έχετε ήδη λογαριασμό;" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "Δεν έχετε πρόσβαση για να διαχειριστείτε αυτήν τη συλλογή." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "Δεν μπορείτε να αφαιρέσετε συλλογές που έχουν μόνο δικαιώματα Προβολής: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index fa81a80385b..0f48595f09b 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -485,6 +485,18 @@ "editFolder": { "message": "Edit folder" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Base domain", "description": "Domain name. Example: website.com" @@ -749,15 +761,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "ex.", "description": "Short abbreviation for 'example'." @@ -1203,6 +1206,9 @@ "logInInitiated": { "message": "Log in initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Submit" }, @@ -1392,12 +1398,39 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "Version $VERSION_NUMBER$", "placeholders": { @@ -1685,9 +1718,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Regenerate password" - }, "length": { "message": "Length" }, @@ -2191,8 +2221,20 @@ "manage": { "message": "Manage" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Turn off" @@ -2389,11 +2431,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "There was a problem reading the security key. Try again." }, - "twoFactorWebAuthnWarning": { - "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used. Supported platforms:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Web vault and browser extensions on a desktop/laptop with a WebAuthn supported browser (Chrome, Opera, Vivaldi, or Firefox with FIDO U2F turned on)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Your Bitwarden two-step login recovery code" @@ -4731,9 +4770,6 @@ "passwordGeneratorPolicyDesc": { "message": "Set requirements for password generator." }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organization policies are affecting your generator settings." - }, "masterPasswordPolicyInEffect": { "message": "One or more organization policies require your master password to meet the following requirements:" }, @@ -6702,15 +6738,6 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -6751,9 +6778,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6973,9 +6997,6 @@ "message": "Hostname", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API access token" - }, "deviceVerification": { "message": "Device verification" }, @@ -7687,18 +7708,6 @@ "noCollection": { "message": "No collection" }, - "canView": { - "message": "Can view" - }, - "canViewExceptPass": { - "message": "Can view, except passwords" - }, - "canEdit": { - "message": "Can edit" - }, - "canEditExceptPass": { - "message": "Can edit, except passwords" - }, "noCollectionsAdded": { "message": "No collections added" }, @@ -8646,6 +8655,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8695,9 +8707,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domain" - }, "alreadyHaveAccount": { "message": "Already have an account?" }, @@ -8759,11 +8768,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10113,6 +10122,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10303,5 +10321,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification" : { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/en_GB/messages.json b/apps/web/src/locales/en_GB/messages.json index 82035102328..24aa0b675ab 100644 --- a/apps/web/src/locales/en_GB/messages.json +++ b/apps/web/src/locales/en_GB/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Edit folder" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Base domain", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "e.g.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Log in initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Submit" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "Version $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Regenerate password" - }, "length": { "message": "Length" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Danger zone" }, - "dangerZoneDesc": { - "message": "Careful, these actions are not reversible!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Deauthorise sessions" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Proceeding will also log you out of your current session, requiring you to log back in. You will also be prompted for two-step login again, if set up. Active sessions on other devices may continue to remain active for up to one hour." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails Bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have Bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "All sessions deauthorised" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Manage" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Turn off" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "There was a problem reading the security key. Try again." }, - "twoFactorWebAuthnWarning": { - "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used. Supported platforms:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Web vault and browser extensions on a desktop/laptop with a WebAuthn supported browser (Chrome, Opera, Vivaldi, or Firefox with FIDO U2F turned on)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Your Bitwarden two-step login recovery code" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Set requirements for password generator." }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organisation policies are affecting your generator settings." - }, "masterPasswordPolicyInEffect": { "message": "One or more organisation policies require your master password to meet the following requirements:" }, @@ -6666,15 +6717,6 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Use your domain's configured catch-all inbox." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Random", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Hostname", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API access token" - }, "deviceVerification": { "message": "Device verification" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "No collection" }, - "canView": { - "message": "Can view" - }, - "canViewExceptPass": { - "message": "Can view, except passwords" - }, - "canEdit": { - "message": "Can edit" - }, - "canEditExceptPass": { - "message": "Can edit, except passwords" - }, "noCollectionsAdded": { "message": "No collections added" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domain" - }, "alreadyHaveAccount": { "message": "Already have an account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organisation. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organisation" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organisation to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organisations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organisation's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organisation to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organisation" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/en_IN/messages.json b/apps/web/src/locales/en_IN/messages.json index 40ca8bf14ed..f4e4756b393 100644 --- a/apps/web/src/locales/en_IN/messages.json +++ b/apps/web/src/locales/en_IN/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Edit folder" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Base domain", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "e.g.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Log in initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Submit" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "Version $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Regenerate password" - }, "length": { "message": "Length" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Danger zone" }, - "dangerZoneDesc": { - "message": "Careful, these actions are not reversible!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Deauthorise sessions" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Proceeding will also log you out of your current session, requiring you to log back in. You will also be prompted for two-step login again, if enabled. Active sessions on other devices may continue to remain active for up to one hour." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails Bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have Bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "All sessions deauthorised" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Manage" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Disable" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "There was a problem reading the security key. Try again." }, - "twoFactorWebAuthnWarning": { - "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should enable another two-step login provider so that you can access your account when WebAuthn cannot be used. Supported platforms:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Web vault and browser extensions on a desktop/laptop with a WebAuthn enabled browser (Chrome, Opera, Vivaldi, or Firefox with FIDO U2F enabled)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Your Bitwarden two-step login recovery code" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Set minimum requirements for password generator configuration." }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organisation policies are affecting your generator settings." - }, "masterPasswordPolicyInEffect": { "message": "One or more organisation policies require your master password to meet the following requirements:" }, @@ -6666,15 +6717,6 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Use your domain's configured catch-all inbox." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Random", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Hostname", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API access token" - }, "deviceVerification": { "message": "Device verification" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "No collection" }, - "canView": { - "message": "Can view" - }, - "canViewExceptPass": { - "message": "Can view, except passwords" - }, - "canEdit": { - "message": "Can edit" - }, - "canEditExceptPass": { - "message": "Can edit, except passwords" - }, "noCollectionsAdded": { "message": "No collections added" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domain" - }, "alreadyHaveAccount": { "message": "Already have an account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organisation. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organisation" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organisation to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organisations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organisation's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organisation to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organisation" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/eo/messages.json b/apps/web/src/locales/eo/messages.json index 574e483d97a..a864ee99590 100644 --- a/apps/web/src/locales/eo/messages.json +++ b/apps/web/src/locales/eo/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Redakti dosierujon" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Baza domajno", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "ekz.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Log in initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Sendu" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "Versio $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Regeneri Pasvorton" - }, "length": { "message": "Longo" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Danĝera Zono" }, - "dangerZoneDesc": { - "message": "Atentu, ĉi tiuj agoj ne estas reigeblaj!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Senrajtigi Sesiojn" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Se vi daŭrigos vian adiaŭadon de la nuna seanco, necesos vin saluti denove. Oni ankaŭ demandos de vi du-faktoran aŭtentigon, se tiu elekteblo estas ebligita. La seancoj aktivaj sur aliaj aparatoj povas resti daŭre aktivaj ankoraŭ unu horon." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "Ĉiuj Sesioj Neaŭtorizitaj" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Administri" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Neebligi" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "There was a problem reading the security key. Try again." }, - "twoFactorWebAuthnWarning": { - "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used. Supported platforms:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Web vault and browser extensions on a desktop/laptop with a WebAuthn supported browser (Chrome, Opera, Vivaldi, or Firefox with FIDO U2F turned on)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Via kodo de senpaneigo de du-ŝtupa saluto de Bitwarden" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Agordi minimumajn postulojn por agordi pasvortan generilon." }, - "passwordGeneratorPolicyInEffect": { - "message": "Unu aŭ pluraj organizaj politikoj influas viajn generatorajn agordojn." - }, "masterPasswordPolicyInEffect": { "message": "Unu aŭ pluraj organizaj politikoj postulas vian ĉefan pasvorton por plenumi la jenajn postulojn:" }, @@ -6666,15 +6717,6 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Use your domain's configured catch-all inbox." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Hazarda", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Domajna nomo", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API access token" - }, "deviceVerification": { "message": "Device verification" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "No collection" }, - "canView": { - "message": "Can view" - }, - "canViewExceptPass": { - "message": "Can view, except passwords" - }, - "canEdit": { - "message": "Can edit" - }, - "canEditExceptPass": { - "message": "Can edit, except passwords" - }, "noCollectionsAdded": { "message": "No collections added" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domain" - }, "alreadyHaveAccount": { "message": "Already have an account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/es/messages.json b/apps/web/src/locales/es/messages.json index 381f13e3066..3ed9b7964f8 100644 --- a/apps/web/src/locales/es/messages.json +++ b/apps/web/src/locales/es/messages.json @@ -6,7 +6,7 @@ "message": "Aplicaciones críticas" }, "accessIntelligence": { - "message": "Access Intelligence" + "message": "Inteligencia de Acceso" }, "riskInsights": { "message": "Risk Insights" @@ -464,6 +464,18 @@ "editFolder": { "message": "Editar carpeta" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Dominio base", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Nombre del elemento" }, - "cannotRemoveViewOnlyCollections": { - "message": "No puedes eliminar colecciones con permisos de solo visualización: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "ej.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Inicio de sesión en proceso" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Enviar" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "Se ha enviado una notificación a tu dispositivo." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "Versión $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Regenerar contraseña" - }, "length": { "message": "Longitud" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Zona peligrosa" }, - "dangerZoneDesc": { - "message": "¡Cuidado, estas acciones no son reversibles!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Desautorizar sesiones" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Proceder también cerrará tu sesión actual, requiriendo que vuelvas a identificarte. También se te pedirá nuevamente tu autenticación en dos pasos en caso de que la tengas habilitada. Las sesiones activas en otros dispositivos pueden mantenerse activas hasta una hora más." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "Desautorizadas todas las sesiones" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Gestionar" }, - "canManage": { - "message": "Puede gestionar" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Desactivar" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "Hubo un problema al leer la llave de seguridad. Inténtalo de nuevo." }, - "twoFactorWebAuthnWarning": { - "message": "Debido a las limitaciones de la plataforma, WebAuthn no puede ser utilizado en todas las aplicaciones de Bitwarden. Debería habilitar otro proveedor de inicio de sesión en dos-pasos para que pueda acceder a su cuenta cuando WebAuthn no pueda ser usado. Plataformas soportadas:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Caja fuerte web y extensiones de navegador en un escritorio/portátil con un navegador WebAuthn habilitado (Chrome, Opera, Vivaldi o Firefox con FIDO U2F habilitado)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Tu código de recuperación de inicio de sesión de dos pasos de Bitwarden" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Establecer requisitos mínimos para la configuración del generador de contraseñas." }, - "passwordGeneratorPolicyInEffect": { - "message": "Una o más políticas de la organización están afectando su configuración del generador." - }, "masterPasswordPolicyInEffect": { "message": "Una o más políticas de la organización requieren que su contraseña maestra cumpla con los siguientes requisitos:" }, @@ -6666,15 +6717,6 @@ "message": "Generador", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "¿Qué desea generar?" - }, - "passwordType": { - "message": "Tipo de contraseña" - }, - "regenerateUsername": { - "message": "Regenerar nombre de usuario" - }, "generateUsername": { "message": "Generar nombre de usuario" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Tipo de nombre de usuario" - }, "plusAddressedEmail": { "message": "Correo electrónico más dirigido", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Utiliza la bandeja de entrada global configurada de tu dominio." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Aleatorio", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Nombre del host", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "Token de acceso API" - }, "deviceVerification": { "message": "Verificación del dispositivo" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "Sin colecciones" }, - "canView": { - "message": "Puede ver" - }, - "canViewExceptPass": { - "message": "Puede ver, excepto contraseñas" - }, - "canEdit": { - "message": "Puede editar" - }, - "canEditExceptPass": { - "message": "Puede editar, excepto contraseñas" - }, "noCollectionsAdded": { "message": "No hay colecciones añadidas" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Propietarios y administradores pueden gestionar todas las colecciones y elementos" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Dominio alias" - }, "alreadyHaveAccount": { "message": "¿Ya tienes una cuenta?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "No puedes eliminar colecciones con permisos de solo visualización: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/et/messages.json b/apps/web/src/locales/et/messages.json index e41f27be411..ede248d2b93 100644 --- a/apps/web/src/locales/et/messages.json +++ b/apps/web/src/locales/et/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Muuda kausta" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Domeen", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Kirje nimi" }, - "cannotRemoveViewOnlyCollections": { - "message": "Sa ei saa eemaldada neid kogumikke ainult vaatamisloaga: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "nt.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Sisselogimine käivitatud" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Kinnita" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "Sinu seadmesse saadeti teavitus." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "Versioon $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Genereeri parool uuesti" - }, "length": { "message": "Pikkus" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Ohtlik tsoon" }, - "dangerZoneDesc": { - "message": "Ettevaatust, neid toiminguid ei saa tagasi võtta!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Sessioonide tühistamine" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Jätkatest logitakse sind ka käimasolevast sessioonist välja, mistõttu pead kontosse uuesti sisse logima. Lisaks võidakse küsida kaheastmelist kinnitust, kui see on sisse lülitatud. Teised kontoga ühendatud seadmed võivad jääda sisselogituks kuni üheks tunniks." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "Kõikidest seadmetest on välja logitud" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Haldus" }, - "canManage": { - "message": "Saab muuta" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Keela" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "Turvavõtme lugemisel tekkis tõrge. Proovi uuesti." }, - "twoFactorWebAuthnWarning": { - "message": "Mõnede platvormi piirangute tõttu ei saa WebAuthn'i kõikide Bitwardeni rakendustega kasutada. Võiksid kaaluda teise kaheastmelise kinnitamise aktiveerimist olukordadeks, kus WebAuthn'i ei saa kasutada. Toetatud platvormid:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Veebihoidla- ja brauseri laiendused laua- ja sülearvutis, kus on WebAuthn toega brauser (Chrome, Opera, Vivaldi või Firefox, kus on FIDO U2F sisse lülitatud)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Bitwardeni kaheastmelise logimise varukood" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Määra parooli genereerija konfiguratsiooni tingimused." }, - "passwordGeneratorPolicyInEffect": { - "message": "Organisatsiooni seaded mõjutavad parooli genereerija sätteid." - }, "masterPasswordPolicyInEffect": { "message": "Üks või enam organisatsiooni eeskirja nõuavad, et ülemparool vastaks nendele nõudmistele:" }, @@ -6666,15 +6717,6 @@ "message": "Genereerija", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "Mida sa soovid genereerida?" - }, - "passwordType": { - "message": "Parooli tüüp" - }, - "regenerateUsername": { - "message": "Genereeri kasutajanimi uuesti" - }, "generateUsername": { "message": "Genereeri kasutajanimi" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Kasutajanime tüüp" - }, "plusAddressedEmail": { "message": "Plussiga e-posti aadress", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Kasuta domeenipõhist kogumisaadressi." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Juhuslik", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Hosti nimi", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API võti" - }, "deviceVerification": { "message": "Seadme kinnitamine" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "No collection" }, - "canView": { - "message": "Can view" - }, - "canViewExceptPass": { - "message": "Can view, except passwords" - }, - "canEdit": { - "message": "Can edit" - }, - "canEditExceptPass": { - "message": "Can edit, except passwords" - }, "noCollectionsAdded": { "message": "No collections added" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domeen" - }, "alreadyHaveAccount": { "message": "Already have an account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "Sa ei saa eemaldada neid kogumikke ainult vaatamisloaga: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/eu/messages.json b/apps/web/src/locales/eu/messages.json index 43447fb4a9f..0b230da1545 100644 --- a/apps/web/src/locales/eu/messages.json +++ b/apps/web/src/locales/eu/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Editatu Karpeta" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Oinarrizko domeinua", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "adb.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Saioa hastea martxan da" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Bidali" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "Jakinarazpen bat bidali da zure gailura." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "$VERSION_NUMBER$ bertsioa", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Berrezarri pasahitza" - }, "length": { "message": "Luzera" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Eremu arriskutsua" }, - "dangerZoneDesc": { - "message": "Kontuz, ekintza hauek ez dira itzulgarriak!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Baimena kendu saio hasierei" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Jarraitzeak uneko saioa itxiko du eta berriro saioa hasteko eskatuko zaizu. Gaituta badago, berriz ere bi urratseko saioa hasiera eskatuko zaizu. Beste gailu batzuetako saio aktiboek ordubete iraun dezakete aktibo." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "Saio guztiei baimena kendua" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Kudeatu" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Desgaitu" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "Arazo bat egon da segurtasun-gakoa irakurtzean. Saiatu berriro mesedez." }, - "twoFactorWebAuthnWarning": { - "message": "Plataformaren mugak direla eta, WebAuthn ezin da erabili Bitwarden-en aplikazio guztietan. Bi urratseko saio hasierako beste hornitzaile bat gaitu beharko duzu, WebAuthn erabili ezin denean zure kontuan sartzeko. Plataforma bateragarriak:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Webguneko kutxa gotorra eta nabigatzailearen gehiagarriak mahaigain/ordenagailu eramangarri batean, WebAuthn nabigatzaile gaitu batekin (Chrome, Opera, Vivaldi edo Firefox, FIDO U2F gaitua duena)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Zure Bitwardeneko bi urratseko saio hasierako berreskuratze-kodea" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Ezarri pasahitz sortzailearen gutxieneko baldintzak." }, - "passwordGeneratorPolicyInEffect": { - "message": "Erakundeko politika batek edo gehiagok sortzailearen konfigurazioari eragiten diote." - }, "masterPasswordPolicyInEffect": { "message": "Erakundeko politika batek edo gehiagok pasahitz nagusia behar dute baldintza hauek betetzeko:" }, @@ -6666,15 +6717,6 @@ "message": "Sortzailea", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "Zer sortu nahi duzu?" - }, - "passwordType": { - "message": "Pasahitz mota" - }, - "regenerateUsername": { - "message": "Berrezarri erabiltzaile izena" - }, "generateUsername": { "message": "Sortu erabiltzaile izena" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Erabiltzaile izen mota" - }, "plusAddressedEmail": { "message": "Atzizkidun emaila", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Erabili zure domeinuan konfiguratutako sarrerako ontzia." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Ausazkoa", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Ostalariaren izena", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "Token sarbide API-a" - }, "deviceVerification": { "message": "Gailu egiaztapena" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "No collection" }, - "canView": { - "message": "Ikus dezake" - }, - "canViewExceptPass": { - "message": "Ikus dezake, pasahitza izan ezik" - }, - "canEdit": { - "message": "Editatu dezake" - }, - "canEditExceptPass": { - "message": "Editatu dezake, pasahitza izan ezik" - }, "noCollectionsAdded": { "message": "No collections added" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domain" - }, "alreadyHaveAccount": { "message": "Already have an account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/fa/messages.json b/apps/web/src/locales/fa/messages.json index af7ae6e06d4..cfcf12c7907 100644 --- a/apps/web/src/locales/fa/messages.json +++ b/apps/web/src/locales/fa/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "ويرايش پوشه" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "دامنه پایه", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "مثال.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "ورود به سیستم آغاز شد" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "ثبت" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "یک اعلان به دستگاه شما ارسال شده است." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "نسخه $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "تولید مجدد کلمه عبور" - }, "length": { "message": "طول" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "منطقه‌ی خطر" }, - "dangerZoneDesc": { - "message": "مراقب باشید، این اقدامات قابل برگشت نیستند!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "لغو مجوز نشست‌ها" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "ادامه دادن همچنین شما را از نشست فعلی خود خارج می‌کند و باید دوباره وارد سیستم شوید. در صورت راه اندازی مجدداً از شما خواسته می‌شود تا دوباره به سیستم دو مرحله ای بپردازید. جلسات فعال در دستگاه‌های دیگر ممکن است تا یک ساعت فعال بمانند." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "همه نشست‌ها غیرمجاز است" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "مدیریت" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "خاموش کردن" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "مشکلی در خواندن کلید امنیتی وجود داشت. دوباره امتحان کنید." }, - "twoFactorWebAuthnWarning": { - "message": "به دلیل محدودیت‌های پلتفرم، WebAuthn نمی‌تواند در همه برنامه‌های Bitwarden استفاده شود. باید یک ارائه‌دهنده‌ی ورود دو مرحله‌ای دیگر راه‌اندازی کنید تا زمانی که WebAuthn قابل استفاده نیست، بتوانید به حساب خود دسترسی داشته باشید. پلتفرم های پشتیبانی شده:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "گاوصندوق وب و برنامه‌های افزودنی مرورگر روی دسکتاپ/لپ‌تاپ با مرورگر پشتیبانی‌شده از WebAuthn (Chrome، Opera، Vivaldi یا Firefox با FIDO U2F روشن)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "کد بازیابی ورود دو مرحله ای Bitwarden شما" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "الزامات را برای تولید کننده کلمه عبور تنظیم کنید." }, - "passwordGeneratorPolicyInEffect": { - "message": "یک یا چند سیاست سازمان بر تنظیمات تولید کننده شما تأثیر می‌گذارد." - }, "masterPasswordPolicyInEffect": { "message": "یک یا چند سیاست سازمانی برای تأمین شرایط زیر به کلمه عبور اصلی شما احتیاج دارد:" }, @@ -6666,15 +6717,6 @@ "message": "تولید کننده", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "چه چیزی دوست دارید تولید کنید؟" - }, - "passwordType": { - "message": "نوع کلمه عبور" - }, - "regenerateUsername": { - "message": "ایجاد مجدد نام کاربری" - }, "generateUsername": { "message": "ایجاد نام کاربری" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "نوع نام کاربری" - }, "plusAddressedEmail": { "message": "به علاوه نشانی ایمیل داده شده", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "از صندوق ورودی پیکربندی شده دامنه خود استفاده کنید." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "تصادفی", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "نام میزبان", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "توکن دسترسی API" - }, "deviceVerification": { "message": "تأیید دستگاه" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "مجموعه ای وجود ندارد" }, - "canView": { - "message": "می‌تواند مشاهده کند" - }, - "canViewExceptPass": { - "message": "قابل مشاهده، به غیر از کلمه‌های عبور" - }, - "canEdit": { - "message": "می‌تواند ویرایش کند" - }, - "canEditExceptPass": { - "message": "قابل ویرایش، به غیر از کلمه‌های عبور" - }, "noCollectionsAdded": { "message": "مجموعه ای اضافه نشد" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "دامنه مستعار" - }, "alreadyHaveAccount": { "message": "پیشتر حساب کاربری داشته اید؟" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/fi/messages.json b/apps/web/src/locales/fi/messages.json index dcb2d9046f5..00d56fdb1c1 100644 --- a/apps/web/src/locales/fi/messages.json +++ b/apps/web/src/locales/fi/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Muokkaa kansiota" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Pääverkkotunnus", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Kohteen nimi" }, - "cannotRemoveViewOnlyCollections": { - "message": "Et voi poistaa kokoelmia, joihin sinulla on vain tarkasteluoikeus: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "esim.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Kirjautuminen aloitettu" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Jatka" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "Laitteellesi on lähetetty ilmoitus." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "Laitteeseesi lähetettiin ilmoitus" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "Versio $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Vältä epäselviä merkkejä", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Luo uusi salasana" - }, "length": { "message": "Pituus" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Vaaravyöhyke" }, - "dangerZoneDesc": { - "message": "Ole varovainen! Näitä toimintoja ei ole mahdollista kumota!" - }, - "dangerZoneDescSingular": { - "message": "Ole varoivainen. Tätä ei ole mahdollista perua!" - }, "deauthorizeSessions": { "message": "Mitätöi kaikki istunnot" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Jatkaminen uloskirjaa myös nykyisen istunnon pakottaen uudelleenkirjautumisen sekä kaksivaiheinen kirjautumisen, jos se on määritetty. Muiden laitteiden aktiiviset istunnot saattavat toimia vielä tunnin ajan." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "Kaikki istunnot mitätöitiin" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Hallitse" }, - "canManage": { - "message": "Voi hallita" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Poista käytöstä" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "Suojausavainta luettaessa havaittiin ongelma. Yritä uudelleen." }, - "twoFactorWebAuthnWarning": { - "message": "Alustakohtaisten rajoitusten vuoksi WebAuthn-todennuslaiteet eivät ole käytettävissä kaikissa Bitwarden-sovelluksissa. Sinun tulisi määrittää eri kaksivaiheisen kirjautumisen todentaja, jotta pääset tilillesi myös silloin kun WebAuthn-laitteen käyttö ei ole mahdollista. Tuetut alustat:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Verkkoholvi ja selainlaajennukset pöytäkoneissa/kannettavissa, joissa on WebAuthn-tekniikkaa tukeva selain (Chrome, Opera, Vivaldi tai Firefox FIDO U2F käyttöön otettuna)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Bitwardenin kaksivaiheisen kirjautumisen palautuskoodisi" @@ -3324,10 +3378,10 @@ } }, "inviteSingleEmailDesc": { - "message": "You have 1 invite remaining." + "message": "Sinulla on 1 kutsu jäljellä." }, "inviteZeroEmailDesc": { - "message": "You have 0 invites remaining." + "message": "Sinulla on 0 kutsua jäljellä." }, "userUsingTwoStep": { "message": "Käyttäjä on suojannut tilinsä kaksivaiheisella kirjautumisella." @@ -3832,22 +3886,22 @@ "message": "Laite" }, "loginStatus": { - "message": "Login status" + "message": "Kirjautumisen tila" }, "firstLogin": { - "message": "First login" + "message": "Ensimmäinen kirjautuminen" }, "trusted": { - "message": "Trusted" + "message": "Luotettu" }, "needsApproval": { - "message": "Needs approval" + "message": "Vaatii hyväksynnän" }, "areYouTryingtoLogin": { - "message": "Are you trying to log in?" + "message": "Yritätkö kirjautua sisään?" }, "logInAttemptBy": { - "message": "Login attempt by $EMAIL$", + "message": "Kirjautumisyritys osoitteella $EMAIL$", "placeholders": { "email": { "content": "$1", @@ -3890,10 +3944,10 @@ "message": "Login request has already expired." }, "justNow": { - "message": "Just now" + "message": "Juuri nyt" }, "requestedXMinutesAgo": { - "message": "Requested $MINUTES$ minutes ago", + "message": "Pyydetty $MINUTES$ minuuttia sitten", "placeholders": { "minutes": { "content": "$1", @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Aseta salasanageneraattorin vaatimukset." }, - "passwordGeneratorPolicyInEffect": { - "message": "Yksi tai useampi organisaatiokäytäntö vaikuttaa generaattorisi asetuksiin." - }, "masterPasswordPolicyInEffect": { "message": "Yksi tai useampi organisaatiokäytäntö edellyttää, että pääsalasanasi täyttää seuraavat vaatimukset:" }, @@ -5798,11 +5849,11 @@ "message": "Bitwarden could not decrypt the vault item(s) listed below." }, "contactCSToAvoidDataLossPart1": { - "message": "Contact customer success", + "message": "Ota yhteyttä asiakkaaseen", "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": "lisätietojen menettämisen välttämiseksi.", "description": "This is part of a larger sentence. The full sentence will read 'Contact customer success to avoid additional data loss.'" }, "accountRecoveryManageUsers": { @@ -6666,15 +6717,6 @@ "message": "Generaattori", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "Mitä haluat luoda?" - }, - "passwordType": { - "message": "Salasanan tyyppi" - }, - "regenerateUsername": { - "message": "Luo uusi käyttäjätunnus" - }, "generateUsername": { "message": "Luo käyttäjätunnus" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Käyttäjätunnuksen tyyppi" - }, "plusAddressedEmail": { "message": "Plus+merkkinen sähköposti", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Käytä verkkotunnuksesi catch-all-postilaatikkoa." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Satunnainen", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Isäntä", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API-käyttötunniste" - }, "deviceVerification": { "message": "Laitevahvistus" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "Ei kokoelmaa" }, - "canView": { - "message": "Voi tarkastella" - }, - "canViewExceptPass": { - "message": "Voi tarkastella (ei salasanoja)" - }, - "canEdit": { - "message": "Voi muokata" - }, - "canEditExceptPass": { - "message": "Voi muokata (ei salasanoja)" - }, "noCollectionsAdded": { "message": "Kokoelmia ei ole lisätty" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Rajoita kokoelmien poisto omistajille ja ylläpitäjille" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Omistajat ja ylläpitäjät voivat hallita kaikkia kokoelmia ja kohteita" }, @@ -8656,9 +8686,6 @@ "message": "Itse ylläpidetyn palvelimen URL-osoite", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Aliaksen verkkotunnus" - }, "alreadyHaveAccount": { "message": "Onko sinulla jo tili?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "Oikeutesi eivät riitä kokoelman hallintaan." }, - "grantAddAccessCollectionWarningTitle": { - "message": "\"Voi hallita\" -käyttöoikeus puuttuu" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Myönnä ”Voi hallita” -oikeus, joka mahdollistaa kokoelman täydellisen hallinnan, mukaan lukien sen poistamisen." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Myönnä ryhmille tai henkilöille kokoelman käyttöoikeus." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "Et voi poistaa kokoelmia, joihin sinulla on vain tarkasteluoikeus: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Tärkeä ilmoitus" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/fil/messages.json b/apps/web/src/locales/fil/messages.json index 7c5aa918fff..42b4882bf20 100644 --- a/apps/web/src/locales/fil/messages.json +++ b/apps/web/src/locales/fil/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Baguhin ang folder" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Base domain", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "hal.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Sinimulan ang pag-log in" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Ipadala" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "Nakapagpadala na ng notipikasyon sa device mo." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "Bersyon $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Gumawa ng isa pang password" - }, "length": { "message": "Haba" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Mapanganib na lugar" }, - "dangerZoneDesc": { - "message": "Mag-ingat, wala nang bawian sa mga gagawin mo rito!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "I-deauthorize ang mga sesyon" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Mala-log out ka rin sa kasalukuyan mong sesyon kung tutuloy ka, at kakailanganin mong mag-log in ulit. Kakailanganin mo ring ulitin ang dalawang-hakbang na pag-log in kung naka-set up ito. Maaaring manatiling aktibo ang mga sesyon sa iba pang device nang hanggang isang oras." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "Na-deauthorize lahat ng mga sesyon" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Pamahalaan" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Isara" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "Nagkaproblema sa pagbabasa ng security key. Pakisubukan ulit." }, - "twoFactorWebAuthnWarning": { - "message": "Hindi magagamit sa lahat ng mga aplikasyon ng Bitwarden ang WebAuthn dahil sa mga limitasyon ng platform. Dapat mag-set up ka ng isa pang provider ng dalawang-hakbang na pag-log in para ma-access mo ang account mo sakaling hindi magamit ang WebAuthn. Mga suportadong platform:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Web vault at mga ekstensyon pang-browser sa desktop/laptop na may browser na sinusuportahan ang WebAuthn (Chrome, Opera, Vivaldi, o Firefox na nakabukas ang FIDO U2F)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Code pang-recover mo sa dalawang-hakbang na pag-log in sa Bitwarden" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Magtakda ng mga kinakailangan para sa generator ng password." }, - "passwordGeneratorPolicyInEffect": { - "message": "Isang o higit pang patakaran ng organisasyon ay nakakaapekto sa iyong mga setting ng generator." - }, "masterPasswordPolicyInEffect": { "message": "Isang o higit pang mga patakaran ng organisasyon ay nangangailangan ng iyong master password upang matugunan ang sumusunod na kinakailangan:" }, @@ -6666,15 +6717,6 @@ "message": "Magmamana", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "Ano ang nais mong bumuo?" - }, - "passwordType": { - "message": "Uri ng Password" - }, - "regenerateUsername": { - "message": "Muling bumuo ng username" - }, "generateUsername": { "message": "Lumikha ng username" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Uri ng username" - }, "plusAddressedEmail": { "message": "Plus na naka-address na email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Gamitin ang naka configure na inbox ng catch all ng iyong domain." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Random", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Pangalan ng Hostname", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "Token ng Access sa API" - }, "deviceVerification": { "message": "Pag verify ng aparato" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "Walang koleksyon" }, - "canView": { - "message": "Maaaring tingnan" - }, - "canViewExceptPass": { - "message": "Maaaring tingnan, maliban sa mga password" - }, - "canEdit": { - "message": "Maaaring i-edit" - }, - "canEditExceptPass": { - "message": "Maaaring mag edit, maliban sa mga password" - }, "noCollectionsAdded": { "message": "Walang idinagdag na mga koleksyon" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domain" - }, "alreadyHaveAccount": { "message": "Already have an account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/fr/messages.json b/apps/web/src/locales/fr/messages.json index af178713cfc..a5a55255c28 100644 --- a/apps/web/src/locales/fr/messages.json +++ b/apps/web/src/locales/fr/messages.json @@ -114,7 +114,7 @@ "message": "Membres à risque" }, "atRiskMembersWithCount": { - "message": "At-risk members ($COUNT$)", + "message": "Membres à risque ($COUNT$)", "placeholders": { "count": { "content": "$1", @@ -132,13 +132,13 @@ } }, "atRiskMembersDescription": { - "message": "These members are logging into applications with weak, exposed, or reused passwords." + "message": "Ces membres se connectent à des applications avec des mots de passe faibles, exposés ou réutilisés." }, "atRiskApplicationsDescription": { "message": "Ces applications ont des mots de passe faibles, exposés ou réutilisés." }, "atRiskMembersDescriptionWithApp": { - "message": "These members are logging into $APPNAME$ with weak, exposed, or reused passwords.", + "message": "Ces membres se connectent à $APPNAME$ avec des mots de passe faibles, exposés ou réutilisés.", "placeholders": { "appname": { "content": "$1", @@ -464,6 +464,18 @@ "editFolder": { "message": "Modifier le dossier" }, + "newFolder": { + "message": "Nouveau dossier" + }, + "folderName": { + "message": "Nom de dossier" + }, + "folderHintText": { + "message": "Créez un sous-dossier en ajoutant le nom du dossier parent suivi d'un \"/\". Par exemple : Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Êtes-vous sûr de vouloir supprimer définitivement ce dossier ?" + }, "baseDomain": { "message": "Domaine de base", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Nom de l’élément" }, - "cannotRemoveViewOnlyCollections": { - "message": "Vous ne pouvez pas supprimer des collections avec les autorisations d'affichage uniquement : $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "ex.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Connexion initiée" }, + "logInRequestSent": { + "message": "Demande envoyée" + }, "submit": { "message": "Soumettre" }, @@ -1342,7 +1348,7 @@ "message": "Aucun élément à afficher." }, "noPermissionToViewAllCollectionItems": { - "message": "Vous n'avez pas la permission de voir tous les éléments de cette collection." + "message": "Vous n'avez pas l'autorisation d'afficher tous les éléments de cette collection." }, "youDoNotHavePermissions": { "message": "Vous n'avez pas les autorisations pour cette collection" @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "Une notification a été envoyée à votre appareil." }, + "notificationSentDevicePart1": { + "message": "Déverrouillez Bitwarden sur votre appareil ou sur le " + }, + "areYouTryingToAccessYourAccount": { + "message": "Essayez-vous d'accéder à votre compte ?" + }, + "accessAttemptBy": { + "message": "Tentative d'accès par $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirmer l'accès" + }, + "denyAccess": { + "message": "Refuser l'accès" + }, + "notificationSentDeviceAnchor": { + "message": "application web" + }, + "notificationSentDevicePart2": { + "message": "Assurez-vous que la phrase d'empreinte correspond à celle ci-dessous avant d'approuver." + }, + "notificationSentDeviceComplete": { + "message": "Déverrouillez Bitwarden sur votre appareil. Assurez-vous que la phrase d'empreinte correspond à celle ci-dessous avant d'approuver." + }, "aNotificationWasSentToYourDevice": { "message": "Une notification a été envoyée à votre appareil" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Assurez-vous que votre compte est déverrouillé et que la phrase d'empreinte correspond à l'autre appareil" - }, "versionNumber": { "message": "Version $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Éviter les caractères ambigus", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Régénérer un mot de passe" - }, "length": { "message": "Longueur" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Zone de danger" }, - "dangerZoneDesc": { - "message": "Attention, ces actions sont irréversibles !" - }, - "dangerZoneDescSingular": { - "message": "Attention, cette action est irréversible!" - }, "deauthorizeSessions": { "message": "Révoquer les sessions" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "En poursuivant, vous serez également déconnecté de votre session en cours, ce qui vous obligera à vous reconnecter. Vous serez également invité à vous reconnecter via l'authentification à deux facteurs, si elle est configurée. Les sessions actives sur d'autres appareils peuvent rester actives pendant encore une heure." }, + "newDeviceLoginProtection": { + "message": "Connexion à un nouvel appareil" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Désactivez la protection de connexion du nouvel appareil" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Activez la protection de connexion du nouvel appareil" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Procédez ci-dessous pour désactiver les courriels de vérification envoyés par Bitwarden lorsque vous vous connectez à partir d'un nouvel appareil." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Procédez ci-dessous pour que Bitwarden vous envoie des courriels de vérification lorsque vous vous connectez à partir d'un nouvel appareil." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "Avec la protection de connexion d'un nouvel appareil désactivée, toute personne ayant votre mot de passe maître peut accéder à votre compte depuis n'importe quel appareil. Pour protéger votre compte sans courriel de vérification, configurez la connexion en deux étapes." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "Modifications de la protection de connexion de l'appareil enregistrées" + }, "sessionsDeauthorized": { "message": "Toutes les sessions ont été révoquées" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Gérer" }, - "canManage": { - "message": "Peut gérer" + "manageCollection": { + "message": "Gérer la collection" + }, + "viewItems": { + "message": "Afficher les éléments" + }, + "viewItemsHidePass": { + "message": "Afficher les éléments, les mots de passe cachés" + }, + "editItems": { + "message": "Modifier les items" + }, + "editItemsHidePass": { + "message": "Modifier les éléments, les mots de passe cachés" }, "disable": { "message": "Désactiver" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "Un problème est survenu lors de la lecture de la clé de sécurité. Veuillez réessayer." }, - "twoFactorWebAuthnWarning": { - "message": "En raison des limitations de la plate-forme, WebAuthn ne peut pas être utilisé sur toutes les applications Bitwarden. Vous devriez mettre en place un autre fournisseur d'authentification à deux facteurs afin de pouvoir accéder à votre compte lorsque WebAuthn ne peut pas être utilisé. Plateformes supportées :" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Coffre web et extensions sur un ordinateur fixe/portable avec un navigateur compatible WebAuthn (Chrome, Opera, Vivaldi ou Firefox avec FIDO U2F activé)." + "twoFactorWebAuthnWarning1": { + "message": "En raison des limitations de plate-forme, WebAuthn ne peut pas être utilisé sur toutes les applications Bitwarden. Vous devriez mettre en place un autre fournisseur d'authentification à deux facteurs afin de pouvoir accéder à votre compte lorsque WebAuthn ne peut pas être utilisé." }, "twoFactorRecoveryYourCode": { "message": "Votre code de récupération de d'authentification à deux facteurs Bitwarden" @@ -3324,7 +3378,7 @@ } }, "inviteSingleEmailDesc": { - "message": "You have 1 invite remaining." + "message": "Il vous reste 1 invitation." }, "inviteZeroEmailDesc": { "message": "Il vous reste 0 invitations." @@ -3348,7 +3402,7 @@ "message": "Propriétaire" }, "ownerDesc": { - "message": "L’utilisateur avec l’accès le plus élevé qui peut gérer tous les aspects de votre organisation." + "message": "Gérer tous les aspects de votre organisation, y compris la facturation et les abonnements" }, "clientOwnerDesc": { "message": "Cet utilisateur doit être indépendant du fournisseur. Si le fournisseur est dissocié de l'organisation, cet utilisateur conservera la propriété de l'organisation." @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Définir les exigences pour le générateur de mot de passe." }, - "passwordGeneratorPolicyInEffect": { - "message": "Une ou plusieurs politiques de sécurité de l'organisation affectent les paramètres de votre générateur." - }, "masterPasswordPolicyInEffect": { "message": "Une ou plusieurs politiques de sécurité de l'organisation exigent que votre mot de passe principal réponde aux exigences suivantes :" }, @@ -5117,7 +5168,7 @@ "message": "Accordez et gérez l'accès d'urgence pour les contacts de confiance. Les contacts de confiance peuvent demander l'accès pour afficher ou reprendre le contrôle de votre compte en cas d'urgence. Consultez notre page d'aide pour plus d'informations et de détails sur le fonctionnement du partage à divulgation nulle de connaissance (zero knowledge sharing)." }, "emergencyAccessOwnerWarning": { - "message": "Vous êtes propriétaire d'une ou de plusieurs organisations. Si vous autorisez la prise de contrôle à un contact d'urgence, il sera en mesure d'utiliser toutes vos permissions de propriétaire après la prise de contrôle." + "message": "Vous êtes propriétaire d'une ou de plusieurs organisations. Si vous autorisez la prise de contrôle à un contact d'urgence, il sera en mesure d'utiliser toutes vos autorisations de propriétaire après la prise de contrôle." }, "trustedEmergencyContacts": { "message": "Contacts d'urgence de confiance" @@ -5344,7 +5395,7 @@ "message": "Permissions" }, "permission": { - "message": "Permission" + "message": "Autorisation" }, "accessEventLogs": { "message": "Accéder aux journaux d'événements" @@ -6626,7 +6677,7 @@ } }, "accessDenied": { - "message": "Accès Refusé. Vous n'avez pas la permission de voir cette page." + "message": "Accès Refusé. Vous n'avez pas l'autorisation d'afficher cette page." }, "masterPassword": { "message": "Mot de passe principal" @@ -6666,15 +6717,6 @@ "message": "Générateur", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "Que souhaitez-vous générer ?" - }, - "passwordType": { - "message": "Type de mot de passe" - }, - "regenerateUsername": { - "message": "Régénérer le Nom d'Utilisateur" - }, "generateUsername": { "message": "Générer le Nom d'Utilisateur" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Type de Nom d'Utilisateur" - }, "plusAddressedEmail": { "message": "Courriel Adressé Plus", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Utilisez la boîte de réception du collecteur (catch-all) configurée de votre domaine." }, + "useThisEmail": { + "message": "Utiliser ce courriel" + }, "random": { "message": "Aléatoire", "description": "Generates domain-based username using random letters" @@ -6762,7 +6804,7 @@ "message": "Service" }, "unknownCipher": { - "message": "Élément inconnu, vous devrez peut-être vous connecter avec un autre compte pour accéder à cet élément." + "message": "Élément inconnu, vous devrez peut-être demander l'autorisation d'accéder à cet élément." }, "cannotSponsorSelf": { "message": "Vous ne pouvez pas réclamer pour le compte actif. Saisissez un courriel différent." @@ -6934,9 +6976,6 @@ "message": "Nom d'hôte", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "Jetons d'accès API" - }, "deviceVerification": { "message": "Vérification de l'Appareil" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "Aucune collection" }, - "canView": { - "message": "Peut voir" - }, - "canViewExceptPass": { - "message": "Peut voir, sauf les mots de passe" - }, - "canEdit": { - "message": "Peut modifier" - }, - "canEditExceptPass": { - "message": "Peut modifier, sauf les mots de passe" - }, "noCollectionsAdded": { "message": "Pas de collections ajoutées" }, @@ -7850,7 +7877,7 @@ "message": "Sélectionner les groupes" }, "userPermissionOverrideHelperDesc": { - "message": "Les permissions définies pour un membre remplaceront les permissions définies par le groupe de ce membre." + "message": "Les autorisations définies pour un membre remplaceront les autorisations définies par le groupe de ce membre." }, "noMembersOrGroupsAdded": { "message": "Aucun membre ou groupe ajouté" @@ -8237,7 +8264,7 @@ "message": "Exiger que les membres existants changent leurs mots de passe" }, "smProjectDeleteAccessRestricted": { - "message": "Vous n'avez pas les droits pour supprimer ce projet", + "message": "Vous n'avez pas les autorisations pour supprimer ce projet", "description": "The individual description shown to the user when the user doesn't have access to delete a project." }, "smProjectsDeleteBulkConfirmation": { @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limiter la suppression de collections aux propriétaires et administrateurs" }, + "limitItemDeletionDesc": { + "message": "Limite la suppression de l'élément aux membres avec l'autorisation Peut gérer" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Les propriétaires et les administrateurs peuvent gérer toutes les collections et tous les éléments" }, @@ -8656,9 +8686,6 @@ "message": "URL du serveur auto-hébergé", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Domaine de l'alias" - }, "alreadyHaveAccount": { "message": "Vous avez déjà un compte ?" }, @@ -8669,7 +8696,7 @@ "message": "Sauter directement au contenu" }, "managePermissionRequired": { - "message": "Au moins un membre ou un groupe doit avoir la permission peut gérer." + "message": "Au moins un membre ou un groupe doit avoir l'autorisation peut gérer." }, "typePasskey": { "message": "Passkey" @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "Vous n'avez pas accès à la gestion de cette collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "\"Peut Gérer les Permissions\" manquant" + "grantManageCollectionWarningTitle": { + "message": "Autorisations pour Gérer la Collection manquantes" }, - "grantAddAccessCollectionWarning": { - "message": "Accorder \"Peut Gérer les Permissions\" pour permettre une gestion complète de la collection, y compris la suppression de la collection." + "grantManageCollectionWarning": { + "message": "Accorde les autorisations pour Gérer la collection pour permettre la gestion complète de la collection incluant sa suppression." }, "grantCollectionAccess": { "message": "Accorder l'accès à cette collection aux groupes ou aux membres." @@ -9437,16 +9464,16 @@ "message": "Informations sur les taxes mises à jour" }, "billingInvalidTaxIdError": { - "message": "Invalid tax ID, if you believe this is an error please contact support." + "message": "ID de taxe non valide, si vous pensez qu'il s'agit d'une erreur, veuillez contacter le support." }, "billingTaxIdTypeInferenceError": { - "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + "message": "Nous n'avons pu valider votre ID de taxes. Si vous pensez que c'est une erreur, veuillez contacter le support s'il-vous-plaît." }, "billingPreviewInvalidTaxIdError": { - "message": "Invalid tax ID, if you believe this is an error please contact support." + "message": "ID de taxe non valide, si vous pensez qu'il s'agit d'une erreur, veuillez contacter le support." }, "billingPreviewInvoiceError": { - "message": "An error occurred while previewing the invoice. Please try again later." + "message": "Une erreur s'est produite lors de la prévisualisation de la facture. Veuillez réessayer plus tard." }, "unverified": { "message": "Non vérifié" @@ -9489,7 +9516,7 @@ "message": "(Aucune collection)" }, "memberAccessReportNoCollectionPermission": { - "message": "(Aucune permission de collection)" + "message": "(Aucune Autorisation de Collection)" }, "memberAccessReportNoGroup": { "message": "(Aucun groupe)" @@ -9531,7 +9558,7 @@ "message": " Contactez le Support Client pour rétablir votre abonnement." }, "secretPeopleDescription": { - "message": "Autoriser les groupes ou les personnes à accéder à ce secret. Les permissions définies pour les personnes remplaceront les permissions définies par les groupes." + "message": "Autoriser les groupes ou les personnes à accéder à ce secret. Les autorisations définies pour les personnes remplaceront les autorisations définies par les groupes." }, "secretPeopleEmptyMessage": { "message": "Ajouter des personnes ou des groupes pour partager l'accès à ce secret" @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Code descripteur" }, + "cannotRemoveViewOnlyCollections": { + "message": "Vous ne pouvez pas supprimer des collections avec les autorisations d'affichage uniquement : $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Avis important" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Les administrateurs ont maintenant la possibilité de supprimer les comptes de membre qui appartiennent à un domaine revendiqué." + }, + "deleteManagedUserWarningDesc": { + "message": "Cette action supprimera le compte du membre, incluant tous les éléments de son coffre. Cela remplace l'action précédente de Supprimer." + }, + "deleteManagedUserWarning": { + "message": "Supprimer est une nouvelle action !" + }, + "seatsRemaining": { + "message": "Vous avez $REMAINING$ places restantes sur $TOTAL$ attribuées à cette organisation. Contactez votre fournisseur pour gérer votre abonnement.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Organisation existante" + }, + "selectOrganizationProviderPortal": { + "message": "Sélectionnez une organisation à ajouter à votre Portail fournisseur." + }, + "noOrganizations": { + "message": "Il n'y a aucune organisation à lister" + }, + "yourProviderSubscriptionCredit": { + "message": "Votre abonnement à un fournisseur recevra un crédit pour tout temps restant dans l'abonnement de l'organisation." + }, + "doYouWantToAddThisOrg": { + "message": "Voulez-vous ajouter cette organisation à $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Organisation existante ajoutée" + }, + "assignedExceedsAvailable": { + "message": "Les places assignées dépassent les places disponibles." } } diff --git a/apps/web/src/locales/gl/messages.json b/apps/web/src/locales/gl/messages.json index 436b28dbabd..f5cd301fc5f 100644 --- a/apps/web/src/locales/gl/messages.json +++ b/apps/web/src/locales/gl/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Edit folder" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Base domain", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Nome do elemento" }, - "cannotRemoveViewOnlyCollections": { - "message": "Non podes eliminar coleccións con permisos de só lectura: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "ex.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Log in initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Submit" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "Version $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Regenerate password" - }, "length": { "message": "Length" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Danger zone" }, - "dangerZoneDesc": { - "message": "Careful, these actions are not reversible!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Deauthorize sessions" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Proceeding will also log you out of your current session, requiring you to log back in. You will also be prompted for two-step login again, if set up. Active sessions on other devices may continue to remain active for up to one hour." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "All sessions deauthorized" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Manage" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Turn off" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "There was a problem reading the security key. Try again." }, - "twoFactorWebAuthnWarning": { - "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used. Supported platforms:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Web vault and browser extensions on a desktop/laptop with a WebAuthn supported browser (Chrome, Opera, Vivaldi, or Firefox with FIDO U2F turned on)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Your Bitwarden two-step login recovery code" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Set requirements for password generator." }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organization policies are affecting your generator settings." - }, "masterPasswordPolicyInEffect": { "message": "One or more organization policies require your master password to meet the following requirements:" }, @@ -6666,15 +6717,6 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Use your domain's configured catch-all inbox." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Random", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Hostname", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API access token" - }, "deviceVerification": { "message": "Device verification" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "No collection" }, - "canView": { - "message": "Can view" - }, - "canViewExceptPass": { - "message": "Can view, except passwords" - }, - "canEdit": { - "message": "Can edit" - }, - "canEditExceptPass": { - "message": "Can edit, except passwords" - }, "noCollectionsAdded": { "message": "No collections added" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domain" - }, "alreadyHaveAccount": { "message": "Already have an account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "Non podes eliminar coleccións con permisos de só lectura: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/he/messages.json b/apps/web/src/locales/he/messages.json index c9e552cab94..27ea87bcfe4 100644 --- a/apps/web/src/locales/he/messages.json +++ b/apps/web/src/locales/he/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "ערוך תיקייה" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "שם בסיס הדומיין", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "לדוגמא", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Log in initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "שלח" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "גרסה $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "צור סיסמה חדשה" - }, "length": { "message": "אורך" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "אזור מסוכן" }, - "dangerZoneDesc": { - "message": "זהירות, פעולות אלה לא ניתנות לביטול!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "בטל הרשאות סשנים" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "בכדי להמשיך הסשן הנוכחי ינותק, ותדרש להזין את פרטי הכניסה החדשים וגם את פרטי האימות הדו-שלבי, אם הוא מאופשר. כל הסשנים הפעילים במכשירים אחרים ישארו פעילים עד שעה ממועד הכניסה החדשה." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "הוסרה ההרשאה מכל הסשנים" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "נהל" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "בטל" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "היתה בעיה בקריאת מפתח האבטחה. נסה בשנית." }, - "twoFactorWebAuthnWarning": { - "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used. Supported platforms:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Web vault and browser extensions on a desktop/laptop with a WebAuthn supported browser (Chrome, Opera, Vivaldi, or Firefox with FIDO U2F turned on)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "קוד השחזור שלך עבור כניסה דו שלבית לBitwarden" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "הגדר דרישות מינימום במחולל הסיסמאות." }, - "passwordGeneratorPolicyInEffect": { - "message": "מדיניות ארגונית אחת או יותר משפיעה על הגדרות המחולל שלך." - }, "masterPasswordPolicyInEffect": { "message": "אחד או יותר מכללי מדיניות הארגון דורשים שסיסמתך הראשית תעמוד בדרישות הבאות:" }, @@ -6666,15 +6717,6 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Use your domain's configured catch-all inbox." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Random", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Hostname", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API access token" - }, "deviceVerification": { "message": "Device verification" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "No collection" }, - "canView": { - "message": "Can view" - }, - "canViewExceptPass": { - "message": "Can view, except passwords" - }, - "canEdit": { - "message": "Can edit" - }, - "canEditExceptPass": { - "message": "Can edit, except passwords" - }, "noCollectionsAdded": { "message": "No collections added" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domain" - }, "alreadyHaveAccount": { "message": "Already have an account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/hi/messages.json b/apps/web/src/locales/hi/messages.json index 8e94756b311..266a868e435 100644 --- a/apps/web/src/locales/hi/messages.json +++ b/apps/web/src/locales/hi/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Edit folder" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Base domain", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "ex.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Log in initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Submit" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "Version $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Regenerate password" - }, "length": { "message": "Length" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Danger zone" }, - "dangerZoneDesc": { - "message": "Careful, these actions are not reversible!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Deauthorize sessions" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Proceeding will also log you out of your current session, requiring you to log back in. You will also be prompted for two-step login again, if set up. Active sessions on other devices may continue to remain active for up to one hour." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "All sessions deauthorized" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Manage" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Turn off" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "There was a problem reading the security key. Try again." }, - "twoFactorWebAuthnWarning": { - "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used. Supported platforms:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Web vault and browser extensions on a desktop/laptop with a WebAuthn supported browser (Chrome, Opera, Vivaldi, or Firefox with FIDO U2F turned on)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Your Bitwarden two-step login recovery code" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Set requirements for password generator." }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organization policies are affecting your generator settings." - }, "masterPasswordPolicyInEffect": { "message": "One or more organization policies require your master password to meet the following requirements:" }, @@ -6666,15 +6717,6 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Use your domain's configured catch-all inbox." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Random", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Hostname", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API access token" - }, "deviceVerification": { "message": "Device verification" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "No collection" }, - "canView": { - "message": "Can view" - }, - "canViewExceptPass": { - "message": "Can view, except passwords" - }, - "canEdit": { - "message": "Can edit" - }, - "canEditExceptPass": { - "message": "Can edit, except passwords" - }, "noCollectionsAdded": { "message": "No collections added" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domain" - }, "alreadyHaveAccount": { "message": "Already have an account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/hr/messages.json b/apps/web/src/locales/hr/messages.json index 6a4ee04be4e..a847caf7644 100644 --- a/apps/web/src/locales/hr/messages.json +++ b/apps/web/src/locales/hr/messages.json @@ -114,7 +114,7 @@ "message": "Rizični korisnici" }, "atRiskMembersWithCount": { - "message": "At-risk members ($COUNT$)", + "message": "Izloženi članovi ($COUNT$)", "placeholders": { "count": { "content": "$1", @@ -123,7 +123,7 @@ } }, "atRiskApplicationsWithCount": { - "message": "At-risk applications ($COUNT$)", + "message": "Izložene aplikacije ($COUNT$)", "placeholders": { "count": { "content": "$1", @@ -132,13 +132,13 @@ } }, "atRiskMembersDescription": { - "message": "These members are logging into applications with weak, exposed, or reused passwords." + "message": "Ovi članovi se prijavljuju u aplikacije slabim, izloženim ili ponovno korištenim lozinkama." }, "atRiskApplicationsDescription": { - "message": "These applications have weak, exposed, or reused passwords." + "message": "Ove aplikacije imaju slabe, izložene ili ponovno korištene lozinke." }, "atRiskMembersDescriptionWithApp": { - "message": "These members are logging into $APPNAME$ with weak, exposed, or reused passwords.", + "message": "Ovi članovi se u $APPNAME$ prijavljuju slabim, izloženim ili ponovno korištenim lozinkama.", "placeholders": { "appname": { "content": "$1", @@ -156,10 +156,10 @@ "message": "Ukupno aplikacija" }, "unmarkAsCriticalApp": { - "message": "Unmark as critical app" + "message": "Odznači kao kritičnu aplikaciju" }, "criticalApplicationSuccessfullyUnmarked": { - "message": "Critical application successfully unmarked" + "message": "Kritična aplikacija uspješno odznačena" }, "whatTypeOfItem": { "message": "Koja je ovo vrsta stavke?" @@ -235,7 +235,7 @@ "message": "Povijest stavke" }, "authenticatorKey": { - "message": "Kôd za provjeru" + "message": "Ključ autentifikatora" }, "autofillOptions": { "message": "Postavke auto-ispune" @@ -405,7 +405,7 @@ "message": "Bitwarden može pohraniti i ispuniti kodove za dvostruku autentifikaciju. Kopiraj i zalijepi ključ u ovo polje." }, "totpHelperWithCapture": { - "message": "Bitwarden može pohraniti i ispuniti kodove za dvostruku autentifikaciju. Odaberi ikonu kamere i označi QR kôd za provjeru autentičnosti ove web stranice ili kopiraj i zalijepi ključ u ovo polje." + "message": "Bitwarden može pohraniti i ispuniti kodove provjeru dvostruke autentifikacije. Odaberi ikonu kamere i označi QR kôd za provjeru autentičnosti ove web stranice ili kopiraj i zalijepi ključ u ovo polje." }, "learnMoreAboutAuthenticators": { "message": "Više o autentifikatorima" @@ -464,6 +464,18 @@ "editFolder": { "message": "Uredi mapu" }, + "newFolder": { + "message": "Nova mapa" + }, + "folderName": { + "message": "Naziv mape" + }, + "folderHintText": { + "message": "Ugnijezdi mapu dodavanjem naziva roditeljske mape i znaka kroz. Npr. Mreže/Forumi" + }, + "deleteFolderPermanently": { + "message": "Sigurno želiš trajno izbrisati ovu mapu?" + }, "baseDomain": { "message": "Primarna domena", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Naziv stavke" }, - "cannotRemoveViewOnlyCollections": { - "message": "S dopuštenjima samo za prikaz ne možeš ukloniti zbirke: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "npr.", "description": "Short abbreviation for 'example'." @@ -1168,20 +1171,23 @@ "message": "Potvrdi svoj identitet" }, "weDontRecognizeThisDevice": { - "message": "We don't recognize this device. Enter the code sent to your email to verify your identity." + "message": "Ne prepoznajemo ovaj uređaj. Za potvrdu identiteta unesi kôd poslan e-poštom." }, "continueLoggingIn": { - "message": "Continue logging in" + "message": "Nastavi prijavu" }, "whatIsADevice": { - "message": "What is a device?" + "message": "Što je uređaj?" }, "aDeviceIs": { - "message": "A device is a unique installation of the Bitwarden app where you have logged in. Reinstalling, clearing app data, or clearing your cookies could result in a device appearing multiple times." + "message": "Uređaj je jedinstvena instalacija Bitwarden aplikacije gdje si prijavljen/a. Ponovna instalacija, brisanje podataka aplikacije ili kolačića može rezultirati višestrukim prikazom uređaja." }, "logInInitiated": { "message": "Pokrenuta prijava" }, + "logInRequestSent": { + "message": "Zahtjev poslan" + }, "submit": { "message": "Pošalji" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "Obavijest je poslana na tvoj uređaj." }, + "notificationSentDevicePart1": { + "message": "Otključaj Bitwarden na svojem uređaju ili na " + }, + "areYouTryingToAccessYourAccount": { + "message": "Pokušavaš li pristupiti svom računu?" + }, + "accessAttemptBy": { + "message": "$EMAIL$ pokušava pristupiti", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Potvrdi pristup" + }, + "denyAccess": { + "message": "Odbij pristup" + }, + "notificationSentDeviceAnchor": { + "message": "web trezoru" + }, + "notificationSentDevicePart2": { + "message": "Provjeri slaže li se jedinstvena fraza s ovdje prikazanom prije odobravanja." + }, + "notificationSentDeviceComplete": { + "message": "Otključaj Bitwarden na svojem uređaju. Provjeri slaže li se jedinstvena fraza s ovdje prikazanom prije odobravanja." + }, "aNotificationWasSentToYourDevice": { "message": "Obavijest je poslana na tvoj uređaj" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Provjeri je li trezor otključan i slaže li se jedinstvena fraza s drugim uređajem" - }, "versionNumber": { "message": "Verzija $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Izbjegavaj dvosmislene znakove", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Ponovno generiraj lozinku" - }, "length": { "message": "Duljina" }, @@ -1767,10 +1797,10 @@ "message": "Molimo, ponovno se prijavi." }, "currentSession": { - "message": "Current session" + "message": "Trenutna sesija" }, "requestPending": { - "message": "Request pending" + "message": "Zahtjev u tijeku" }, "logBackInOthersToo": { "message": "Molimo, ponovno se prijavi. Ako koristiš druge aplikacije Bitwarden i u njima napravi odjavu/prijavu." @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "OPASNA zona!" }, - "dangerZoneDesc": { - "message": "Pažljivo, ove akcije su konačne i ne mogu se poništiti!" - }, - "dangerZoneDescSingular": { - "message": "Pažljivo, ova radnja se ne može poništiti!" - }, "deauthorizeSessions": { "message": "Deautoriziraj sesije" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Ako nastaviš, trenutna sesija će biti zatvorena, što će zahtijevati ponovnu prijavu uklljučujući i prijavu dvostrukom autentifikacijom, ako je ona aktivna. Aktivne sesije na drugim uređajima mogu ostati aktivne još jedan sat." }, + "newDeviceLoginProtection": { + "message": "Prijava novog uređaja" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Isključi zaštitu prijave novih uređaja" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Uključi zaštitu prijave novih uređaja" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Za prestanak dobivanja e-pošte kada se prijaviš s novog uređaja, nastavi niže." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Za dobivanje e-pošte kada se prijaviš s novog uređaja, nastavi niže." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "Ako je zaštita prijave novih uređaja isključena, bilo tko s tvojom glavnom lozinkom može pristupiti tvom računu s bilo kojeg uređaja. Za zaštitu svog računa bez potvrde e-poštom, uključi dvostruku autentifikaciju." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "Promjene zaštite prijave novih uređaja su spremljene" + }, "sessionsDeauthorized": { "message": "Sve sesije deautorizirane" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Upravljaj" }, - "canManage": { - "message": "Može upravljati" + "manageCollection": { + "message": "Upravljaj zbirkom" + }, + "viewItems": { + "message": "Prikaz stavke" + }, + "viewItemsHidePass": { + "message": "Prikaz stavke, skrivene lozinke" + }, + "editItems": { + "message": "Uredi stavke" + }, + "editItemsHidePass": { + "message": "Uredi stavke, skrivene lozinke" }, "disable": { "message": "Onemogući" @@ -2198,7 +2255,7 @@ "message": "Nastavi na bitwarden.com?" }, "twoStepContinueToBitwardenUrlDesc": { - "message": "Bitwarden autentifikator omogućuje pohranu ključeva za autentifikaciju i generiranje TOTP kodova za dvostruku autentifikaciju. Saznaj više na bitwarden.com." + "message": "Bitwarden autentifikator omogućuje pohranu ključeva za autentifikator i generiranje TOTP kodova za provjeru dvostruke autentifikacije. Saznaj više na bitwarden.com." }, "twoStepAuthenticatorScanCodeV2": { "message": "Skeniraj donji QR kôd svojom autentifikatorskom aplikacijom ili unesi ključ." @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "Došlo je do pogreške kod očitavanja sigurnosnog ključa. Pokušaj ponovno." }, - "twoFactorWebAuthnWarning": { - "message": "Zbog platformskih ograničenja, WebAuthn nije moguće koristiti s Bitwarden aplikacijama na svim platformama. Za pristup računu kada nije moguće koristiti WebAuthn, trebalo bi uključiti drugog pružatelja prijave dvostrukom autentifikacijom. Platforme na kojima je WebAuthn podržan:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Web trezor i proširenja preglednika na stolnim/prijenosnim računalima s WebAuthn podržanim preglednikom (npr. Chrome, Opera, Vivaldi ili Firefox s omogućenim WebAuthn)." + "twoFactorWebAuthnWarning1": { + "message": "Zbog platformskih ograničenja, WebAuthn nije moguće koristiti sa svim Bitwarden aplikacijama. Uključi drugi način dvostruke autentifikacije za pristup računu kada se ne može koristiti WebAuthn." }, "twoFactorRecoveryYourCode": { "message": "Tvoj kôd za oporavak Bitwarden prijave dvostrukom autentifikacijom" @@ -3324,10 +3378,10 @@ } }, "inviteSingleEmailDesc": { - "message": "You have 1 invite remaining." + "message": "Imaš jednu preostalu pozivnicu." }, "inviteZeroEmailDesc": { - "message": "You have 0 invites remaining." + "message": "Nemaš preostalih pozivnica." }, "userUsingTwoStep": { "message": "Ovaj korisnik upotrebljava prijavu u dva koraka za zaštitu svog računa." @@ -3781,7 +3835,7 @@ } }, "unlinkedSso": { - "message": "Unlinked SSO." + "message": "SSO odspojen." }, "unlinkedSsoUser": { "message": "Odspojen SSO za korisnika $ID$.", @@ -3832,22 +3886,22 @@ "message": "Uređaj" }, "loginStatus": { - "message": "Login status" + "message": "Status prijave" }, "firstLogin": { - "message": "First login" + "message": "Prva prijava" }, "trusted": { - "message": "Trusted" + "message": "Pouzdan" }, "needsApproval": { - "message": "Needs approval" + "message": "Zahtjeva odobrenje" }, "areYouTryingtoLogin": { - "message": "Are you trying to log in?" + "message": "Pokušavaš li se prijaviti?" }, "logInAttemptBy": { - "message": "Login attempt by $EMAIL$", + "message": "$EMAIL$ se pokušava prijaviti", "placeholders": { "email": { "content": "$1", @@ -3856,22 +3910,22 @@ } }, "deviceType": { - "message": "Device Type" + "message": "Vrsta uređaja" }, "ipAddress": { - "message": "IP Address" + "message": "IP Adresa" }, "confirmLogIn": { - "message": "Confirm login" + "message": "Potvrdi prijavu" }, "denyLogIn": { - "message": "Deny login" + "message": "Odbij prijavu" }, "thisRequestIsNoLongerValid": { - "message": "This request is no longer valid." + "message": "Ovaj zahtjev više nije valjan." }, "logInConfirmedForEmailOnDevice": { - "message": "Login confirmed for $EMAIL$ on $DEVICE$", + "message": "Prijava za $EMAIL$ potvrđena na uređaju $DEVICE$", "placeholders": { "email": { "content": "$1", @@ -3884,16 +3938,16 @@ } }, "youDeniedALogInAttemptFromAnotherDevice": { - "message": "You denied a login attempt from another device. If this really was you, try to log in with the device again." + "message": "Odbijena je prijava na drugom uređaju. Ako si ovo stvarno ti, pokušaj se ponovno prijaviti uređajem." }, "loginRequestHasAlreadyExpired": { - "message": "Login request has already expired." + "message": "Zahtjev za prijavu je već istekao." }, "justNow": { - "message": "Just now" + "message": "Upravo" }, "requestedXMinutesAgo": { - "message": "Requested $MINUTES$ minutes ago", + "message": "Zatraženo prije $MINUTES$ minute/a", "placeholders": { "minutes": { "content": "$1", @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Postavi pravila sigurnosti koje mora zadovoljiti generator lozinki." }, - "passwordGeneratorPolicyInEffect": { - "message": "Jedna ili više organizacijskih pravila utječe na postavke generatora." - }, "masterPasswordPolicyInEffect": { "message": "Jedna ili više organizacijskih pravila zahtijeva da tvoja glavna lozinka ispunjava sljedeće uvjete:" }, @@ -5792,17 +5843,17 @@ "message": "Greška" }, "decryptionError": { - "message": "Decryption error" + "message": "Pogreška pri dešifriranju" }, "couldNotDecryptVaultItemsBelow": { - "message": "Bitwarden could not decrypt the vault item(s) listed below." + "message": "Bitwarden nije mogao dešifrirati sljedeće stavke trezora." }, "contactCSToAvoidDataLossPart1": { - "message": "Contact customer success", + "message": "Kontaktiraj službu za korisnike", "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": "kako bi izbjegli gubitak podataka.", "description": "This is part of a larger sentence. The full sentence will read 'Contact customer success to avoid additional data loss.'" }, "accountRecoveryManageUsers": { @@ -6666,15 +6717,6 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "Što želiš generirati?" - }, - "passwordType": { - "message": "Tip lozinke" - }, - "regenerateUsername": { - "message": "Ponovno generiraj korisničko ime" - }, "generateUsername": { "message": "Generiraj korisničko ime" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Tip korisničkog imena" - }, "plusAddressedEmail": { "message": "Plus adresa e-pošte", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Koristi konfigurirani catch-all sandučić svoje domene." }, + "useThisEmail": { + "message": "Koristi ovu e-poštu" + }, "random": { "message": "Nasumično", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Naziv poslužitelja", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "Token za API pristup" - }, "deviceVerification": { "message": "Provjera uređaja" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "Nema zbirke" }, - "canView": { - "message": "Može vidjeti" - }, - "canViewExceptPass": { - "message": "Može vidjeti, osim lozinke" - }, - "canEdit": { - "message": "Može urediti" - }, - "canEditExceptPass": { - "message": "Može urediti, osim lozinke" - }, "noCollectionsAdded": { "message": "Niti jedna zbirka nije dodana" }, @@ -8284,31 +8311,31 @@ "message": "Pouzdani uređaji" }, "memberDecryptionOptionTdeDescPart1": { - "message": "Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The", + "message": "Članovi neće trebati glavnu lozinku kada se prijavljuju putem SSO-a. Glavnu lozinku zamjenjuje ključem za šifriranje pohranjen na uređaju, što taj uređaj čini pouzdanim. Prvi uređaj na kojem član kreira svoj račun i s kojeg se prijavi bit će pouzdan. Nove uređaje morat će odobriti ili postojeći pouzdani uređaj ili administrator. Pravilo", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescLink1": { - "message": "single organization", + "message": "isključive organizacije,", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescPart2": { - "message": "policy,", + "message": "", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescLink2": { - "message": "SSO required", + "message": "obavezne SSO prijave", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescPart3": { - "message": "policy, and", + "message": "i", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescLink3": { - "message": "account recovery administration", + "message": "administracije oporavka računa", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescPart4": { - "message": "policy will turn on when this option is used.", + "message": "biti će uključeni ako se koristi ova opcija.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "orgPermissionsUpdatedMustSetPassword": { @@ -8387,16 +8414,16 @@ "message": "Odobri zahtjev" }, "deviceApproved": { - "message": "Device approved" + "message": "Uređaj odobren" }, "deviceRemoved": { - "message": "Device removed" + "message": "Uređaj uklonjen" }, "removeDevice": { - "message": "Remove device" + "message": "Ukloni uređaj" }, "removeDeviceConfirmation": { - "message": "Are you sure you want to remove this device?" + "message": "Sigurno želiš ukoniti ovaj uređaj?" }, "noDeviceRequests": { "message": "Nema zahtjeva na čekanju" @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Omogući brisanje zbirki samo vlasnicima i adminima" }, + "limitItemDeletionDesc": { + "message": "Ograniči brisanje stavke samo članovima koji imaju dozvolu „Moguće upravljanje”" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Vlasnici i admini mogu upravljati svim zbirkama i stavkama" }, @@ -8656,9 +8686,6 @@ "message": "URL vlastitog poslužitelja", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domene" - }, "alreadyHaveAccount": { "message": "Već imaš račun?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "Nemaš pristup za upravljanje ovom zbirkom." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Neodstaju prava „Moguće upravljanje”" + "grantManageCollectionWarningTitle": { + "message": "Nedostaju prava za upravljanje zbirkom" }, - "grantAddAccessCollectionWarning": { - "message": "Dodijeli prava „Moguće upravljanje” kako bi dozvolili puni pristup zbirkama uključujući brisanje." + "grantManageCollectionWarning": { + "message": "Dodijeli potpuna prava upravljanja zbirkom što uključuje i brisanje." }, "grantCollectionAccess": { "message": "Dodijeli grupama i članovima pristup ovoj zbirki." @@ -9286,7 +9313,7 @@ "message": "mjesečno po korisniku" }, "monthPerMemberBilledAnnually": { - "message": "month per member billed annually" + "message": "mjesečno po članu, naplata godišnje" }, "seats": { "message": "Mjesta" @@ -9437,16 +9464,16 @@ "message": "Ažurirane porezne informacije" }, "billingInvalidTaxIdError": { - "message": "Invalid tax ID, if you believe this is an error please contact support." + "message": "Neispravni porezni broj. Ako misliš da je broj ispravan, kontaktiraj podršku." }, "billingTaxIdTypeInferenceError": { - "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + "message": "Nismo mogli provjeriti tvoj porezni broj. Ako misliš da je broj ispravan, kontaktiraj podršku." }, "billingPreviewInvalidTaxIdError": { - "message": "Invalid tax ID, if you believe this is an error please contact support." + "message": "Neispravni porezni broj. Ako misliš da je broj ispravan, kontaktiraj podršku." }, "billingPreviewInvoiceError": { - "message": "An error occurred while previewing the invoice. Please try again later." + "message": "Greška kod pregleda fakture. Pokušaj ponovno kasnije." }, "unverified": { "message": "Nepotvrđeno" @@ -9809,13 +9836,13 @@ "message": "Algoritam ključa" }, "sshPrivateKey": { - "message": "Private key" + "message": "Privatni ključ" }, "sshPublicKey": { - "message": "Public key" + "message": "Javni ključ" }, "sshFingerprint": { - "message": "Fingerprint" + "message": "Otisak prsta" }, "sshKeyFingerprint": { "message": "Otisak prsta" @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Šifra uplate" }, + "cannotRemoveViewOnlyCollections": { + "message": "S dopuštenjima samo za prikaz ne možeš ukloniti zbirke: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Važna napomena" }, @@ -10110,13 +10146,13 @@ "message": "Ukloni članove" }, "devices": { - "message": "Devices" + "message": "Uređaji" }, "deviceListDescription": { - "message": "Your account was logged in to each of the devices below. If you do not recognize a device, remove it now." + "message": "Tvoj račun je prijavljen na svakom od ovih uređaja. Ako ne prepoznaješ uređaj, odmah ga ukloni." }, "deviceListDescriptionTemp": { - "message": "Your account was logged in to each of the devices below." + "message": "Tvoj račun je prijavljen na svakom od ovih uređaja." }, "claimedDomains": { "message": "Potvrđene domene" @@ -10204,7 +10240,7 @@ "message": "Naziv organizacije ne može biti duži od 50 znakova." }, "resellerRenewalWarningMsg": { - "message": "Your subscription will renew soon. To ensure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "message": "Tvoja će se pretplata uskoro obnoviti. Za neprekinutu uslugu, kontaktiraj $RESELLER$ za potvrdu obnove prije $RENEWAL_DATE$.", "placeholders": { "reseller": { "content": "$1", @@ -10217,7 +10253,7 @@ } }, "resellerOpenInvoiceWarningMgs": { - "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To ensure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "message": "Za tvoju je pretplatu $ISSUED_DATE$ izdana faktura. Za neprekinutu uslugu, kontaktiraj $RESELLER$ za potvrdu obnove prije $DUE_DATE$.", "placeholders": { "reseller": { "content": "$1", @@ -10234,7 +10270,7 @@ } }, "resellerPastDueWarningMsg": { - "message": "The invoice for your subscription has not been paid. To ensure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "message": "Faktura za tvoju pretplatu nije plaćena. Za neprekinutu uslugu, kontaktiraj $RESELLER$ za potvrdu obnovu prije $GRACE_PERIOD_END$.", "placeholders": { "reseller": { "content": "$1", @@ -10247,18 +10283,67 @@ } }, "restartOrganizationSubscription": { - "message": "Organization subscription restarted" + "message": "Organizacijska pretplata ponovno pokrenuta" }, "restartSubscription": { - "message": "Restart your subscription" + "message": "Ponovno pokreni pretplatu" }, "suspendedManagedOrgMessage": { - "message": "Contact $PROVIDER$ for assistance.", + "message": "Kontaktiraj $PROVIDER$ za pomoć.", "placeholders": { "provider": { "content": "$1", "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administratori sada imaju mogućnost obrisati članski račun koji pripada potvrđenoj domeni." + }, + "deleteManagedUserWarningDesc": { + "message": "Ovo će obrisati članski račun uključujući sve stavke u trezoru. Ovo zamjenjuje prethodnu radnju „Ukloni”." + }, + "deleteManagedUserWarning": { + "message": "Brisanje je nova radnja!" + }, + "seatsRemaining": { + "message": "Imaš još $REMAINING$ preostalih sjedišta od $TOTAL$ dodijeljenih ovog organizaciji. Kontaktiraj svog pružatelja usluge za upravljanje pretplatom.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Postojeća organizacija" + }, + "selectOrganizationProviderPortal": { + "message": "Odaberi organizaciju koju želiš dodati na svoj portal pružatelja usluga." + }, + "noOrganizations": { + "message": "Nema organizaciji za prikaz" + }, + "yourProviderSubscriptionCredit": { + "message": "Tvoja pretplata davatelja usluga dobit će kredit za preostalo vrijeme u organizacijskoj pretplati." + }, + "doYouWantToAddThisOrg": { + "message": "IP Adresa", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Postojeća organizacija dodana" + }, + "assignedExceedsAvailable": { + "message": "Dodijeljene licence premašuju dostupne licence." } } diff --git a/apps/web/src/locales/hu/messages.json b/apps/web/src/locales/hu/messages.json index 76587eacc32..bdc55b96d3c 100644 --- a/apps/web/src/locales/hu/messages.json +++ b/apps/web/src/locales/hu/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Mappa szerkesztése" }, + "newFolder": { + "message": "Új mappa" + }, + "folderName": { + "message": "Mappanév" + }, + "folderHintText": { + "message": "Mappa beágyazása a szülőmappa nevének hozzáadásával, majd egy “/” karakterrel. Példa: Közösségi/Fórumok" + }, + "deleteFolderPermanently": { + "message": "Biztosan véglegesen törlésre kerüljön ez a mappa?" + }, "baseDomain": { "message": "Alap domain", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Elem neve" }, - "cannotRemoveViewOnlyCollections": { - "message": "Nem távolíthatók el a csak megtekintési engedéllyel bíró gyűjtemények: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "Példa:", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "A bejelentkezés elindításra került." }, + "logInRequestSent": { + "message": "A kérés elküldésre került." + }, "submit": { "message": "Elküldés" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "A rendszer értesítést küldött az eszközre." }, + "notificationSentDevicePart1": { + "message": "A Bitwarden zárolás feloldása az eszközön vagy: " + }, + "areYouTryingToAccessYourAccount": { + "message": "A fiókhoz próbálunk hozzáférni?" + }, + "accessAttemptBy": { + "message": "Bejelentkezési kísérlet $EMAIL$ segítségével", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Hozzáférés megerősítése" + }, + "denyAccess": { + "message": "Hozzáférés megtagadása" + }, + "notificationSentDeviceAnchor": { + "message": "webalkalmazás" + }, + "notificationSentDevicePart2": { + "message": "Jóváhagyás előtt győződjünk meg arról, hogy az ujjlenyomat kifejezés megegyezik az alábbi kifejezéssel." + }, + "notificationSentDeviceComplete": { + "message": "Oldjuk fel a Bitwarden zárolását az eszközön. Jóváhagyás előtt győződjünk meg arról, hogy az ujjlenyomat kifejezés megegyezik az alábbi kifejezéssel." + }, "aNotificationWasSentToYourDevice": { "message": "Egy értesítés lett elküldve az eszközre." }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Ellenőrizzük, hogy a széf feloldásra került és az ujjlenyomat kifejezés egyezik a másik eszközön levővel." - }, "versionNumber": { "message": "Verzió: $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Félreérthető karakterek mellőzése", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Jelszó újragenerálása" - }, "length": { "message": "Hossz" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Veszélyes terület" }, - "dangerZoneDesc": { - "message": "Óvatosan! Ezeket a műveleteket nem lehet visszaállítani." - }, - "dangerZoneDescSingular": { - "message": "Óvatosan! Ezeket a műveleteket nem lehet visszaállítani." - }, "deauthorizeSessions": { "message": "Munkamenetek hitelesítésének eldobása" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "A folytatásban s felhasználó kiléptetésre kerül az aktuális munkamenetből, szükséges az ismételt bejelentkezés. Ismételten megjelenik a kétlépcsős bejelentkezés, ha az engedélyezett. Más eszközök aktív munkamenetei akár egy óráig is aktívak maradhatnak." }, + "newDeviceLoginProtection": { + "message": "Új eszköz bejelentkezés" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Az új eszköz bejelentkezési védelmének kikapcsolása" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Az új eszköz bejelentkezési védelmének bekapcsolása" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Folytassuk az alábbiakkal a Bitwarden által küldendő ellenőrző emailek kikapcsolásához, amikor új eszközről jelentkezünk be." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Folytassuk az alábbiakkal a Bitwarden által küldendő ellenőrző emailek bekapcsolásához, amikor új eszközről jelentkezünk be." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "Ha az új eszköz bejelentkezési védelme ki van kapcsolva, a mesterjelszó birtokában bárki hozzáférhet fiókhoz bármilyen eszközről. Ha meg szeretnénk védeni fiókot ellenőrző emailek nélkül, állítsunk be kétlépcsős bejelentkezést." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "Az új eszköz bejelentkezés védelmi módosítások mentésre kerültek." + }, "sessionsDeauthorized": { "message": "Az összes munkamenet hitelesítése eldobásra került." }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Kezelés" }, - "canManage": { - "message": "Kezelhet" + "manageCollection": { + "message": "Gyűjtemény kezelése" + }, + "viewItems": { + "message": "Elemek megtekintése" + }, + "viewItemsHidePass": { + "message": "Elemek megtekintése, rejtett jelszavak" + }, + "editItems": { + "message": "Elemek szerkesztése" + }, + "editItemsHidePass": { + "message": "Elemek szerkesztése, rejtett jelszavak" }, "disable": { "message": "Letiltás" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "Probléma lépett fel a biztonsági kulcs olvasásakor. Próbáljuk újra." }, - "twoFactorWebAuthnWarning": { - "message": "A platform korlátozások miatt nem lehetséges minden Bitwarden alkalmazásban YubiKey eszközt használni. Engedélyezzünk egy másik kétlépcsős bejelentkezés szolgáltatót, hogy hozzáférhessünk a fiókhoz akkor is, ha a YubiKey nem használható. Támogatott platformok:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Web széf és böngésző kiegészítők asztali gépen / laptopon engedélyezett U2F böngészővel (Chrome, Opera, Vivaldi, vagy Firefox bekapcsolt FIDO U2F-fel)." + "twoFactorWebAuthnWarning1": { + "message": "A platform korlátozások miatt nem lehetséges minden Bitwarden alkalmazásban a WebAuthn használata. Be kell üzemelni egy másik kétlépcsős bejelentkezés szolgáltatót, hogy hozzáférhessünk a fiókhoz akkor is, ha a WebAuthn nem használható." }, "twoFactorRecoveryYourCode": { "message": "Bitwarden kétlépcsős bejelentkezés helyreállító kód" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "A minimális követelmények beállítása a jelszó generáló konfigurációhoz." }, - "passwordGeneratorPolicyInEffect": { - "message": "Egy vagy több szervezeti szabály érinti a generátor beállításokat." - }, "masterPasswordPolicyInEffect": { "message": "Egy vagy több szervezeti szabály előírja a mesterjelszóhoz a következő követelményeket:" }, @@ -6666,15 +6717,6 @@ "message": "Generátor", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "Mit szeretnénk generálni?" - }, - "passwordType": { - "message": "Jelszótípus" - }, - "regenerateUsername": { - "message": "Felhasználónév ismételt generálása" - }, "generateUsername": { "message": "Felhasználónév generálása" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Felhasználónév típusa" - }, "plusAddressedEmail": { "message": "További címzési email cím", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Használjuk a tartomány konfigurált összes befogási bejövő postaládát." }, + "useThisEmail": { + "message": "Ezen email használata" + }, "random": { "message": "Véletlen", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Kiszolglónév", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API hozzáférési vezérjel" - }, "deviceVerification": { "message": "Eszköz ellenőrzés" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "Nincs gyűjtemény." }, - "canView": { - "message": "Megtekintheti" - }, - "canViewExceptPass": { - "message": "Megtekintheti, kivéve a jelszavakat" - }, - "canEdit": { - "message": "Szerkesztheti" - }, - "canEditExceptPass": { - "message": "Szerkesztheti, kivéve a jelszavakat" - }, "noCollectionsAdded": { "message": "Nem lett gyűjtemény hozzáadva." }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "A gyűjtemény törlésének korlátozása tulajdonosokra és adminisztrátorokra" }, + "limitItemDeletionDesc": { + "message": "Az elemek törlésének korlátozása a Kezelheti jogosultsággal rendelkező tagokra" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Saját üzemeltetésű szerver webcím", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Áldomain" - }, "alreadyHaveAccount": { "message": "Van már saját fiók?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "Nincs jogosultság ennek a gyűjteménynek a kezelésére." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Hiányzó gyűjtemény kezelési engedélyek" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Adjunk gyűjtemény kezelési engedélyeket, hogy lehetővé tegyük a teljes gyűjtemény kezelést, beleértve a gyűjtemény törlését is." }, "grantCollectionAccess": { "message": "Adjunk hozzáférést csoportoknak vagy személyeknek eennél a gyűjteménynél." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Leíró kód" }, + "cannotRemoveViewOnlyCollections": { + "message": "Nem távolíthatók el a csak megtekintési engedéllyel bíró gyűjtemények: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Fontos megjegyzés" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Az adminisztrátorok mostantól törölhetik az igényelt tartományhoz tartozó tagi fiókokat." + }, + "deleteManagedUserWarningDesc": { + "message": "Ez a művelet törli a tagi fiókot, beleértve a tárolókban lévő összes elemet. Ez felváltja az előző Eltávolítás műveletet." + }, + "deleteManagedUserWarning": { + "message": "A törlés új művelet!" + }, + "seatsRemaining": { + "message": "$REMAINING$ hely maradt a szervezethez rendelt $TOTAL$ helyből. Az előfizetés kezeléséhez forduljunk a szolgáltatóhoz.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Létező szervezet" + }, + "selectOrganizationProviderPortal": { + "message": "Válasszuk ki a szolgáltatói portálhoz hozzáadni kívánt szervezetet." + }, + "noOrganizations": { + "message": "Nincsenek listázható szervezetek." + }, + "yourProviderSubscriptionCredit": { + "message": "A szolgáltatói előfizetés jóváírást kap a szervezet előfizetésből hátralévő időre." + }, + "doYouWantToAddThisOrg": { + "message": "Hozzáadásra kerüljön ez a szervezet $PROVIDER$ szolgáltatáshoz?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "A létező szervezet hozzáadásra került." + }, + "assignedExceedsAvailable": { + "message": "A hozzárendelt helyek száma meghaladja a rendelkezésre álló helyek számát." } } diff --git a/apps/web/src/locales/id/messages.json b/apps/web/src/locales/id/messages.json index afaa94f8b5e..565cb743eab 100644 --- a/apps/web/src/locales/id/messages.json +++ b/apps/web/src/locales/id/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Edit Folder" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Domain dasar", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "cth.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Log in initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Kirim" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "Versi $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Buat Ulang Sandi" - }, "length": { "message": "Panjang" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Zona Bahaya" }, - "dangerZoneDesc": { - "message": "Hati-hati, tindakan ini tidak bisa dibatalkan!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Batalkan Otorisasi Sesi" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Melanjutkan juga akan mengeluarkan Anda dari sesi saat ini, mengharuskan Anda untuk masuk kembali. Anda juga akan diminta untuk masuk dua langkah lagi, jika diaktifkan. Sesi aktif di perangkat lain dapat terus aktif hingga satu jam." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "Semua Sesi Dicabut Izinnya" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Kelola" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Nonaktifkan" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "Ada masalah saat membaca kunci keamanan. Coba lagi." }, - "twoFactorWebAuthnWarning": { - "message": "Karena keterbatasan platform, WebAuthn tidak dapat digunakan di semua aplikasi Bitwarden. Anda harus mengaktifkan penyedia proses masuk dua langkah lainnya sehingga Anda dapat mengakses akun Anda saat WebAUthn tidak dapat digunakan. Platform yang didukung:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Brankas web dan ekstensi browser di desktop / laptop dengan browser yang mendukung WebAuthn (Chrome, Opera, Vivaldi, atau Firefox dengan FIDO U2F diaktifkan)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Kode pemulihan masuk dua langkah Bitwarden Anda" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Tetapkan persyaratan minimum untuk konfigurasi pembuat kata sandi." }, - "passwordGeneratorPolicyInEffect": { - "message": "Satu atau beberapa kebijakan organisasi memengaruhi pengaturan generator Anda." - }, "masterPasswordPolicyInEffect": { "message": "Satu atau lebih kebijakan organisasi memerlukan kata sandi utama Anda untuk memenuhi persyaratan berikut:" }, @@ -6666,15 +6717,6 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Jenis kata sandi" - }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Jenis nama pengguna" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Use your domain's configured catch-all inbox." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Acak", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Hostname", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API access token" - }, "deviceVerification": { "message": "Verifikasi Perangkat" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "No collection" }, - "canView": { - "message": "Can view" - }, - "canViewExceptPass": { - "message": "Can view, except passwords" - }, - "canEdit": { - "message": "Can edit" - }, - "canEditExceptPass": { - "message": "Can edit, except passwords" - }, "noCollectionsAdded": { "message": "No collections added" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domain" - }, "alreadyHaveAccount": { "message": "Already have an account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/it/messages.json b/apps/web/src/locales/it/messages.json index 4b708de2dd6..d05dec8e603 100644 --- a/apps/web/src/locales/it/messages.json +++ b/apps/web/src/locales/it/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Modifica cartella" }, + "newFolder": { + "message": "Nuova cartella" + }, + "folderName": { + "message": "Nome cartella" + }, + "folderHintText": { + "message": "Annida una cartella aggiungendo il nome della cartella superiore seguito da un “/”. Esempio: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Sei sicuro di voler eliminare definitivamente questo cartella?" + }, "baseDomain": { "message": "Dominio di base", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Nome elemento" }, - "cannotRemoveViewOnlyCollections": { - "message": "Non puoi rimuovere raccolte con i soli permessi di visualizzazione: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "es.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Login avviato" }, + "logInRequestSent": { + "message": "Richiesta inviata" + }, "submit": { "message": "Invia" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "Una notifica è stata inviata al tuo dispositivo." }, + "notificationSentDevicePart1": { + "message": "Sblocca Bitwarden sul tuo dispositivo o su " + }, + "areYouTryingToAccessYourAccount": { + "message": "Stai cercando di accedere al tuo account?" + }, + "accessAttemptBy": { + "message": "Tentativo di accesso di $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Conferma accesso" + }, + "denyAccess": { + "message": "Nega accesso" + }, + "notificationSentDeviceAnchor": { + "message": "app web" + }, + "notificationSentDevicePart2": { + "message": "Assicurarsi che la frase di impronta digitale corrisponda a quella sottostante prima dell'approvazione." + }, + "notificationSentDeviceComplete": { + "message": "Sblocca Bitwarden sul tuo dispositivo. Assicurati che la frase di impronta digitale corrisponda a quella sottostante prima di approvare." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "Versione $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Rigenera password" - }, "length": { "message": "Lunghezza" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Zona pericolosa" }, - "dangerZoneDesc": { - "message": "Attento, queste azioni non sono reversibili!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Annulla autorizzazione sessioni" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Inoltre, procedere ti farà uscire dalla sessione corrente, richiedendoti di accedere. Se attivata, dovrai completare la verifica in due passaggi di nuovo. Le sessioni attive su altri dispositivi potrebbero continuare a rimanere attive per un massimo di un'ora." }, + "newDeviceLoginProtection": { + "message": "Accesso nuovo dispositivo" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Disattiva la nuova protezione di accesso del dispositivo" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Attiva la nuova protezione di accesso del dispositivo" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Procedi qui sotto per disattivare le e-mail di verifica che Bitwarden invia quando accedi da un nuovo dispositivo." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Procedi qui sotto per far sì che Bitwarden invii e-mail di verifica quando accedi da un nuovo dispositivo." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "Con la nuova protezione di accesso del dispositivo disattivata, chiunque con la tua parola d'accesso principale può accedere al tuo account da qualsiasi dispositivo. Per proteggere il tuo account senza e-mail di verifica, imposta l'accesso in due passaggi." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "Modifiche alla protezione del nuovo dispositivo salvate" + }, "sessionsDeauthorized": { "message": "Tutte le sessioni revocate" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Gestisci" }, - "canManage": { - "message": "Può gestire" + "manageCollection": { + "message": "Gestisci collezione" + }, + "viewItems": { + "message": "Vedi voci" + }, + "viewItemsHidePass": { + "message": "Vedi elementi, parole d'accesso nascoste" + }, + "editItems": { + "message": "Modifica voci" + }, + "editItemsHidePass": { + "message": "Modifica elementi, parole d'accesso nascoste" }, "disable": { "message": "Disattiva" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "Si è verificato un problema durante la lettura della chiave di sicurezza. Riprova." }, - "twoFactorWebAuthnWarning": { - "message": "A causa di limitazioni della piattaforma, WebAuthn non può essere utilizzato su tutte le app Bitwarden. Dovresti abilitare un altro metodo di verifica in due passaggi per accedere al tuo account anche quando WebAuthn non può essere usato. Piattaforme supportate:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Cassaforte Web ed estensione per il browser desktop/laptop con un browser abilitato per WebAuthn (Chrome, Opera, Vivaldi o Firefox con FIDO U2F abilitato)." + "twoFactorWebAuthnWarning1": { + "message": "A causa delle limitazioni della piattaforma, WebAuthn non può essere usato in tutte le applicazioni Bitwarden. È necessario impostare un altro fornitore d'accesso in due passaggi in modo da poter accedere al tuo account quando WebAuthn non può essere usato." }, "twoFactorRecoveryYourCode": { "message": "Il tuo codice di recupero Bitwarden per la verifica in due passaggi" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Imposta requisiti minimi di complessità per il generatore di password." }, - "passwordGeneratorPolicyInEffect": { - "message": "Una o più politiche dell'organizzazione stanno influenzando le impostazioni del tuo generatore." - }, "masterPasswordPolicyInEffect": { "message": "Una o più politiche dell'organizzazione richiedono che la tua password principale soddisfi questi requisiti:" }, @@ -6666,15 +6717,6 @@ "message": "Generatore", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "Cosa vuoi generare?" - }, - "passwordType": { - "message": "Tipo di password" - }, - "regenerateUsername": { - "message": "Rigenera nome utente" - }, "generateUsername": { "message": "Genera nome utente" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Tipo di nome utente" - }, "plusAddressedEmail": { "message": "Indirizzo email alternativo", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Usa la casella di posta catch-all di dominio." }, + "useThisEmail": { + "message": "Usa questa e-mail" + }, "random": { "message": "Casuale", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Nome host", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "Token di accesso API" - }, "deviceVerification": { "message": "Verifica del dispositivo" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "Nessuna raccolta" }, - "canView": { - "message": "Può visualizzare" - }, - "canViewExceptPass": { - "message": "Può visualizzare, eccetto le password" - }, - "canEdit": { - "message": "Può modificare" - }, - "canEditExceptPass": { - "message": "Può modificare, eccetto le password" - }, "noCollectionsAdded": { "message": "Nessuna raccolta aggiunta" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limita l'eliminazione di elementi ai membri con il permesso di gestione" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Proprietari e amministratori possono gestire tutte le raccolte e gli elementi" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Dominio alias" - }, "alreadyHaveAccount": { "message": "Hai già un account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "Non hai accesso alla gestione di questa raccolta." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Autorizzazione Può gestire mancante" + "grantManageCollectionWarningTitle": { + "message": "Permessi di gestione raccolte mancanti" }, - "grantAddAccessCollectionWarning": { - "message": "Concedi l'autorizzazione Può gestire per consentire la gestione completa della raccolta, inclusa l'eliminazione della raccolta." + "grantManageCollectionWarning": { + "message": "Concedi i permessi di gestione della collezione per consentire la gestione completa della raccolta, inclusa l'eliminazione della raccolta." }, "grantCollectionAccess": { "message": "Consenti a gruppi o membri di accedere a questa raccolta." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "Non puoi rimuovere raccolte con i soli permessi di visualizzazione: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Gli amministratori ora hanno la possibilità di eliminare gli account membri che appartengono a un dominio rivendicato." + }, + "deleteManagedUserWarningDesc": { + "message": "Questa azione eliminerà l'account membro includendo tutti gli elementi nella sua cassaforte. Questo sostituisce l'azione precedente Rimuovi." + }, + "deleteManagedUserWarning": { + "message": "Eliminare è una nuova azione!" + }, + "seatsRemaining": { + "message": "Hai $REMAINING$ posti di $TOTAL$ posti assegnati a quest'organizzazione. Contatta il provider per gestire l'abbonamento.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Organizzazione esistente" + }, + "selectOrganizationProviderPortal": { + "message": "Seleziona un'organizzazione da aggiungere al tuo portale fornitori." + }, + "noOrganizations": { + "message": "Non ci sono organizzazioni da elencare" + }, + "yourProviderSubscriptionCredit": { + "message": "Il tuo abbonamento fornitore riceverà un credito per qualsiasi tempo rimanente nell'abbonamento dell'organizzazione." + }, + "doYouWantToAddThisOrg": { + "message": "Vuoi aggiungere questa organizzazione a $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Aggiunta organizzazione esistente" + }, + "assignedExceedsAvailable": { + "message": "I posti assegnati superano i posti disponibili." } } diff --git a/apps/web/src/locales/ja/messages.json b/apps/web/src/locales/ja/messages.json index 1a07ff92dac..dbe3ceb6eaf 100644 --- a/apps/web/src/locales/ja/messages.json +++ b/apps/web/src/locales/ja/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "フォルダーを編集" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "ベースドメイン", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "アイテム名" }, - "cannotRemoveViewOnlyCollections": { - "message": "表示のみの権限が与えられているコレクションを削除することはできません: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "例:", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "ログイン開始" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "送信" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "デバイスに通知を送信しました。" }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "お使いのデバイスに通知が送信されました" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "アカウントがロック解除されていることと、フィンガープリントフレーズが他の端末と一致していることを確認してください" - }, "versionNumber": { "message": "バージョン $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "あいまいな文字を避ける", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "パスワードの再生成" - }, "length": { "message": "長さ" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "危険な操作" }, - "dangerZoneDesc": { - "message": "これらの操作はやり直せないため注意してください!" - }, - "dangerZoneDescSingular": { - "message": "この操作は元に戻せないため注意してください!" - }, "deauthorizeSessions": { "message": "セッションの承認を取り消す" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "次に進むと現在のセッションからログアウトし二段階認証を含め再度ログインが必要になります。他のデバイスでのセッションは1時間程度維持されます。" }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "全てのセッションを無効化" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "管理" }, - "canManage": { - "message": "管理可能" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "無効化" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "セキュリティキーの読み取り中に問題が発生しました。もう一度やり直して下さい。" }, - "twoFactorWebAuthnWarning": { - "message": "プラットフォームの制限により、WebAuthnはBitwardenの全てのアプリケーションで使用できるわけではありません。WebAuthnが使用できない場合に備えて、他の二段階認証プロバイダを有効化しておくことをおすすめします。サポートされているプラットフォーム:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "WebAuthn対応ブラウザ(FIDO U2F が有効な Chrome、Opera、Vivaldi、Firefox)を搭載したデスクトップ/ノートパソコンで、WebVaultとブラウザ拡張機能を使用します。" + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "二段階認証のリカバリーコード" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "パスワード生成の最低要件を設定する。" }, - "passwordGeneratorPolicyInEffect": { - "message": "組織の要件がパスワード生成の設定に影響しています。" - }, "masterPasswordPolicyInEffect": { "message": "組織が求めるマスターパスワードの要件は:" }, @@ -6666,15 +6717,6 @@ "message": "ジェネレーター", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "何を生成しますか?" - }, - "passwordType": { - "message": "パスワードの種類" - }, - "regenerateUsername": { - "message": "ユーザー名を再生成" - }, "generateUsername": { "message": "ユーザー名を生成" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "ユーザー名の種類" - }, "plusAddressedEmail": { "message": "プラス付きのメールアドレス", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "ドメインに設定されたキャッチオール受信トレイを使用します。" }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "ランダム", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "ホスト名", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API アクセストークン" - }, "deviceVerification": { "message": "デバイス認証" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "コレクションなし" }, - "canView": { - "message": "閲覧可能" - }, - "canViewExceptPass": { - "message": "パスワード以外は閲覧可能" - }, - "canEdit": { - "message": "編集可能" - }, - "canEditExceptPass": { - "message": "パスワード以外は編集可能" - }, "noCollectionsAdded": { "message": "コレクションが追加されていません" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "コレクションの削除を所有者と管理者のみに制限" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "所有者と管理者はすべてのコレクションとアイテムを管理できます" }, @@ -8656,9 +8686,6 @@ "message": "自己ホスト型サーバー URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "エイリアスドメイン" - }, "alreadyHaveAccount": { "message": "既にアカウントをお持ちですか?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "このコレクションを管理する権限がありません。" }, - "grantAddAccessCollectionWarningTitle": { - "message": "「管理可能」権限がありません" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "コレクションの削除を含む完全なコレクション管理を許可するには「管理可能」権限を許可してください。" + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "グループまたはメンバーにこのコレクションへのアクセスを許可します。" @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "表示のみの権限が与えられているコレクションを削除することはできません: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/ka/messages.json b/apps/web/src/locales/ka/messages.json index 64df2c2111c..92c64db7f56 100644 --- a/apps/web/src/locales/ka/messages.json +++ b/apps/web/src/locales/ka/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "საქაღალდის ჩასწორება" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "დომენის ბაზა", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "მაგ.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "ავტორიზაცია დაწყებულია" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "გადაცემა" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "შეტყობინება გამოიგზავნა თქვენი ტელეფონის მისამართით." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "ვერსია $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Regenerate password" - }, "length": { "message": "Length" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Danger zone" }, - "dangerZoneDesc": { - "message": "Careful, these actions are not reversible!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Deauthorize sessions" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Proceeding will also log you out of your current session, requiring you to log back in. You will also be prompted for two-step login again, if set up. Active sessions on other devices may continue to remain active for up to one hour." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "All sessions deauthorized" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Manage" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Turn off" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "There was a problem reading the security key. Try again." }, - "twoFactorWebAuthnWarning": { - "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used. Supported platforms:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Web vault and browser extensions on a desktop/laptop with a WebAuthn supported browser (Chrome, Opera, Vivaldi, or Firefox with FIDO U2F turned on)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Your Bitwarden two-step login recovery code" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Set requirements for password generator." }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organization policies are affecting your generator settings." - }, "masterPasswordPolicyInEffect": { "message": "One or more organization policies require your master password to meet the following requirements:" }, @@ -6666,15 +6717,6 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Use your domain's configured catch-all inbox." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Random", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Hostname", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API access token" - }, "deviceVerification": { "message": "Device verification" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "No collection" }, - "canView": { - "message": "Can view" - }, - "canViewExceptPass": { - "message": "Can view, except passwords" - }, - "canEdit": { - "message": "Can edit" - }, - "canEditExceptPass": { - "message": "Can edit, except passwords" - }, "noCollectionsAdded": { "message": "No collections added" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domain" - }, "alreadyHaveAccount": { "message": "Already have an account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/km/messages.json b/apps/web/src/locales/km/messages.json index 486f01ce2cb..7e6f614b9c8 100644 --- a/apps/web/src/locales/km/messages.json +++ b/apps/web/src/locales/km/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Edit folder" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Base domain", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "ex.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Log in initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Submit" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "Version $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Regenerate password" - }, "length": { "message": "Length" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Danger zone" }, - "dangerZoneDesc": { - "message": "Careful, these actions are not reversible!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Deauthorize sessions" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Proceeding will also log you out of your current session, requiring you to log back in. You will also be prompted for two-step login again, if set up. Active sessions on other devices may continue to remain active for up to one hour." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "All sessions deauthorized" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Manage" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Turn off" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "There was a problem reading the security key. Try again." }, - "twoFactorWebAuthnWarning": { - "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used. Supported platforms:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Web vault and browser extensions on a desktop/laptop with a WebAuthn supported browser (Chrome, Opera, Vivaldi, or Firefox with FIDO U2F turned on)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Your Bitwarden two-step login recovery code" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Set requirements for password generator." }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organization policies are affecting your generator settings." - }, "masterPasswordPolicyInEffect": { "message": "One or more organization policies require your master password to meet the following requirements:" }, @@ -6666,15 +6717,6 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Use your domain's configured catch-all inbox." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Random", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Hostname", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API access token" - }, "deviceVerification": { "message": "Device verification" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "No collection" }, - "canView": { - "message": "Can view" - }, - "canViewExceptPass": { - "message": "Can view, except passwords" - }, - "canEdit": { - "message": "Can edit" - }, - "canEditExceptPass": { - "message": "Can edit, except passwords" - }, "noCollectionsAdded": { "message": "No collections added" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domain" - }, "alreadyHaveAccount": { "message": "Already have an account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/kn/messages.json b/apps/web/src/locales/kn/messages.json index d6720ef2375..83d0f5f6b89 100644 --- a/apps/web/src/locales/kn/messages.json +++ b/apps/web/src/locales/kn/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "ಫೋಲ್ಡರ್ ಸಂಪಾದಿಸಿ" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "ಮೂಲ ಡೊಮೇನ್", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "ಉದಾಹರಣೆ.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Log in initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "ಒಪ್ಪಿಸು" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "ಆವೃತ್ತಿ $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "ಪಾಸ್ವರ್ಡ್ ಅನ್ನು ಪುನರುತ್ಪಾದಿಸಿ" - }, "length": { "message": "ಉದ್ದ" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "ಅಪಾಯ ವಲಯ" }, - "dangerZoneDesc": { - "message": "ಎಚ್ಚರಿಕೆಯಿಂದ, ಈ ಕ್ರಿಯೆಗಳು ಹಿಂತಿರುಗಿಸಲಾಗುವುದಿಲ್ಲ!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "ಸೆಷನ್‌ಗಳನ್ನು ಅನಧಿಕೃತಗೊಳಿಸಿ" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "ಮುಂದುವರಿಯುವುದರಿಂದ ನಿಮ್ಮ ಪ್ರಸ್ತುತ ಸೆಷನ್‌ನಿಂದ ನಿಮ್ಮನ್ನು ಲಾಗ್ಔಟ್ ಮಾಡುತ್ತದೆ, ನಿಮಗೆ ಮತ್ತೆ ಲಾಗ್ ಇನ್ ಆಗುವ ಅಗತ್ಯವಿರುತ್ತದೆ. ಸಕ್ರಿಯಗೊಳಿಸಿದ್ದರೆ ಮತ್ತೆ ಎರಡು-ಹಂತದ ಲಾಗಿನ್‌ಗೆ ನಿಮ್ಮನ್ನು ಕೇಳಲಾಗುತ್ತದೆ. ಇತರ ಸಾಧನಗಳಲ್ಲಿ ಸಕ್ರಿಯ ಸೆಷನ್‌ಗಳು ಒಂದು ಗಂಟೆಯವರೆಗೆ ಸಕ್ರಿಯವಾಗಿ ಮುಂದುವರಿಯಬಹುದು." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "ಎಲ್ಲಾ ಸೆಷನ್‌ಗಳು ಅನಧಿಕೃತವಾಗಿವೆ" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "ವ್ಯವಸ್ಥಾಪಕ" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "ನಿಷ್‌ಕ್ರಿಯೆಗೊಳಿಸಿ" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "ಭದ್ರತಾ ಕೀಲಿಯನ್ನು ಓದುವಲ್ಲಿ ಸಮಸ್ಯೆ ಇದೆ. ಮತ್ತೆ ಪ್ರಯತ್ನಿಸು." }, - "twoFactorWebAuthnWarning": { - "message": "ಪ್ಲಾಟ್‌ಫಾರ್ಮ್ ಮಿತಿಗಳ ಕಾರಣ, ಎಲ್ಲಾ ಬಿಟ್‌ವಾರ್ಡೆನ್ ಅಪ್ಲಿಕೇಶನ್‌ಗಳಲ್ಲಿ ವೆಬ್‌ಆಥ್ನ್ ಅನ್ನು ಬಳಸಲಾಗುವುದಿಲ್ಲ. ನೀವು ಇನ್ನೊಂದು ಎರಡು-ಹಂತದ ಲಾಗಿನ್ ಒದಗಿಸುವವರನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಬೇಕು ಇದರಿಂದ ವೆಬ್‌ಆಥ್ನ್ ಅನ್ನು ಬಳಸಲಾಗದಿದ್ದಾಗ ನಿಮ್ಮ ಖಾತೆಯನ್ನು ಪ್ರವೇಶಿಸಬಹುದು. ಬೆಂಬಲಿತ ವೇದಿಕೆಗಳು:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "ವೆಬ್‌ಆಥ್ನ್ ಶಕ್ತಗೊಂಡ ಬ್ರೌಸರ್‌ನೊಂದಿಗೆ ಡೆಸ್ಕ್‌ಟಾಪ್ / ಲ್ಯಾಪ್‌ಟಾಪ್‌ನಲ್ಲಿ ವೆಬ್ ವಾಲ್ಟ್ ಮತ್ತು ಬ್ರೌಸರ್ ವಿಸ್ತರಣೆಗಳು (ಕ್ರೋಮ್, ಒಪೇರಾ, ವಿವಾಲ್ಡಿ, ಅಥವಾ ಎಫ್‌ಐಡಿಒ ಯು 2 ಎಫ್ ಸಕ್ರಿಯಗೊಳಿಸಿದ ಫೈರ್‌ಫಾಕ್ಸ್)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "ನಿಮ್ಮ ಬಿಟ್‌ವಾರ್ಡೆನ್ ಎರಡು-ಹಂತದ ಲಾಗಿನ್ ಮರುಪಡೆಯುವಿಕೆ ಕೋಡ್" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "ಪಾಸ್ವರ್ಡ್ ಜನರೇಟರ್ ಕಾನ್ಫಿಗರೇಶನ್ಗಾಗಿ ಕನಿಷ್ಠ ಅವಶ್ಯಕತೆಗಳನ್ನು ಹೊಂದಿಸಿ." }, - "passwordGeneratorPolicyInEffect": { - "message": "ಒಂದು ಅಥವಾ ಹೆಚ್ಚಿನ ಸಂಸ್ಥೆ ನೀತಿಗಳು ನಿಮ್ಮ ಜನರೇಟರ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳ ಮೇಲೆ ಪರಿಣಾಮ ಬೀರುತ್ತವೆ." - }, "masterPasswordPolicyInEffect": { "message": "ಒಂದು ಅಥವಾ ಹೆಚ್ಚಿನ ಸಂಸ್ಥೆ ನೀತಿಗಳಿಗೆ ಈ ಕೆಳಗಿನ ಅವಶ್ಯಕತೆಗಳನ್ನು ಪೂರೈಸಲು ನಿಮ್ಮ ಮಾಸ್ಟರ್ ಪಾಸ್‌ವರ್ಡ್ ಅಗತ್ಯವಿದೆ:" }, @@ -6666,15 +6717,6 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Use your domain's configured catch-all inbox." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Random", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Hostname", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API access token" - }, "deviceVerification": { "message": "Device verification" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "No collection" }, - "canView": { - "message": "Can view" - }, - "canViewExceptPass": { - "message": "Can view, except passwords" - }, - "canEdit": { - "message": "Can edit" - }, - "canEditExceptPass": { - "message": "Can edit, except passwords" - }, "noCollectionsAdded": { "message": "No collections added" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domain" - }, "alreadyHaveAccount": { "message": "Already have an account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/ko/messages.json b/apps/web/src/locales/ko/messages.json index d030fffee14..7ff621bf3c1 100644 --- a/apps/web/src/locales/ko/messages.json +++ b/apps/web/src/locales/ko/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "폴더 편집" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "기본 도메인", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "예)", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Log in initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "보내기" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "기기에 알림이 전송되었습니다." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "버전 $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "비밀번호 재생성" - }, "length": { "message": "길이" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "위험 구역" }, - "dangerZoneDesc": { - "message": "주의, 이 행동들은 되돌릴 수 없음!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "세션 해제" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "계속 진행하면, 현재 세션 또한 로그아웃 되므로 다시 로그인하여야 합니다. 2단계 로그인이 활성화 된 경우 다시 요구하는 메세지가 표시됩니다. 다른 기기의 활성화 된 세션은 최대 1시간 동안 유지 될 수 있습니다." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "모든 세션 해제 됨" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "관리" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "비활성화" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "보안 키를 읽어오는데 문제가 발생했습니다. 다시 시도해보십시오." }, - "twoFactorWebAuthnWarning": { - "message": "플랫폼 제한으로 인해, 모든 Bitwarden 애플리케이션에서 WebAuthn을 사용할 수 없습니다. WebAuthn을 사용할 수 없을 때 계정에 접근할 수 있도록 다른 2단계 로그인 방법을 활성화하십시오. 지원하는 플랫폼:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "WebAuthn 지원 브라우저가 있는 데스크탑/랩탑의 웹 보관함 및 브라우저 확장 (WebAuthn이 활성화된 Chrome, Opera, Vivaldi 또는 Firefox 사용)" + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Bitwarden 2단계 로그인 복구 코드" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "비밀번호 생성기 설정에 최소 요구 사항을 설정해주세요." }, - "passwordGeneratorPolicyInEffect": { - "message": "하나 이상의 단체 정책이 생성기 설정에 영항을 미치고 있습니다." - }, "masterPasswordPolicyInEffect": { "message": "하나 이상의 단체 정책이 마스터 비밀번호가 다음 사항을 따르도록 요구합니다:" }, @@ -6666,15 +6717,6 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Use your domain's configured catch-all inbox." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Random", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Hostname", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API access token" - }, "deviceVerification": { "message": "Device verification" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "No collection" }, - "canView": { - "message": "Can view" - }, - "canViewExceptPass": { - "message": "Can view, except passwords" - }, - "canEdit": { - "message": "Can edit" - }, - "canEditExceptPass": { - "message": "Can edit, except passwords" - }, "noCollectionsAdded": { "message": "No collections added" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domain" - }, "alreadyHaveAccount": { "message": "Already have an account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/lv/messages.json b/apps/web/src/locales/lv/messages.json index ffd166b6655..9f7ba055ed4 100644 --- a/apps/web/src/locales/lv/messages.json +++ b/apps/web/src/locales/lv/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Labot mapi" }, + "newFolder": { + "message": "Jauna mape" + }, + "folderName": { + "message": "Mapes nosaukums" + }, + "folderHintText": { + "message": "Apakšmapes var izveidot, ja pievieno iekļaujošās mapes nosaukumu, aiz kura ir \"/\". Piemēram: Tīklošanās/Forumi" + }, + "deleteFolderPermanently": { + "message": "Vai tiešām neatgriezeniski izdzēst šo mapi?" + }, "baseDomain": { "message": "Pamata domēns", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Vienuma nosaukums" }, - "cannotRemoveViewOnlyCollections": { - "message": "Nevar noņemt krājumus ar tiesībām \"Tikai skatīt\": $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "piem.,", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Uzsākta pieteikšanās" }, + "logInRequestSent": { + "message": "Pieprasījums nosūtīts" + }, "submit": { "message": "Iesniegt" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "Uz ierīci ir nosūtīts paziņojums." }, + "notificationSentDevicePart1": { + "message": "Bitwarden jāatslēdz savā ierīcē vai " + }, + "areYouTryingToAccessYourAccount": { + "message": "Vai mēģini piekļūt savam kontam?" + }, + "accessAttemptBy": { + "message": "$EMAIL$ piekļuves mēģinājums", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Apstiprināt piekļuvi" + }, + "denyAccess": { + "message": "Noraidīt piekļuvi" + }, + "notificationSentDeviceAnchor": { + "message": "tīmekļa lietotnē" + }, + "notificationSentDevicePart2": { + "message": "Pirms apstiprināšanas jāpārliecinās, ka pirkstu nospieduma vārdkopa atbilst zemāk esošajai." + }, + "notificationSentDeviceComplete": { + "message": "Savā ierīcē jāatslēdz Bitwarden. Pirms apstiprināšanas jāpārliecinās, ka pirkstu nospieduma vārdkopa atbilst zemāk esošajai." + }, "aNotificationWasSentToYourDevice": { "message": "Uz ierīci tika nosūtīts paziņojums" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Lūgums pārliecināties, ka konts ir atslēgts un atpazīšanas vārdkopa ir tāda pati arī otrā ierīcē" - }, "versionNumber": { "message": "Laidiens $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Izvairīties no viegli sajaucamām rakstzīmēm", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Pārizveidot paroli" - }, "length": { "message": "Garums" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Bīstamā sadaļa" }, - "dangerZoneDesc": { - "message": "Piesardzību, šīs darbības nav atsaucamas!" - }, - "dangerZoneDescSingular": { - "message": "Uzmanīgi, šī darbība ir neatgriezeniska!" - }, "deauthorizeSessions": { "message": "Padarīt sesijas spēkā neesošas" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Tiks veikta atteikšanās no pašreizējās sesijas, un pēc tam būs nepieciešams atkārtoti pieteikties. Būs nepieciešama arī divpakāpju pieteikšanās, ja tā ir iespējota. Citās ierīcēs darbojošās sesijas var būt spēkā līdz vienai stundai." }, + "newDeviceLoginProtection": { + "message": "Pieteikšanās jaunā ierīcē" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Izslēgt pieteikšanās jaunā ierīcē aizsardzību" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Ieslēgt pieteikšanās jaunā ierīcē aizsardzību" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Turpināt zemāk, lai izslēgtu apliecināšanas e-pasta ziņojumus, ko Bitwarden sūta, kad notiek pieteikšanās jaunā ierīcē." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Turpināt zemāk, lai Bitwarden sūtītu apliecināšanas e-pasta ziņojumus, kad notiek pieteikšanās jaunā ierīcē." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "Ar izslēgtu pieteikšanās jaunā ierīcē aizsardzību ikviens ar Tavu galveno paroli var piekļūt kontam no jebkuras ierīces. Lai aizsargātu savu kontu bez apliecināšanas e-pasta ziņojumiem, jāiestata divpakāpju pieteikšanās." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "Pieteikšanās jaunā ierīcē aizsardzības izmaiņas saglabātas" + }, "sessionsDeauthorized": { "message": "Visu sesiju darbība ir atsaukta" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Pārvaldīt" }, - "canManage": { - "message": "Var pārvaldīt" + "manageCollection": { + "message": "Pārvaldīt krājumu" + }, + "viewItems": { + "message": "Apskatīt vienumus" + }, + "viewItemsHidePass": { + "message": "Apskatīt vienumus, paslēptās paroles" + }, + "editItems": { + "message": "Labot vienumus" + }, + "editItemsHidePass": { + "message": "Labot vienumus, paslēptās paroles" }, "disable": { "message": "Atspējot" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "Radās sarežģījumi, nolasot drošības atslēgu. Jāmēģina vēlreiz." }, - "twoFactorWebAuthnWarning": { - "message": "Platformas ierobežojumu dēļ WebAuth nevar izmantot visās Bitwarden lietotnēs. Ir ieteicams iespējot vēl kādu divpakāpju pieteikšanās nodrošinātāju, lai varētu piekļūt kontam, kad nav iespējams izmantot WebAuth. Atbalstītās platformas:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Tīmekļa glabātava un pārlūku paplašinājums galddatorā/klēpjdatorā ar WebAuthn iespējotu pārlūku (Chrome, Opera, Vivaldi vai Firefox ar iespējotu FIDO U2F)." + "twoFactorWebAuthnWarning1": { + "message": "Platformas ierobežojumu dēļ WebAuth nevar izmantot visās Bitwarden lietotnēs. Ir ieteicams iespējot vēl kādu divpakāpju pieteikšanās nodrošinātāju, lai varētu piekļūt kontam, kad nav iespējams izmantot WebAuth." }, "twoFactorRecoveryYourCode": { "message": "Bitwarden divpakāpju pieteikšanās atkopšanas kods" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Uzstādīt paroļu veidotāja uzstādījumu mazākās izpildāmās prasības." }, - "passwordGeneratorPolicyInEffect": { - "message": "Viens vai vairāki apvienības nosacījumi ietekmē veidotāja iestatījumus." - }, "masterPasswordPolicyInEffect": { "message": "Vienā vai vairākos apvienības nosacījumos ir norādīts, ka galvenajai parolei ir jāatbilst šādām prasībām:" }, @@ -6666,15 +6717,6 @@ "message": "Veidotājs", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "Ko ir vēlme izveidot?" - }, - "passwordType": { - "message": "Paroles veids" - }, - "regenerateUsername": { - "message": "Pārizveidot lietotājvārdu" - }, "generateUsername": { "message": "Izveidot lietotājvārdu" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Lietotājvārda veids" - }, "plusAddressedEmail": { "message": "E-pasta adrese ar plusu", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Izmantot uzstādīto domēna visu tverošo iesūtni." }, + "useThisEmail": { + "message": "Izmantot šo e-pasta adresi" + }, "random": { "message": "Nejauši", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Resursdatora nosaukums", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API piekļuves pilnvara" - }, "deviceVerification": { "message": "Ierīces apstiprināšana" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "Nav krājuma" }, - "canView": { - "message": "Var skatīt" - }, - "canViewExceptPass": { - "message": "Var skatīt, izņemot paroles" - }, - "canEdit": { - "message": "Var labot" - }, - "canEditExceptPass": { - "message": "Var labot, izņemot paroles" - }, "noCollectionsAdded": { "message": "Nav pievienotu krājumu" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Ļaut krājumu izdzēšanu tikai īpašniekiem un pārvaldītājiem" }, + "limitItemDeletionDesc": { + "message": "Ierobežot lietotājiem vienumu izdzēšanu ar atļauju \"Var pārvaldīt\"" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Īpašnieki un pārvaldnieki var pārvaldīt visus krājumus un vienumus" }, @@ -8656,9 +8686,6 @@ "message": "Pašmitināta servera URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Aizstājdomēns" - }, "alreadyHaveAccount": { "message": "Jau ir konts?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "Nav piekļuves pārvaldīt šo krājumu." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Trūkst atļaujas \"Var pārvaldīt\"" + "grantManageCollectionWarningTitle": { + "message": "Trūkst krājumu pārvaldīšanas atļaujas" }, - "grantAddAccessCollectionWarning": { - "message": "Jānodrošina atļauja \"Var pārvaldīt\", lai ļautu pilnu krājuma pārvaldību, tajā skaitā krājuma izdzēšanu." + "grantManageCollectionWarning": { + "message": "Jānodrošina atļauja \"Pārvaldīt kŗajumu\", lai ļautu pilnu krājuma pārvaldību, tajā skaitā krājuma izdzēšanu." }, "grantCollectionAccess": { "message": "Piešķirt kopām vai dalībniekiem piekļuvi šim krājumam." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Apraksta kods" }, + "cannotRemoveViewOnlyCollections": { + "message": "Nevar noņemt krājumus ar tiesībām \"Tikai skatīt\": $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Svarīgs paziņojums" }, @@ -10176,7 +10212,7 @@ } }, "updatedRevokeSponsorshipConfirmationForSentSponsorship": { - "message": "If you remove $EMAIL$, the sponsorship for this Family plan cannot be redeemed. Are you sure you want to continue?", + "message": "Ja tiks noņemta $EMAIL$, atbalstītājdarbība šim Ģimenes plānam nevarēs izmantot. Vai tiešām turpināt?", "placeholders": { "email": { "content": "$1", @@ -10185,7 +10221,7 @@ } }, "updatedRevokeSponsorshipConfirmationForAcceptedSponsorship": { - "message": "If you remove $EMAIL$, the sponsorship for this Family plan will end and the saved payment method will be charged $40 + applicable tax on $DATE$. You will not be able to redeem a new sponsorship until $DATE$. Are you sure you want to continue?", + "message": "Ja tiks noņemta $EMAIL$, šī Ģimenes plāna atbalstītājdarbība beigsies, un $DATE$ ar saglabāto maksājumu veidu tiks veikta $40 apmaksa + piemērojamais nodoklis. Nebūs iespējams izmantot jaunu atbalstītājdarbību līdz $DATE$. Vai tiešām turpināt?", "placeholders": { "email": { "content": "$1", @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Pārvaldītājiem tagad ir iespēja izdzēst dalībnieku kontus, kas pieder pieteiktam domēnam." + }, + "deleteManagedUserWarningDesc": { + "message": "Šī darbība izdzēsīs dalībnieka kontu, tajā skaitā visus glabātavas vienumus. Tā aizstāj iepriekšējo darbību \"Noņemt\"." + }, + "deleteManagedUserWarning": { + "message": "\"Izdzēst\" ir jaunā darbība." + }, + "seatsRemaining": { + "message": "Ir atlikušas $REMAINING$ no apvienībai piesaistītajām $TOTAL$ vietām. Jāsazinās ar nodrošinātāju, lai pārvaldītu savu abonementu.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Esoša apvienība" + }, + "selectOrganizationProviderPortal": { + "message": "Jāatlasa apvienība, kuru pievienot savam nodrošinātāju portālam." + }, + "noOrganizations": { + "message": "Nav apvienību, ko uzskaitīt" + }, + "yourProviderSubscriptionCredit": { + "message": "Nodrošinātāja abonements saņemts kredītu par jebkuru atlikušo laiku apvienības abonementā." + }, + "doYouWantToAddThisOrg": { + "message": "Vai šo apvienību pievienot $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Pievienota esoša apvienība" + }, + "assignedExceedsAvailable": { + "message": "Piešķirtās vietas pārsniedz pieejamās vietas." } } diff --git a/apps/web/src/locales/ml/messages.json b/apps/web/src/locales/ml/messages.json index 56746c8f01f..617f3b2d8ac 100644 --- a/apps/web/src/locales/ml/messages.json +++ b/apps/web/src/locales/ml/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "ഫോൾഡർ തിരുത്തുക" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "അടിസ്ഥാന ഡൊമെയ്ൻ", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "ഉദാഹരണം.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Log in initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "സമർപ്പിക്കുക" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "വേർഷൻ $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "പാസ്സ്‌വേഡ് വീണ്ടും സൃഷ്ടിക്കുക" - }, "length": { "message": "ദൈര്‍ഘ്യം" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "അപകട മേഖല" }, - "dangerZoneDesc": { - "message": "ശ്രദ്ധിക്കുക, ഈ പ്രവർത്തനങ്ങൾ മാറ്റാനാവില്ല!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Deauthorize Sessions" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Proceeding will also log you out of your current session, requiring you to log back in. You will also be prompted for two-step login again, if enabled. Active sessions on other devices may continue to remain active for up to one hour." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "എല്ലാ സെഷനും നിരസിച്ചു." }, @@ -2155,8 +2200,20 @@ "manage": { "message": "നിയന്ത്രിക്കുക" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "പ്രവര്‍ത്തന രഹിതമാക്കുക" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "There was a problem reading the security key. Try again." }, - "twoFactorWebAuthnWarning": { - "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used. Supported platforms:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Web vault and browser extensions on a desktop/laptop with a WebAuthn supported browser (Chrome, Opera, Vivaldi, or Firefox with FIDO U2F turned on)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Your Bitwarden two-step login recovery code" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "പാസ്‌വേഡ് ജനറേറ്റർ കോൺഫിഗറേഷനായി മിനിമം ആവശ്യകതകൾ സജ്ജമാക്കുക." }, - "passwordGeneratorPolicyInEffect": { - "message": "ഒന്നോ അതിലധികമോ സംഘടന നയങ്ങൾ നിങ്ങളുടെ പാസ്സ്‌വേഡ് സൃഷ്ടാവിൻ്റെ ക്രമീകരണങ്ങളെ ബാധിക്കുന്നു." - }, "masterPasswordPolicyInEffect": { "message": "ഒന്നോ അതിലധികമോ ഓർഗനൈസേഷൻ നയങ്ങൾക്ക് ഇനിപ്പറയുന്ന ആവശ്യകതകൾ നിറവേറ്റുന്നതിന് നിങ്ങളുടെ മാസ്റ്റർ പാസ്‌വേഡ് ആവശ്യമാണ്:" }, @@ -6666,15 +6717,6 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Use your domain's configured catch-all inbox." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Random", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Hostname", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API access token" - }, "deviceVerification": { "message": "Device verification" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "No collection" }, - "canView": { - "message": "Can view" - }, - "canViewExceptPass": { - "message": "Can view, except passwords" - }, - "canEdit": { - "message": "Can edit" - }, - "canEditExceptPass": { - "message": "Can edit, except passwords" - }, "noCollectionsAdded": { "message": "No collections added" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domain" - }, "alreadyHaveAccount": { "message": "Already have an account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/mr/messages.json b/apps/web/src/locales/mr/messages.json index 486f01ce2cb..7e6f614b9c8 100644 --- a/apps/web/src/locales/mr/messages.json +++ b/apps/web/src/locales/mr/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Edit folder" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Base domain", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "ex.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Log in initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Submit" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "Version $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Regenerate password" - }, "length": { "message": "Length" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Danger zone" }, - "dangerZoneDesc": { - "message": "Careful, these actions are not reversible!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Deauthorize sessions" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Proceeding will also log you out of your current session, requiring you to log back in. You will also be prompted for two-step login again, if set up. Active sessions on other devices may continue to remain active for up to one hour." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "All sessions deauthorized" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Manage" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Turn off" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "There was a problem reading the security key. Try again." }, - "twoFactorWebAuthnWarning": { - "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used. Supported platforms:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Web vault and browser extensions on a desktop/laptop with a WebAuthn supported browser (Chrome, Opera, Vivaldi, or Firefox with FIDO U2F turned on)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Your Bitwarden two-step login recovery code" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Set requirements for password generator." }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organization policies are affecting your generator settings." - }, "masterPasswordPolicyInEffect": { "message": "One or more organization policies require your master password to meet the following requirements:" }, @@ -6666,15 +6717,6 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Use your domain's configured catch-all inbox." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Random", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Hostname", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API access token" - }, "deviceVerification": { "message": "Device verification" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "No collection" }, - "canView": { - "message": "Can view" - }, - "canViewExceptPass": { - "message": "Can view, except passwords" - }, - "canEdit": { - "message": "Can edit" - }, - "canEditExceptPass": { - "message": "Can edit, except passwords" - }, "noCollectionsAdded": { "message": "No collections added" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domain" - }, "alreadyHaveAccount": { "message": "Already have an account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/my/messages.json b/apps/web/src/locales/my/messages.json index 486f01ce2cb..7e6f614b9c8 100644 --- a/apps/web/src/locales/my/messages.json +++ b/apps/web/src/locales/my/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Edit folder" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Base domain", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "ex.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Log in initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Submit" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "Version $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Regenerate password" - }, "length": { "message": "Length" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Danger zone" }, - "dangerZoneDesc": { - "message": "Careful, these actions are not reversible!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Deauthorize sessions" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Proceeding will also log you out of your current session, requiring you to log back in. You will also be prompted for two-step login again, if set up. Active sessions on other devices may continue to remain active for up to one hour." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "All sessions deauthorized" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Manage" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Turn off" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "There was a problem reading the security key. Try again." }, - "twoFactorWebAuthnWarning": { - "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used. Supported platforms:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Web vault and browser extensions on a desktop/laptop with a WebAuthn supported browser (Chrome, Opera, Vivaldi, or Firefox with FIDO U2F turned on)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Your Bitwarden two-step login recovery code" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Set requirements for password generator." }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organization policies are affecting your generator settings." - }, "masterPasswordPolicyInEffect": { "message": "One or more organization policies require your master password to meet the following requirements:" }, @@ -6666,15 +6717,6 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Use your domain's configured catch-all inbox." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Random", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Hostname", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API access token" - }, "deviceVerification": { "message": "Device verification" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "No collection" }, - "canView": { - "message": "Can view" - }, - "canViewExceptPass": { - "message": "Can view, except passwords" - }, - "canEdit": { - "message": "Can edit" - }, - "canEditExceptPass": { - "message": "Can edit, except passwords" - }, "noCollectionsAdded": { "message": "No collections added" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domain" - }, "alreadyHaveAccount": { "message": "Already have an account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/nb/messages.json b/apps/web/src/locales/nb/messages.json index d27d6c8fae0..a804f5dfafb 100644 --- a/apps/web/src/locales/nb/messages.json +++ b/apps/web/src/locales/nb/messages.json @@ -96,7 +96,7 @@ "message": "Apps marked as critical" }, "application": { - "message": "Application" + "message": "Program" }, "atRiskPasswords": { "message": "At-risk passwords" @@ -208,22 +208,22 @@ "message": "Kortholderens navn" }, "loginCredentials": { - "message": "Login credentials" + "message": "Legitimasjoner for innlogging" }, "personalDetails": { - "message": "Personal details" + "message": "Personlige detaljer" }, "identification": { - "message": "Identification" + "message": "Identifikasjon" }, "contactInfo": { - "message": "Contact info" + "message": "Kontaktinfo" }, "cardDetails": { - "message": "Card details" + "message": "Kortdetaljer" }, "cardBrandDetails": { - "message": "$BRAND$ details", + "message": "$BRAND$-detaljer", "placeholders": { "brand": { "content": "$1", @@ -232,19 +232,19 @@ } }, "itemHistory": { - "message": "Item history" + "message": "Gjenstandshistorikk" }, "authenticatorKey": { - "message": "Authenticator key" + "message": "Autentiseringsnøkkel" }, "autofillOptions": { - "message": "Autofill options" + "message": "Autoutfyllings-innstillinger" }, "websiteUri": { - "message": "Website (URI)" + "message": "Nettsted (URİ)" }, "websiteUriCount": { - "message": "Website (URI) $COUNT$", + "message": "Nettsted (URİ) $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": { @@ -254,16 +254,16 @@ } }, "websiteAdded": { - "message": "Website added" + "message": "Nettsted lagt til" }, "addWebsite": { - "message": "Add website" + "message": "Legg til nettsted" }, "deleteWebsite": { - "message": "Delete website" + "message": "Slett nettsted" }, "defaultLabel": { - "message": "Default ($VALUE$)", + "message": "Standard ($VALUE$)", "description": "A label that indicates the default value for a field with the current default value in parentheses.", "placeholders": { "value": { @@ -384,7 +384,7 @@ "message": "Dr․" }, "cardExpiredTitle": { - "message": "Expired card" + "message": "Utløpt kort" }, "cardExpiredMessage": { "message": "If you've renewed it, update the card's information" @@ -408,7 +408,7 @@ "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." }, "learnMoreAboutAuthenticators": { - "message": "Learn more about authenticators" + "message": "Lær mer om autentisering" }, "folder": { "message": "Mappe" @@ -432,17 +432,17 @@ "message": "Boolsk verdi" }, "cfTypeCheckbox": { - "message": "Checkbox" + "message": "Avkryssingsboks" }, "cfTypeLinked": { "message": "Tilknyttet", "description": "This describes a field that is 'linked' (related) to another field." }, "fieldType": { - "message": "Field type" + "message": "Felttype" }, "fieldLabel": { - "message": "Field label" + "message": "Feltetikett" }, "remove": { "message": "Fjern" @@ -455,7 +455,7 @@ "description": "This is the folder for uncategorized items" }, "selfOwnershipLabel": { - "message": "You", + "message": "Du", "description": "Used as a label to indicate that the user is the owner of an item." }, "addFolder": { @@ -464,6 +464,18 @@ "editFolder": { "message": "Rediger mappen" }, + "newFolder": { + "message": "Ny mappe" + }, + "folderName": { + "message": "Mappenavn" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Grunndomene", "description": "Domain name. Example: website.com" @@ -508,7 +520,7 @@ "message": "Generer et passord" }, "generatePassphrase": { - "message": "Generate passphrase" + "message": "Generér passordfrase" }, "checkPassword": { "message": "Sjekk om passordet har blitt utsatt." @@ -611,7 +623,7 @@ "message": "Sikkert notat" }, "typeSshKey": { - "message": "SSH key" + "message": "SSH-nøkkel" }, "typeLoginPlural": { "message": "Innlogginger" @@ -644,7 +656,7 @@ "message": "Fullt navn" }, "address": { - "message": "Address" + "message": "Adresse" }, "address1": { "message": "Adresse 1" @@ -689,7 +701,7 @@ "message": "Vis elementet" }, "newItemHeader": { - "message": "New $TYPE$", + "message": "Ny $TYPE$", "placeholders": { "type": { "content": "$1", @@ -698,7 +710,7 @@ } }, "editItemHeader": { - "message": "Edit $TYPE$", + "message": "Rediger $TYPE$", "placeholders": { "type": { "content": "$1", @@ -723,19 +735,10 @@ "message": "Element" }, "itemDetails": { - "message": "Item details" + "message": "Gjenstandens detaljer" }, "itemName": { - "message": "Item name" - }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } + "message": "Gjenstandens navn" }, "ex": { "message": "f.eks.", @@ -761,7 +764,7 @@ } }, "copySuccessful": { - "message": "Copy Successful" + "message": "Kopiering lyktes" }, "copyValue": { "message": "Kopier verdien", @@ -776,7 +779,7 @@ "description": "Copy passphrase to clipboard" }, "passwordCopied": { - "message": "Password copied" + "message": "Passordet er kopiert" }, "copyUsername": { "message": "Kopier brukernavnet", @@ -795,7 +798,7 @@ "description": "Copy URI to clipboard" }, "copyCustomField": { - "message": "Copy $FIELD$", + "message": "Kopiér $FIELD$", "placeholders": { "field": { "content": "$1", @@ -804,34 +807,34 @@ } }, "copyWebsite": { - "message": "Copy website" + "message": "Kopiér nettsted" }, "copyNotes": { - "message": "Copy notes" + "message": "Kopiér notater" }, "copyAddress": { - "message": "Copy address" + "message": "Kopiér adresse" }, "copyPhone": { - "message": "Copy phone" + "message": "Kopiér telefonnummer" }, "copyEmail": { "message": "Copy email" }, "copyCompany": { - "message": "Copy company" + "message": "Kopiér firma" }, "copySSN": { - "message": "Copy Social Security number" + "message": "Kopiér fødselsnummer" }, "copyPassportNumber": { - "message": "Copy passport number" + "message": "Kopiér passnummer" }, "copyLicenseNumber": { - "message": "Copy license number" + "message": "Kopiér lisensnummer" }, "copyName": { - "message": "Copy name" + "message": "Kopiér navn" }, "me": { "message": "Meg" @@ -922,7 +925,7 @@ } }, "itemsMovedToOrg": { - "message": "Items moved to $ORGNAME$", + "message": "Gjenstandene ble flyttet til $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -931,7 +934,7 @@ } }, "itemMovedToOrg": { - "message": "Item moved to $ORGNAME$", + "message": "Gjenstanden ble flyttet til $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -991,22 +994,22 @@ "message": "Logget av" }, "loggedOutDesc": { - "message": "You have been logged out of your account." + "message": "Du har blitt logget ut av kontoen din." }, "loginExpired": { "message": "Din innloggingsøkt har utløpt." }, "restartRegistration": { - "message": "Restart registration" + "message": "Start registreringen på nytt" }, "expiredLink": { - "message": "Expired link" + "message": "Utløpt lenke" }, "pleaseRestartRegistrationOrTryLoggingIn": { "message": "Please restart registration or try logging in." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Du har kanskje allerede en konto" }, "logOutConfirmation": { "message": "Er du sikker på at du vil logge av?" @@ -1033,7 +1036,7 @@ "message": "Logg på med enhet må settes opp i Bitwarden-innstillingene. Trenger du et annet alternativ?" }, "needAnotherOptionV1": { - "message": "Need another option?" + "message": "Trenger du et annet alternativ?" }, "loginWithMasterPassword": { "message": "Logg på med hovedpassord" @@ -1048,13 +1051,13 @@ "message": "Bruk en annen innloggingsmetode" }, "logInWithPasskey": { - "message": "Log in with passkey" + "message": "Logg inn med passnøkkel" }, "useSingleSignOn": { "message": "Use single sign-on" }, "welcomeBack": { - "message": "Welcome back" + "message": "Velkommen tilbake" }, "invalidPasskeyPleaseTryAgain": { "message": "Ugyldig Passkey. Vennligst prøv igjen." @@ -1138,10 +1141,10 @@ "message": "Opprett en konto" }, "newToBitwarden": { - "message": "New to Bitwarden?" + "message": "Er du ny til Bitwarden?" }, "setAStrongPassword": { - "message": "Set a strong password" + "message": "Velg et sterkt passord" }, "finishCreatingYourAccountBySettingAPassword": { "message": "Finish creating your account by setting a password" @@ -1156,7 +1159,7 @@ "message": "Logg på" }, "logInToBitwarden": { - "message": "Log in to Bitwarden" + "message": "Logg inn på Bitwarden" }, "authenticationTimeout": { "message": "Authentication timeout" @@ -1171,7 +1174,7 @@ "message": "We don't recognize this device. Enter the code sent to your email to verify your identity." }, "continueLoggingIn": { - "message": "Continue logging in" + "message": "Fortsett innloggingen" }, "whatIsADevice": { "message": "What is a device?" @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Pålogging startet" }, + "logInRequestSent": { + "message": "Forespørsel sendt" + }, "submit": { "message": "Send inn" }, @@ -1235,13 +1241,13 @@ "message": "Innstillinger" }, "accountEmail": { - "message": "Account email" + "message": "Kontoens E-postadresse" }, "requestHint": { - "message": "Request hint" + "message": "Be om et hint" }, "requestPasswordHint": { - "message": "Request password hint" + "message": "Be om passordhint" }, "enterYourAccountEmailAddressAndYourPasswordHintWillBeSentToYou": { "message": "Enter your account email address and your password hint will be sent to you" @@ -1284,10 +1290,10 @@ "message": "Din nye konto har blitt opprettet! Du kan nå logge på." }, "newAccountCreated2": { - "message": "Your new account has been created!" + "message": "Den nye kontoen din er opprettet!" }, "youHaveBeenLoggedIn": { - "message": "You have been logged in!" + "message": "Du har blitt logget inn!" }, "trialAccountCreated": { "message": "Kontoen ble opprettet." @@ -1305,10 +1311,10 @@ "message": "E-postadresse" }, "yourVaultIsLockedV2": { - "message": "Your vault is locked" + "message": "Hvelvet ditt er låst" }, "yourAccountIsLocked": { - "message": "Your account is locked" + "message": "Kontoen din er låst" }, "uuid": { "message": "UUID" @@ -1371,11 +1377,38 @@ "notificationSentDevice": { "message": "Et varsel har blitt sendt til enheten din." }, - "aNotificationWasSentToYourDevice": { - "message": "A notification was sent to your device" + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "nett-app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, + "aNotificationWasSentToYourDevice": { + "message": "Et varsel ble sendt til enheten din" }, "versionNumber": { "message": "Versjon $VERSION_NUMBER$", @@ -1480,7 +1513,7 @@ "message": "E-post" }, "emailDescV2": { - "message": "Enter a code sent to your email." + "message": "Skriv inn koden du har fått tilsendt på E-post." }, "continue": { "message": "Fortsett" @@ -1661,17 +1694,14 @@ "description": "deprecated. Use avoidAmbiguous instead." }, "avoidAmbiguous": { - "message": "Avoid ambiguous characters", + "message": "Unngå forvekslingsbare tegn", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Regenerer passord" - }, "length": { "message": "Lengde" }, "passwordMinLength": { - "message": "Minimum password length" + "message": "Minimum passordlengde" }, "uppercase": { "message": "Store bokstaver (A-Z)", @@ -1709,10 +1739,10 @@ "message": "Passordhistorikk" }, "generatorHistory": { - "message": "Generator history" + "message": "Generatorhistorikk" }, "clearGeneratorHistoryTitle": { - "message": "Clear generator history" + "message": "Tøm generatorhistorikk" }, "cleargGeneratorHistoryDescription": { "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" @@ -1721,13 +1751,13 @@ "message": "Det er ingen passord å liste opp." }, "clearHistory": { - "message": "Clear history" + "message": "Tøm historikk" }, "nothingToShow": { - "message": "Nothing to show" + "message": "Ingenting å vise" }, "nothingGeneratedRecently": { - "message": "You haven't generated anything recently" + "message": "Du har ikke generert noe i det siste" }, "clear": { "message": "Tøm", @@ -1767,7 +1797,7 @@ "message": "Vennligst logg på igjen." }, "currentSession": { - "message": "Current session" + "message": "Gjeldende økt" }, "requestPending": { "message": "Request pending" @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Faresone" }, - "dangerZoneDesc": { - "message": "Vær forsiktig, disse handlingene kan ikke reverseres!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Fjern autorisering av økter" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Å fortsette vil også logge deg av din nåværende økt, og gjør at du vil måtte logge på igjen. Du vil også bli bedt om 2-trinnsinnlogging igjen, dersom det er aktivert. Aktive økter på andre enheter kan kanskje forbli aktive i opptil en time." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "Fjernet autoriseringen fra alle økter" }, @@ -1944,7 +1989,7 @@ "message": "Dataene har blitt vellykket importert inn i hvelvet ditt." }, "importSuccessNumberOfItems": { - "message": "A total of $AMOUNT$ items were imported.", + "message": "$AMOUNT$ gjenstander totalt ble importert.", "placeholders": { "amount": { "content": "$1", @@ -1974,16 +2019,16 @@ "message": "Feil under dekryptering av den eksporterte filen. Krypteringsnøkkelen samsvarte ikke med krypteringsnøkkelen som ble brukt eksport av data." }, "destination": { - "message": "Destination" + "message": "Destinasjon" }, "learnAboutImportOptions": { - "message": "Learn about your import options" + "message": "Lær mer om importalternativene dine" }, "selectImportFolder": { - "message": "Select a folder" + "message": "Velg en mappe" }, "selectImportCollection": { - "message": "Select a collection" + "message": "Velg en samling" }, "importTargetHint": { "message": "Select this option if you want the imported file contents moved to a $DESTINATION$", @@ -1996,7 +2041,7 @@ } }, "importUnassignedItemsError": { - "message": "File contains unassigned items." + "message": "Filen inneholder utildelte elementer." }, "selectFormat": { "message": "Velg formatet til importfilen" @@ -2155,8 +2200,20 @@ "manage": { "message": "Behandle" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Deaktiver" @@ -2195,7 +2252,7 @@ "message": "You are leaving Bitwarden and launching an external website in a new window." }, "twoStepContinueToBitwardenUrlTitle": { - "message": "Continue to bitwarden.com?" + "message": "Vil du fortsette til bitwarden.com?" }, "twoStepContinueToBitwardenUrlDesc": { "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." @@ -2210,7 +2267,7 @@ "message": "Nøkkel" }, "twoStepAuthenticatorEnterCodeV2": { - "message": "Verification code" + "message": "Verifiseringskode" }, "twoStepAuthenticatorReaddDesc": { "message": "Dersom du trenger å legge den til til en annen enhet, er QR-koden (eller -nøkkelen) som kreves av din autentiseringsapp nedenfor." @@ -2294,7 +2351,7 @@ "message": "Client Id" }, "twoFactorDuoClientSecret": { - "message": "Client Secret" + "message": "Klienthemmelighet" }, "twoFactorDuoApiHostname": { "message": "API-vertsnavn" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "Det oppsto et problem med å lese sikkerhetsnøkkelen. Prøv igjen." }, - "twoFactorWebAuthnWarning": { - "message": "På grunn av plattformbegrensninger, kan ikke WebAuthn brukes på alle Bitwarden-apper. Du bør aktivere en annen 2-trinnsinnloggingsleverandør, slik at du kan få tilgang til kontoen din når WebAuthn ikke kan brukes. Støttede plattformer:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Netthvelv og nettleserutvidelser, på en datamaskin med en WebAuthn støttende nettleser (Chrome, Opera, Vivaldi, eller Firefox med FIDO U2F aktivert)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Din 2-trinnsinnloggingsgjenopprettingskode for Bitwarden" @@ -2938,7 +2992,7 @@ "message": "Ta kontakt med kundestøtte" }, "contactSupportShort": { - "message": "Contact Support" + "message": "Kontakt kundestøtte" }, "updatedPaymentMethod": { "message": "Oppdaterte betalingsmetoden." @@ -3405,7 +3459,7 @@ "message": "Netthvelv" }, "cli": { - "message": "CLI" + "message": "Ledetekst" }, "bitWebVault": { "message": "Bitwarden Web vault" @@ -3435,13 +3489,13 @@ "message": "Innloggingsforsøket mislyktes grunnet feil 2-trinnsinnlogging." }, "incorrectPassword": { - "message": "Incorrect password" + "message": "Feil passord" }, "incorrectCode": { - "message": "Incorrect code" + "message": "Feil kode" }, "incorrectPin": { - "message": "Incorrect PIN" + "message": "Feil PIN-kode" }, "pin": { "message": "PIN", @@ -3493,7 +3547,7 @@ } }, "viewAllLogInOptions": { - "message": "View all log in options" + "message": "Vis alle påloggingsalternativer" }, "viewAllLoginOptions": { "message": "Vis alle påloggingsalternativer" @@ -3838,16 +3892,16 @@ "message": "First login" }, "trusted": { - "message": "Trusted" + "message": "Betrodd" }, "needsApproval": { "message": "Needs approval" }, "areYouTryingtoLogin": { - "message": "Are you trying to log in?" + "message": "Prøver du å logge på?" }, "logInAttemptBy": { - "message": "Login attempt by $EMAIL$", + "message": "Påloggingsforsøk av $EMAIL$", "placeholders": { "email": { "content": "$1", @@ -3859,7 +3913,7 @@ "message": "Device Type" }, "ipAddress": { - "message": "IP Address" + "message": "IP-adresse" }, "confirmLogIn": { "message": "Confirm login" @@ -3890,7 +3944,7 @@ "message": "Login request has already expired." }, "justNow": { - "message": "Just now" + "message": "Akkurat nå" }, "requestedXMinutesAgo": { "message": "Requested $MINUTES$ minutes ago", @@ -3902,25 +3956,25 @@ } }, "creatingAccountOn": { - "message": "Creating account on" + "message": "Oppretter en konto på" }, "checkYourEmail": { - "message": "Check your email" + "message": "Sjekk E-postinnboksen din" }, "followTheLinkInTheEmailSentTo": { - "message": "Follow the link in the email sent to" + "message": "Følg lenken i E-postadressen som ble sendt til" }, "andContinueCreatingYourAccount": { "message": "and continue creating your account." }, "noEmail": { - "message": "No email?" + "message": "Ingen E-post?" }, "goBack": { - "message": "Go back" + "message": "Gå tilbake" }, "toEditYourEmailAddress": { - "message": "to edit your email address." + "message": "for å redigere E-postadressen din." }, "view": { "message": "Vis" @@ -4004,7 +4058,7 @@ "message": "Din E-postadresse har blitt bekreftet." }, "emailVerifiedV2": { - "message": "Email verified" + "message": "E-post bekreftet" }, "emailVerifiedFailed": { "message": "Klarte ikke å bekrefte E-postadressen din. Prøv å sende en ny bekreftelses-E-post." @@ -4461,10 +4515,10 @@ "message": "Unsubscribe" }, "atAnyTime": { - "message": "at any time." + "message": "når som helst." }, "byContinuingYouAgreeToThe": { - "message": "By continuing, you agree to the" + "message": "Ved å fortsette, samtykker du til" }, "and": { "message": "and" @@ -4488,7 +4542,7 @@ "message": "Pause for hvelvet" }, "vaultTimeout1": { - "message": "Timeout" + "message": "Tidsavbrudd" }, "vaultTimeoutDesc": { "message": "Velg når hvelvet ditt skal ta pause og utføre den valgte handlingen." @@ -4557,7 +4611,7 @@ "message": "Valgt" }, "recommended": { - "message": "Recommended" + "message": "Anbefalt" }, "ownership": { "message": "Eierskap" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Sett minimumskrav for konfigurasjon av passordgenerator." }, - "passwordGeneratorPolicyInEffect": { - "message": "En eller flere av organisasjonens vilkår påvirker generatorinnstillingene dine." - }, "masterPasswordPolicyInEffect": { "message": "En eller flere av organisasjonens vilkår krever hovedpassordet ditt for å oppfylle følgende krav:" }, @@ -4873,13 +4924,13 @@ "message": "Du kan nå lukke denne fanen og fortsette i utvidelsen." }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "Du har vellykket logget inn" }, "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "Du kan lukke dette vinduet" }, "includeAllTeamsFeatures": { "message": "Alle Lag funksjoner, plus:" @@ -5044,7 +5095,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "copyLink": { - "message": "Copy link" + "message": "Kopier lenke" }, "copySendLink": { "message": "Kopier Send-lenke", @@ -5792,7 +5843,7 @@ "message": "Feil" }, "decryptionError": { - "message": "Decryption error" + "message": "Dekrypteringsfeil" }, "couldNotDecryptVaultItemsBelow": { "message": "Bitwarden could not decrypt the vault item(s) listed below." @@ -5802,7 +5853,7 @@ "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": "for å unngå ytterligere datatap.", "description": "This is part of a larger sentence. The full sentence will read 'Contact customer success to avoid additional data loss.'" }, "accountRecoveryManageUsers": { @@ -6469,7 +6520,7 @@ "message": "Rotasjon av faktureringssynkroniserings-token vil gjøre den forrige token ugyldig." }, "selfHostedServer": { - "message": "self-hosted" + "message": "selvbetjent" }, "customEnvironment": { "message": "Custom environment" @@ -6666,23 +6717,14 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "Hva vil du generere?" - }, - "passwordType": { - "message": "Passordtype" - }, - "regenerateUsername": { - "message": "Regenerer Brukernavn" - }, "generateUsername": { "message": "Generer brukernavn" }, "generateEmail": { - "message": "Generate email" + "message": "Generér E-post" }, "spinboxBoundariesHint": { - "message": "Value must be between $MIN$ and $MAX$.", + "message": "Verdien må være mellom $MIN$ og $MAX$.", "description": "Explains spin box minimum and maximum values to the user", "placeholders": { "min": { @@ -6696,7 +6738,7 @@ } }, "passwordLengthRecommendationHint": { - "message": " Use $RECOMMENDED$ characters or more to generate a strong password.", + "message": " Bruk minst $RECOMMENDED$ tegn for å generere et sterkt passord.", "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": { @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Brukernavntype" - }, "plusAddressedEmail": { "message": "Pluss-adressert e-post", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Bruk domenets konfigurerte catch-all innboks." }, + "useThisEmail": { + "message": "Bruk denne E-postadressen" + }, "random": { "message": "Vilkårlig", "description": "Generates domain-based username using random letters" @@ -6739,23 +6781,23 @@ "message": "Vilkårlig ord" }, "usernameGenerator": { - "message": "Username generator" + "message": "Brukernavngenerator" }, "useThisPassword": { - "message": "Use this password" + "message": "Bruk dette passordet" }, "useThisUsername": { - "message": "Use this username" + "message": "Bruk dette brukernavnet" }, "securePasswordGenerated": { "message": "Secure password generated! Don't forget to also update your password on the website." }, "useGeneratorHelpTextPartOne": { - "message": "Use the generator", + "message": "Bruk denne generatoren", "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": "for å lage et sterkt og unikt passord", "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'" }, "service": { @@ -6821,11 +6863,11 @@ "message": "Generer et e-postalias med en ekstern videresendingstjeneste." }, "forwarderDomainName": { - "message": "Email domain", + "message": "E-postdomene", "description": "Labels the domain name email forwarder service option" }, "forwarderDomainNameHint": { - "message": "Choose a domain that is supported by the selected service", + "message": "Velg et domene som støttes av den valgte tjenesten", "description": "Guidance provided for email forwarding services that support multiple email domains." }, "forwarderError": { @@ -6843,11 +6885,11 @@ } }, "forwarderGeneratedBy": { - "message": "Generated by Bitwarden.", + "message": "Generert av Bitwarden.", "description": "Displayed with the address on the forwarding service's configuration screen." }, "forwarderGeneratedByWithWebsite": { - "message": "Website: $WEBSITE$. Generated by Bitwarden.", + "message": "Nettsted: $WEBSITE$. Generert av Bitwarden.", "description": "Displayed with the address on the forwarding service's configuration screen.", "placeholders": { "WEBSITE": { @@ -6857,7 +6899,7 @@ } }, "forwaderInvalidToken": { - "message": "Invalid $SERVICENAME$ API token", + "message": "Ugyldig $SERVICENAME$-API-sjetong", "description": "Displayed when the user's API token is empty or rejected by the forwarding service.", "placeholders": { "servicename": { @@ -6867,7 +6909,7 @@ } }, "forwaderInvalidTokenWithMessage": { - "message": "Invalid $SERVICENAME$ API token: $ERRORMESSAGE$", + "message": "Ugyldig $SERVICENAME$-API-sjetong: $ERRORMESSAGE$", "description": "Displayed when the user's API token is rejected by the forwarding service with an error message.", "placeholders": { "servicename": { @@ -6891,7 +6933,7 @@ } }, "forwarderNoDomain": { - "message": "Invalid $SERVICENAME$ domain.", + "message": "Ugyldig $SERVICENAME$-domene.", "description": "Displayed when the domain is empty or domain authorization failed at the forwarding service.", "placeholders": { "servicename": { @@ -6911,7 +6953,7 @@ } }, "forwarderUnknownError": { - "message": "Unknown $SERVICENAME$ error occurred.", + "message": "Ukjent $SERVICENAME$-feil oppstod.", "description": "Displayed when the forwarding service failed due to an unknown error.", "placeholders": { "servicename": { @@ -6934,9 +6976,6 @@ "message": "Vertsnavn", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API tilgangstoken" - }, "deviceVerification": { "message": "Enhetsverifisering" }, @@ -7053,7 +7092,7 @@ } }, "inputMinValue": { - "message": "Input value must be at least $MIN$.", + "message": "Inndataverdien må være minst $MIN$.", "placeholders": { "min": { "content": "$1", @@ -7062,7 +7101,7 @@ } }, "inputMaxValue": { - "message": "Input value must not exceed $MAX$.", + "message": "Inndataverdien kan ikke være mer enn $MAX$.", "placeholders": { "max": { "content": "$1", @@ -7092,10 +7131,10 @@ } }, "singleFieldNeedsAttention": { - "message": "1 field needs your attention." + "message": "1 felt trenger din oppmerksomhet." }, "multipleFieldsNeedAttention": { - "message": "$COUNT$ fields need your attention.", + "message": "$COUNT$ felter trenger din oppmerksomhet.", "placeholders": { "count": { "content": "$1", @@ -7113,7 +7152,7 @@ "message": "Duo two-step login is required for your account." }, "launchDuo": { - "message": "Launch Duo" + "message": "Start Duo" }, "turnOn": { "message": "Slå på" @@ -7122,7 +7161,7 @@ "message": "På" }, "off": { - "message": "Off" + "message": "Av" }, "members": { "message": "Medlemmer" @@ -7648,18 +7687,6 @@ "noCollection": { "message": "Ingen samling" }, - "canView": { - "message": "Kan vise" - }, - "canViewExceptPass": { - "message": "Kan vise, bortsett fra passord" - }, - "canEdit": { - "message": "Kan redigere" - }, - "canEditExceptPass": { - "message": "Kan redigere, bortsett fra passord" - }, "noCollectionsAdded": { "message": "Ingen samlinger lagt til" }, @@ -7808,37 +7835,37 @@ "message": "Verification required for this action. Set a PIN to continue." }, "setPin": { - "message": "Set PIN" + "message": "Velg PIN" }, "verifyWithBiometrics": { - "message": "Verify with biometrics" + "message": "Bekreft med biometri" }, "awaitingConfirmation": { - "message": "Awaiting confirmation" + "message": "Avventer bekreftelse" }, "couldNotCompleteBiometrics": { - "message": "Could not complete biometrics." + "message": "Kunne ikke fullføre biometri." }, "needADifferentMethod": { - "message": "Need a different method?" + "message": "Trenger du en annen metode?" }, "useMasterPassword": { - "message": "Use master password" + "message": "Bruk hovedpassord" }, "usePin": { - "message": "Use PIN" + "message": "Bruk PIN-kode" }, "useBiometrics": { - "message": "Use biometrics" + "message": "Bruk biometri" }, "enterVerificationCodeSentToEmail": { - "message": "Enter the verification code that was sent to your email." + "message": "Skriv inn bekreftelseskoden som ble sendt til e-postadressen din." }, "resendCode": { - "message": "Resend code" + "message": "Send koden på nytt" }, "memberColumnHeader": { - "message": "Member" + "message": "Medlem" }, "groupSlashMemberColumnHeader": { "message": "Group/Member" @@ -7952,7 +7979,7 @@ "message": "Filopplasting" }, "upload": { - "message": "Upload" + "message": "Last opp" }, "acceptedFormats": { "message": "Aksepterte formater:" @@ -7964,13 +7991,13 @@ "message": "eller" }, "unlockWithBiometrics": { - "message": "Unlock with biometrics" + "message": "Lås opp med biometri" }, "unlockWithPin": { - "message": "Unlock with PIN" + "message": "Lås opp med PIN-kode" }, "unlockWithMasterPassword": { - "message": "Unlock with master password" + "message": "Lås opp med hovedpassord" }, "licenseAndBillingManagement": { "message": "Håndtering av lisens og fakturering" @@ -8066,10 +8093,10 @@ "message": "This user can access Secrets Manager" }, "important": { - "message": "Important:" + "message": "Viktig:" }, "viewAll": { - "message": "View all" + "message": "Vis alle" }, "showingPortionOfTotal": { "message": "Showing $PORTION$ of $TOTAL$", @@ -8085,10 +8112,10 @@ } }, "resolveTheErrorsBelowAndTryAgain": { - "message": "Resolve the errors below and try again." + "message": "Fiks feilene nedenfor og prøv igjen." }, "description": { - "message": "Description" + "message": "Beskrivelse" }, "errorReadingImportFile": { "message": "An error occurred when trying to read the import file" @@ -8107,7 +8134,7 @@ "description": "Software Development Kit" }, "createAnAccount": { - "message": "Create an account" + "message": "Opprett en konto" }, "createSecret": { "message": "Create a secret" @@ -8129,7 +8156,7 @@ "message": "Import secrets" }, "getStarted": { - "message": "Get started" + "message": "Kom i gang" }, "complete": { "message": "$COMPLETED$/$TOTAL$ Complete", @@ -8248,7 +8275,7 @@ "message": "Update KDF settings" }, "loginInitiated": { - "message": "Login initiated" + "message": "Innlogging igangsatt" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { "message": "Remember this device to make future logins seamless" @@ -8257,25 +8284,25 @@ "message": "Device approval required. Select an approval option below:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "Enhetsgodkjennelse kreves" }, "selectAnApprovalOptionBelow": { "message": "Select an approval option below" }, "rememberThisDevice": { - "message": "Remember this device" + "message": "Husk denne enheten" }, "uncheckIfPublicDevice": { "message": "Uncheck if using a public device" }, "approveFromYourOtherDevice": { - "message": "Approve from your other device" + "message": "Godkjenn fra en av dine andre enheter" }, "requestAdminApproval": { - "message": "Request admin approval" + "message": "Be om administratorgodkjennelse" }, "approveWithMasterPassword": { - "message": "Approve with master password" + "message": "Godkjenn med hovedpassord" }, "trustedDeviceEncryption": { "message": "Trusted device encryption" @@ -8320,7 +8347,7 @@ "description": "Used as a card title description on the set password page to explain why the user is there" }, "cardMetrics": { - "message": "out of $TOTAL$", + "message": "av $TOTAL$", "placeholders": { "total": { "content": "$1", @@ -8338,7 +8365,7 @@ } }, "verificationRequired": { - "message": "Verification required", + "message": "Verifisering kreves", "description": "Default title for the user verification dialog." }, "recoverAccount": { @@ -8375,7 +8402,7 @@ "message": "Device info" }, "time": { - "message": "Time" + "message": "Tid" }, "denyAllRequests": { "message": "Deny all requests" @@ -8474,7 +8501,7 @@ } }, "next": { - "message": "Next" + "message": "Neste" }, "ssoLoginIsRequired": { "message": "SSO login is required" @@ -8489,16 +8516,16 @@ "message": "Admin approval requested" }, "adminApprovalRequestSentToAdmins": { - "message": "Your request has been sent to your admin." + "message": "Forespørselen din har blitt sendt til administratoren din." }, "youWillBeNotifiedOnceApproved": { - "message": "You will be notified once approved." + "message": "Du vil bli varslet når det er godkjent." }, "troubleLoggingIn": { - "message": "Trouble logging in?" + "message": "Har du problemer med å logge inn?" }, "loginApproved": { - "message": "Login approved" + "message": "Innlogging godkjent" }, "userEmailMissing": { "message": "User email missing" @@ -8507,18 +8534,18 @@ "message": "Active user email not found. Logging you out." }, "deviceTrusted": { - "message": "Device trusted" + "message": "Enheten er betrodd" }, "sendsNoItemsTitle": { - "message": "No active Sends", + "message": "Ingen aktive Send", "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": "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." }, "inviteUsers": { - "message": "Invite Users" + "message": "Inviter brukere" }, "secretsManagerForPlan": { "message": "Secrets Manager for $PLAN$", @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8638,7 +8668,7 @@ "message": "Max potential service account cost" }, "loggedInExclamation": { - "message": "Logged in!" + "message": "Innlogget!" }, "beta": { "message": "Beta" @@ -8650,32 +8680,29 @@ "message": "Edited collections" }, "baseUrl": { - "message": "Server URL" + "message": "Tjener-URL" }, "selfHostBaseUrl": { "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domain" - }, "alreadyHaveAccount": { - "message": "Already have an account?" + "message": "Har du allerede en konto?" }, "toggleSideNavigation": { "message": "Toggle side navigation" }, "skipToContent": { - "message": "Skip to content" + "message": "Hopp frem til innholdet" }, "managePermissionRequired": { "message": "At least one member or group must have can manage permission." }, "typePasskey": { - "message": "Passkey" + "message": "Passnøkkel" }, "passkeyNotCopied": { - "message": "Passkey will not be copied" + "message": "Passkoden vil ikke bli kopiert" }, "passkeyNotCopiedAlert": { "message": "The passkey will not be copied to the cloned item. Do you want to continue cloning this item?" @@ -8690,7 +8717,7 @@ } }, "seeDetailedInstructions": { - "message": "See detailed instructions on our help site at", + "message": "Se detaljerte instruksjoner på hjelpesidene våre på", "description": "This is followed a by a hyperlink to the help website." }, "installBrowserExtension": { @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -8739,7 +8766,7 @@ "message": "Service account access updated" }, "commonImportFormats": { - "message": "Common formats", + "message": "Vanlige formater", "description": "Label indicating the most common import formats" }, "maintainYourSubscription": { @@ -8816,7 +8843,7 @@ "message": "Provider Portal" }, "success": { - "message": "Success" + "message": "Suksess" }, "restrictedGroupAccess": { "message": "You cannot add yourself to groups." @@ -8825,10 +8852,10 @@ "message": "You cannot add yourself to collections." }, "assign": { - "message": "Assign" + "message": "Knytt" }, "assignToCollections": { - "message": "Assign to collections" + "message": "Legg til i samlinger" }, "assignToTheseCollections": { "message": "Assign to these collections" @@ -8840,7 +8867,7 @@ "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { - "message": "Select collections to assign" + "message": "Velg samlinger å tilordne" }, "noCollectionsAssigned": { "message": "No collections have been assigned" @@ -8862,25 +8889,25 @@ } }, "addField": { - "message": "Add field" + "message": "Legg til felt" }, "editField": { - "message": "Edit field" + "message": "Rediger felt" }, "items": { - "message": "Items" + "message": "Gjenstander" }, "assignedSeats": { "message": "Assigned seats" }, "assigned": { - "message": "Assigned" + "message": "Tildelt" }, "used": { - "message": "Used" + "message": "Brukt" }, "remaining": { - "message": "Remaining" + "message": "Gjenstår" }, "unlinkOrganization": { "message": "Unlink organization" @@ -8908,11 +8935,11 @@ "description": "A subscription status label." }, "pastDue": { - "message": "Past due", + "message": "Forbi måldatoen", "description": "A subscription status label" }, "subscriptionExpired": { - "message": "Subscription expired", + "message": "Abonnement har utløpt", "description": "The date header used when a subscription is past due." }, "pastDueWarningForChargeAutomatically": { @@ -9168,7 +9195,7 @@ "description": "The title for the section that deals with integrations and SDKs." }, "integrations": { - "message": "Integrations" + "message": "Integreringer" }, "integrationsDesc": { "message": "Automatically sync secrets from Bitwarden Secrets Manager to a third-party service." @@ -9180,7 +9207,7 @@ "message": "Use Bitwarden Secrets Manager SDK in the following programming languages to build your own applications." }, "ssoDescStart": { - "message": "Configure", + "message": "Sett opp", "description": "This represents the beginning of a sentence, broken up to include links. The full sentence will be 'Configure single sign-on for Bitwarden using the implementation guide for your Identity Provider." }, "ssoDescEnd": { @@ -9194,7 +9221,7 @@ "message": "SCIM" }, "scimIntegrationDescStart": { - "message": "Configure ", + "message": "Sett opp ", "description": "This represents the beginning of a sentence, broken up to include links. The full sentence will be 'Configure SCIM (System for Cross-domain Identity Management) to automatically provision users and groups to Bitwarden using the implementation guide for your Identity Provider" }, "scimIntegrationDescEnd": { @@ -9334,7 +9361,7 @@ "message": "Enter your Enterprise organization information" }, "viewItemsIn": { - "message": "View items in $NAME$", + "message": "Vis gjenstander i $NAME$", "description": "Button to view the contents of a folder or collection", "placeholders": { "name": { @@ -9344,7 +9371,7 @@ } }, "backTo": { - "message": "Back to $NAME$", + "message": "Tilbake til $NAME$", "description": "Navigate back to a previous folder or collection", "placeholders": { "name": { @@ -9354,11 +9381,11 @@ } }, "back": { - "message": "Back", + "message": "Tilbake", "description": "Button text to navigate back" }, "removeItem": { - "message": "Remove $NAME$", + "message": "Fjern $NAME$", "description": "Remove a selected option, such as a folder or collection", "placeholders": { "name": { @@ -9452,7 +9479,7 @@ "message": "Unverified" }, "verified": { - "message": "Verified" + "message": "Verifisert" }, "viewSecret": { "message": "View secret" @@ -9471,7 +9498,7 @@ "message": "Quickly view member access across the organization by upgrading to an Enterprise plan." }, "date": { - "message": "Date" + "message": "Dato" }, "exportClientReport": { "message": "Export client report" @@ -9498,13 +9525,13 @@ "message": "On" }, "memberAccessReportTwoFactorEnabledFalse": { - "message": "Off" + "message": "Av" }, "memberAccessReportAuthenticationEnabledTrue": { "message": "On" }, "memberAccessReportAuthenticationEnabledFalse": { - "message": "Off" + "message": "Av" }, "higherKDFIterations": { "message": "Higher KDF iterations can help protect your master password from being brute forced by an attacker." @@ -9549,7 +9576,7 @@ "message": "This action will remove your access to this secret." }, "invoice": { - "message": "Invoice" + "message": "Faktura" }, "unassignedSeatsAvailable": { "message": "You have $SEATS$ unassigned seats available.", @@ -9576,7 +9603,7 @@ "message": "Client details" }, "downloadCSV": { - "message": "Download CSV" + "message": "Last ned CSV" }, "monthlySubscriptionUserSeatsMessage": { "message": "Adjustments to your subscription will result in prorated charges to your billing totals on your next billing period. " @@ -9610,7 +9637,7 @@ "message": "Add to folder" }, "selectFolder": { - "message": "Select folder" + "message": "Velg mappe" }, "personalItemTransferWarningSingular": { "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." @@ -9662,13 +9689,13 @@ "message": "Project IDs" }, "projectId": { - "message": "Project ID" + "message": "Prosjekt-ID" }, "projectsAccessedByMachineAccount": { "message": "The following projects can be accessed by this machine account." }, "config": { - "message": "Config" + "message": "Oppsett" }, "learnMoreAboutEmergencyAccess": { "message": "Learn more about emergency access" @@ -9809,22 +9836,22 @@ "message": "Key algorithm" }, "sshPrivateKey": { - "message": "Private key" + "message": "Privat nøkkel" }, "sshPublicKey": { - "message": "Public key" + "message": "Offentlig nøkkel" }, "sshFingerprint": { - "message": "Fingerprint" + "message": "Fingeravtrykk" }, "sshKeyFingerprint": { - "message": "Fingerprint" + "message": "Fingeravtrykk" }, "sshKeyPrivateKey": { - "message": "Private key" + "message": "Privat nøkkel" }, "sshKeyPublicKey": { - "message": "Public key" + "message": "Offentlig nøkkel" }, "sshKeyAlgorithmED25519": { "message": "ED25519" @@ -9860,7 +9887,7 @@ "message": "Passwordless SSO" }, "accountRecovery": { - "message": "Account recovery" + "message": "Kontogjenoppretting" }, "customRoles": { "message": "Custom roles" @@ -9878,13 +9905,13 @@ "message": "Up to 20 machine accounts" }, "current": { - "message": "Current" + "message": "Nåværende" }, "secretsManagerSubscriptionInfo": { "message": "Your Secrets Manager subscription will upgrade based on the plan selected" }, "bitwardenPasswordManager": { - "message": "Bitwarden Password Manager" + "message": "Bitwarden passordbehandler" }, "secretsManagerComplimentaryPasswordManager": { "message": "Your complimentary one year Password Manager subscription will upgrade to the selected plan. You will not be charged until the complimentary period is over." @@ -9893,20 +9920,20 @@ "message": "File saved to device. Manage from your device downloads." }, "publicApi": { - "message": "Public API", + "message": "Offentlig API", "description": "The text, 'API', is an acronym and should not be translated." }, "showCharacterCount": { - "message": "Show character count" + "message": "Vis tegntelleren" }, "hideCharacterCount": { - "message": "Hide character count" + "message": "Skjul tegntelleren" }, "editAccess": { "message": "Edit access" }, "textHelpText": { - "message": "Use text fields for data like security questions" + "message": "Bruk tekstfelter for data som sikkerhetsspørsmål" }, "hiddenHelpText": { "message": "Use hidden fields for sensitive data like a password" @@ -9921,15 +9948,15 @@ "message": "Enter the the field's html id, name, aria-label, or placeholder." }, "uppercaseDescription": { - "message": "Include uppercase characters", + "message": "Inkluder store bokstaver", "description": "Tooltip for the password generator uppercase character checkbox" }, "uppercaseLabel": { - "message": "A-Z", + "message": "A-Å", "description": "Label for the password generator uppercase character checkbox" }, "lowercaseDescription": { - "message": "Include lowercase characters", + "message": "Inkluder små bokstaver", "description": "Full description for the password generator lowercase character checkbox" }, "lowercaseLabel": { @@ -9937,7 +9964,7 @@ "description": "Label for the password generator lowercase character checkbox" }, "numbersDescription": { - "message": "Include numbers", + "message": "Inkluder tall", "description": "Full description for the password generator numbers checkbox" }, "numbersLabel": { @@ -9945,7 +9972,7 @@ "description": "Label for the password generator numbers checkbox" }, "specialCharactersDescription": { - "message": "Include special characters", + "message": "Inkluder spesialtegn", "description": "Full description for the password generator special characters checkbox" }, "specialCharactersLabel": { @@ -9953,10 +9980,10 @@ "description": "Label for the password generator special characters checkbox" }, "addAttachment": { - "message": "Add attachment" + "message": "Legg til vedlegg" }, "maxFileSizeSansPunctuation": { - "message": "Maximum file size is 500 MB" + "message": "Maksimal filstørrelse er 500 MB" }, "permanentlyDeleteAttachmentConfirmation": { "message": "Are you sure you want to permanently delete this attachment?" @@ -10070,11 +10097,20 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { - "message": "Important notice" + "message": "Viktig melding" }, "setupTwoStepLogin": { - "message": "Set up two-step login" + "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." @@ -10083,7 +10119,7 @@ "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." }, "remindMeLater": { - "message": "Remind me later" + "message": "Minn meg på det senere" }, "newDeviceVerificationNoticePageOneFormContent": { "message": "Do you have reliable access to your email, $EMAIL$?", @@ -10101,16 +10137,16 @@ "message": "Yes, I can reliably access my email" }, "turnOnTwoStepLogin": { - "message": "Turn on two-step login" + "message": "Slå på 2-trinnsinnlogging" }, "changeAcctEmail": { - "message": "Change account email" + "message": "Endre kontoens E-postadresse" }, "removeMembers": { "message": "Remove members" }, "devices": { - "message": "Devices" + "message": "Enheter" }, "deviceListDescription": { "message": "Your account was logged in to each of the devices below. If you do not recognize a device, remove it now." @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/ne/messages.json b/apps/web/src/locales/ne/messages.json index fc8328efc95..20ceae6f33b 100644 --- a/apps/web/src/locales/ne/messages.json +++ b/apps/web/src/locales/ne/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Edit folder" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Base domain", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "ex.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Log in initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Submit" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "Version $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Regenerate password" - }, "length": { "message": "Length" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Danger zone" }, - "dangerZoneDesc": { - "message": "Careful, these actions are not reversible!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Deauthorize sessions" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Proceeding will also log you out of your current session, requiring you to log back in. You will also be prompted for two-step login again, if set up. Active sessions on other devices may continue to remain active for up to one hour." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "All sessions deauthorized" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Manage" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Turn off" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "There was a problem reading the security key. Try again." }, - "twoFactorWebAuthnWarning": { - "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used. Supported platforms:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Web vault and browser extensions on a desktop/laptop with a WebAuthn supported browser (Chrome, Opera, Vivaldi, or Firefox with FIDO U2F turned on)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Your Bitwarden two-step login recovery code" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Set requirements for password generator." }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organization policies are affecting your generator settings." - }, "masterPasswordPolicyInEffect": { "message": "One or more organization policies require your master password to meet the following requirements:" }, @@ -6666,15 +6717,6 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Use your domain's configured catch-all inbox." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Random", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Hostname", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API access token" - }, "deviceVerification": { "message": "Device verification" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "No collection" }, - "canView": { - "message": "Can view" - }, - "canViewExceptPass": { - "message": "Can view, except passwords" - }, - "canEdit": { - "message": "Can edit" - }, - "canEditExceptPass": { - "message": "Can edit, except passwords" - }, "noCollectionsAdded": { "message": "No collections added" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domain" - }, "alreadyHaveAccount": { "message": "Already have an account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/nl/messages.json b/apps/web/src/locales/nl/messages.json index 1f053997e34..6da0edc72c8 100644 --- a/apps/web/src/locales/nl/messages.json +++ b/apps/web/src/locales/nl/messages.json @@ -156,10 +156,10 @@ "message": "Totaal applicaties" }, "unmarkAsCriticalApp": { - "message": "Markeren als belangrijke applicatie ongedaan maken" + "message": "Markeren als belangrijke app ongedaan maken" }, "criticalApplicationSuccessfullyUnmarked": { - "message": "Markering als belangrijke applicatie ongedaan gemaakt" + "message": "Markeren als belangrijke app ongedaan gemaakt" }, "whatTypeOfItem": { "message": "Van welke categorie is dit item?" @@ -464,6 +464,18 @@ "editFolder": { "message": "Map bewerken" }, + "newFolder": { + "message": "Nieuwe map" + }, + "folderName": { + "message": "Mapnaam" + }, + "folderHintText": { + "message": "Je kunt een map onderbrengen door het toevoegen van de naam van de bovenliggende map gevolgd door een \"/\". Voorbeeld: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Weet je zeker dat je deze map definitief wilt verwijderen?" + }, "baseDomain": { "message": "Basisdomein", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Itemnaam" }, - "cannotRemoveViewOnlyCollections": { - "message": "Je kunt verzamelingen niet verwijderen met alleen rechten voor weergeven: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "bijv.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Inloggen gestart" }, + "logInRequestSent": { + "message": "Verzoek verzonden" + }, "submit": { "message": "Versturen" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "Er is een bericht naar je apparaat verstuurd." }, + "notificationSentDevicePart1": { + "message": "Ontgrendel Bitwarden op je apparaat of op de " + }, + "areYouTryingToAccessYourAccount": { + "message": "Probeer je toegang te krijgen tot je account?" + }, + "accessAttemptBy": { + "message": "Inlogpoging door $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Toegang bevestigen" + }, + "denyAccess": { + "message": "Toegang weigeren" + }, + "notificationSentDeviceAnchor": { + "message": "webapp" + }, + "notificationSentDevicePart2": { + "message": "Zorg ervoor dat de vingerafdrukzin overeenkomt met de onderstaande voor je deze goedkeurt." + }, + "notificationSentDeviceComplete": { + "message": "Ontgrendel Bitwarden op je apparaat. Zorg ervoor dat de vingerafdrukzin overeenkomt met de onderstaande voor je deze goedkeurt." + }, "aNotificationWasSentToYourDevice": { "message": "Er is een melding naar je apparaat verzonden" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Zorg ervoor dat je kluis is ontgrendeld en de vingerafdrukzin hetzelfde is op het andere apparaat" - }, "versionNumber": { "message": "Versie $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Dubbelzinnige tekens vermijden", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Opnieuw genereren" - }, "length": { "message": "Lengte" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Gevarenzone" }, - "dangerZoneDesc": { - "message": "Waarschuwing - deze acties zijn niet terug te draaien!" - }, - "dangerZoneDescSingular": { - "message": "Waarschuwing - deze actie is niet terug te draaien!" - }, "deauthorizeSessions": { "message": "Sessie-autorisaties intrekken" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Doorgaan zal je huidige sessie uitloggen, waarna je opnieuw moet inloggen. Je moet ook je tweestapsaanmelding opnieuw doorlopen, als die is ingeschakeld. Actieve sessies op andere apparaten blijven mogelijk nog een uur actief." }, + "newDeviceLoginProtection": { + "message": "Nieuwe apparaat login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Inlogbescherming nieuwe apparaten uitschakelen" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Inlogbescherming nieuwe apparaten inschakelen" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Ga hieronder verder voor het uitschakelen van de verificatie e-mails die Bitwarden stuurt wanneer je inlogt vanaf een nieuw apparaat." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Ga hieronder verder om Bitwarden verificatie e-mails te sturen wanneer je inlogt vanaf een nieuw apparaat." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "Als je inlogbescherming voor nieuwe apparaten uitschakelt, kan iedereen op ieder apparaat met je hoofdwachtwoord inloggen. Stel tweestapsaanmelding in om je account te beschermen zonder e-mailverificatieberichten." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "Wijzigingen inlogbescherming nieuwe apparaten opgeslagen" + }, "sessionsDeauthorized": { "message": "Autorisatie van alle sessies ingetrokken" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Beheren" }, - "canManage": { - "message": "Kan beheren" + "manageCollection": { + "message": "Collectie beheren" + }, + "viewItems": { + "message": "Items bekijken" + }, + "viewItemsHidePass": { + "message": "Items bekijken, verborgen wachtwoorden" + }, + "editItems": { + "message": "Items bewerken" + }, + "editItemsHidePass": { + "message": "Items bewerken, verborgen wachtwoorden" }, "disable": { "message": "Uitschakelen" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "Er was een probleem met het lezen van de beveiligingssleutel. Probeer het nogmaals." }, - "twoFactorWebAuthnWarning": { - "message": "Vanwege platformbeperkingen kan WebAuthn niet in alle Bitwarden applicaties gebruikt worden. Stel een andere tweestapsaanmeldingsaanbieder in zodat je je account kunt benaderen wanneer WebAuthn niet beschikbaar is. De volgende platformen worden ondersteund:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Webkluis en browser-extensies op een desktop/laptop met een browser met ondersteuning voor WebAuthn (Chrome, Opera, Vivaldi of Firefox met FIDO U2F ingeschakeld)." + "twoFactorWebAuthnWarning1": { + "message": "Vanwege platformbeperkingen kan WebAuthn niet in alle Bitwarden-applicaties gebruikt worden. Stel een andere tweestapsaanmeldingsaanbieder in zodat je je account kunt benaderen wanneer WebAuthn niet beschikbaar is." }, "twoFactorRecoveryYourCode": { "message": "Je herstelcode voor Bitwarden-tweestapsaanmelding" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Stel minimale vereisten in voor de configuratie van het wachtwoord generator." }, - "passwordGeneratorPolicyInEffect": { - "message": "Een of meer organisatiebeleidseisen heeft invloed op de instellingen van je generator." - }, "masterPasswordPolicyInEffect": { "message": "Een of meer organisatiebeleidseisen stelt de volgende eisen aan je hoofdwachtwoord:" }, @@ -6666,15 +6717,6 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "Wat wil je genereren?" - }, - "passwordType": { - "message": "Type wachtwoord" - }, - "regenerateUsername": { - "message": "Gebruikersnaam opnieuw genereren" - }, "generateUsername": { "message": "Gebruikersnaam genereren" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Type gebruikersnaam" - }, "plusAddressedEmail": { "message": "E-mailadres-met-plus", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Gebruik de catch-all inbox van je domein." }, + "useThisEmail": { + "message": "Dit e-mailadres gebruiken" + }, "random": { "message": "Willekeurig", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Hostnaam", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API-toegangstoken" - }, "deviceVerification": { "message": "Apparaatverificatie" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "Geen collectie" }, - "canView": { - "message": "Kan bekijken" - }, - "canViewExceptPass": { - "message": "Kan bekijken, behalve wachtwoorden" - }, - "canEdit": { - "message": "Kan bewerken" - }, - "canEditExceptPass": { - "message": "Kan bewerken, behalve wachtwoorden" - }, "noCollectionsAdded": { "message": "Geen collecties toegevoegd" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Verwijderen van collecties beperken tot eigenaren en managers" }, + "limitItemDeletionDesc": { + "message": "Beperk het verwijderen van items tot leden met het recht Kan beheren" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Eigenaren en beheerders kunnen alle collecties en items beheren" }, @@ -8656,9 +8686,6 @@ "message": "URL zelfgehoste server", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Aliasdomein" - }, "alreadyHaveAccount": { "message": "Heb je al een account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "Je hebt geen toegang om deze collectie te beheren." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Ontbrekende Kan beheren machtigingen" + "grantManageCollectionWarningTitle": { + "message": "Recht voor het beheren van machtigingen ontbreekt" }, - "grantAddAccessCollectionWarning": { - "message": "Kan beheren machtigingen verlenen voor volledig verzamelingsbeheer, inclusief het verwijderen van verzamelingen." + "grantManageCollectionWarning": { + "message": "Beheren van machtigingen toekennen voor het toestaan van het volledig verzamelingenbeheer, inclusief het verwijderen van een verzameling." }, "grantCollectionAccess": { "message": "Groepen of mensen toegang tot deze collectie geven." @@ -9809,7 +9836,7 @@ "message": "Sleutelalgoritme" }, "sshPrivateKey": { - "message": "Privésleutel" + "message": "Privé sleutel" }, "sshPublicKey": { "message": "Publieke sleutel" @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Code bankafschrift" }, + "cannotRemoveViewOnlyCollections": { + "message": "Je kunt verzamelingen niet verwijderen met alleen rechten voor weergeven: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Belangrijke mededeling" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Beheerders hebben nu de mogelijkheid om leden van een geclaimd domein te verwijderen." + }, + "deleteManagedUserWarningDesc": { + "message": "Deze actie verwijdert het account van het lid, inclusief alle items in hun kluis. Dit vervangt de vorige verwijderactie." + }, + "deleteManagedUserWarning": { + "message": "Verwijderen is een nieuwe actie!" + }, + "seatsRemaining": { + "message": "Je hebt nog $REMAINING$ plaatsen van de $TOTAL$ plaatsen die aan deze organisatie zijn toegewezen. Neem contact op met je provider om je abonnement te beheren.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Bestaande organisatie" + }, + "selectOrganizationProviderPortal": { + "message": "Kies een organisatie om aan je providerportaal toe te voegen." + }, + "noOrganizations": { + "message": "Er zijn geen organisaties om weer te geven" + }, + "yourProviderSubscriptionCredit": { + "message": "Je providerabonnement zal een credit ontvangen voor de resterende tijd van het abonnement van de organisatie." + }, + "doYouWantToAddThisOrg": { + "message": "Wilt je deze organisatie toevoegen aan $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Bestaande organisatie toegevoegd" + }, + "assignedExceedsAvailable": { + "message": "Meer toegewezen dan beschikbare plaatsen." } } diff --git a/apps/web/src/locales/nn/messages.json b/apps/web/src/locales/nn/messages.json index bb479db1a41..8b7682fa39c 100644 --- a/apps/web/src/locales/nn/messages.json +++ b/apps/web/src/locales/nn/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Rediger mappe" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Grunndomene", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "t.d.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Log in initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Submit" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "Version $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Regenerate password" - }, "length": { "message": "Length" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Danger zone" }, - "dangerZoneDesc": { - "message": "Careful, these actions are not reversible!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Deauthorize sessions" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Proceeding will also log you out of your current session, requiring you to log back in. You will also be prompted for two-step login again, if set up. Active sessions on other devices may continue to remain active for up to one hour." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "All sessions deauthorized" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Manage" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Slå av" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "There was a problem reading the security key. Try again." }, - "twoFactorWebAuthnWarning": { - "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used. Supported platforms:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Web vault and browser extensions on a desktop/laptop with a WebAuthn supported browser (Chrome, Opera, Vivaldi, or Firefox with FIDO U2F turned on)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Your Bitwarden two-step login recovery code" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Set requirements for password generator." }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organization policies are affecting your generator settings." - }, "masterPasswordPolicyInEffect": { "message": "One or more organization policies require your master password to meet the following requirements:" }, @@ -6666,15 +6717,6 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Use your domain's configured catch-all inbox." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Random", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Hostname", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API access token" - }, "deviceVerification": { "message": "Device verification" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "No collection" }, - "canView": { - "message": "Can view" - }, - "canViewExceptPass": { - "message": "Can view, except passwords" - }, - "canEdit": { - "message": "Can edit" - }, - "canEditExceptPass": { - "message": "Can edit, except passwords" - }, "noCollectionsAdded": { "message": "No collections added" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domain" - }, "alreadyHaveAccount": { "message": "Already have an account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/or/messages.json b/apps/web/src/locales/or/messages.json index 486f01ce2cb..7e6f614b9c8 100644 --- a/apps/web/src/locales/or/messages.json +++ b/apps/web/src/locales/or/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Edit folder" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Base domain", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "ex.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Log in initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Submit" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "Version $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Regenerate password" - }, "length": { "message": "Length" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Danger zone" }, - "dangerZoneDesc": { - "message": "Careful, these actions are not reversible!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Deauthorize sessions" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Proceeding will also log you out of your current session, requiring you to log back in. You will also be prompted for two-step login again, if set up. Active sessions on other devices may continue to remain active for up to one hour." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "All sessions deauthorized" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Manage" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Turn off" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "There was a problem reading the security key. Try again." }, - "twoFactorWebAuthnWarning": { - "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used. Supported platforms:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Web vault and browser extensions on a desktop/laptop with a WebAuthn supported browser (Chrome, Opera, Vivaldi, or Firefox with FIDO U2F turned on)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Your Bitwarden two-step login recovery code" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Set requirements for password generator." }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organization policies are affecting your generator settings." - }, "masterPasswordPolicyInEffect": { "message": "One or more organization policies require your master password to meet the following requirements:" }, @@ -6666,15 +6717,6 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Use your domain's configured catch-all inbox." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Random", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Hostname", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API access token" - }, "deviceVerification": { "message": "Device verification" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "No collection" }, - "canView": { - "message": "Can view" - }, - "canViewExceptPass": { - "message": "Can view, except passwords" - }, - "canEdit": { - "message": "Can edit" - }, - "canEditExceptPass": { - "message": "Can edit, except passwords" - }, "noCollectionsAdded": { "message": "No collections added" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domain" - }, "alreadyHaveAccount": { "message": "Already have an account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/pl/messages.json b/apps/web/src/locales/pl/messages.json index 779f29045f2..6935f334d62 100644 --- a/apps/web/src/locales/pl/messages.json +++ b/apps/web/src/locales/pl/messages.json @@ -3,22 +3,22 @@ "message": "Wszystkie aplikacje" }, "criticalApplications": { - "message": "Critical applications" + "message": "Krytyczne aplikacje" }, "accessIntelligence": { - "message": "Access Intelligence" + "message": "Dostęp do informacji" }, "riskInsights": { - "message": "Risk Insights" + "message": "Spostrzeżenia dotyczące ryzyka" }, "passwordRisk": { - "message": "Password Risk" + "message": "Ryzyko związne z hasłem" }, "reviewAtRiskPasswords": { - "message": "Review at-risk passwords (weak, exposed, or reused) across applications. Select your most critical applications to prioritize security actions for your users to address at-risk passwords." + "message": "Przejrzyj hasła zagrożone (słabe, ujawnione lub ponownie używane) we wszystkich aplikacjach. Wybierz swoje najbardziej krytyczne aplikacje, aby nadać priorytet działaniom bezpieczeństwa swoim użytkownikom, aby zająć się hasłami zagrożonymi." }, "dataLastUpdated": { - "message": "Data last updated: $DATE$", + "message": "Data ostatniej aktualizacji: $DATE$", "placeholders": { "date": { "content": "$1", @@ -30,16 +30,16 @@ "message": "Powiadomieni członkowie" }, "revokeMembers": { - "message": "Revoke members" + "message": "Unieważnij członk" }, "restoreMembers": { - "message": "Restore members" + "message": "Przywróć członków" }, "cannotRestoreAccessError": { - "message": "Cannot restore organization access" + "message": "Nie można przywrócić dostępu organizacji" }, "allApplicationsWithCount": { - "message": "All applications ($COUNT$)", + "message": "Wszystkie aplikacje ($COUNT$)", "placeholders": { "count": { "content": "$1", @@ -48,10 +48,10 @@ } }, "createNewLoginItem": { - "message": "Create new login item" + "message": "Utwórz nowy element logowania" }, "criticalApplicationsWithCount": { - "message": "Critical applications ($COUNT$)", + "message": "Aplikacje krytyczne ($COUNT$)", "placeholders": { "count": { "content": "$1", @@ -60,7 +60,7 @@ } }, "notifiedMembersWithCount": { - "message": "Notified members ($COUNT$)", + "message": "Powiadomieni członkowie ($COUNT$)", "placeholders": { "count": { "content": "$1", @@ -69,7 +69,7 @@ } }, "noAppsInOrgTitle": { - "message": "No applications found in $ORG NAME$", + "message": "Nie znaleziono aplikacji w $ORG NAME$", "placeholders": { "org name": { "content": "$1", @@ -78,43 +78,43 @@ } }, "noAppsInOrgDescription": { - "message": "As users save logins, applications appear here, showing any at-risk passwords. Mark critical apps and notify users to update passwords." + "message": "Jako użytkownicy zapisują logowania, pojawiają się tutaj aplikacje, pokazujące wszelkie hasła zagrożone. Zaznacz kluczowe aplikacje i powiadamiaj użytkowników o potrzebie aktualizacji haseł." }, "noCriticalAppsTitle": { - "message": "You haven't marked any applications as a Critical" + "message": "Nie oznaczyłeś żadnych aplikacji jako krytycznych" }, "noCriticalAppsDescription": { - "message": "Select your most critical applications to discover at-risk passwords, and notify users to change those passwords." + "message": "Wybierz najbardziej krytyczne aplikacje, aby odkryć hasła zagrożone i poinformuj użytkowników, by zmienili te hasła." }, "markCriticalApps": { - "message": "Mark critical apps" + "message": "Oznacz krytyczne aplikacje" }, "markAppAsCritical": { - "message": "Mark app as critical" + "message": "Oznacz aplikację jako krytyczną" }, "appsMarkedAsCritical": { - "message": "Apps marked as critical" + "message": "Aplikacje oznaczone jako krytyczne" }, "application": { "message": "Aplikacja" }, "atRiskPasswords": { - "message": "At-risk passwords" + "message": "Zagrożone hasła" }, "requestPasswordChange": { - "message": "Request password change" + "message": "Poproś o zmianę hasła" }, "totalPasswords": { - "message": "Total passwords" + "message": "Wszystkie hasła" }, "searchApps": { - "message": "Search applications" + "message": "Wyszukaj aplikacje" }, "atRiskMembers": { - "message": "At-risk members" + "message": "Zagrożeni użytkownicy" }, "atRiskMembersWithCount": { - "message": "At-risk members ($COUNT$)", + "message": "Zagrożeni członkowie ($COUNT$)", "placeholders": { "count": { "content": "$1", @@ -123,7 +123,7 @@ } }, "atRiskApplicationsWithCount": { - "message": "At-risk applications ($COUNT$)", + "message": "Zagrożone aplikacje ($COUNT$)", "placeholders": { "count": { "content": "$1", @@ -132,13 +132,13 @@ } }, "atRiskMembersDescription": { - "message": "These members are logging into applications with weak, exposed, or reused passwords." + "message": "Ci członkowie logują się do aplikacji ze słabymi, ujawnionymi lub ponownie używanymi hasłami." }, "atRiskApplicationsDescription": { - "message": "These applications have weak, exposed, or reused passwords." + "message": "Te aplikacje mają słabe, ujawnione lub ponownie użyte hasła." }, "atRiskMembersDescriptionWithApp": { - "message": "These members are logging into $APPNAME$ with weak, exposed, or reused passwords.", + "message": "Ci użytkownicy logują się do $APPNAME$ ze słabymi, ujawnionymi lub ponownie używanymi hasłami.", "placeholders": { "appname": { "content": "$1", @@ -147,19 +147,19 @@ } }, "totalMembers": { - "message": "Total members" + "message": "Wszyscy członkowie" }, "atRiskApplications": { - "message": "At-risk applications" + "message": "Zagrożone aplikacje" }, "totalApplications": { - "message": "Total applications" + "message": "Wszystkie aplikacje" }, "unmarkAsCriticalApp": { - "message": "Unmark as critical app" + "message": "Odznacz jako krytyczną aplikację" }, "criticalApplicationSuccessfullyUnmarked": { - "message": "Critical application successfully unmarked" + "message": "Krytyczna aplikacja została pomyślnie odznaczona" }, "whatTypeOfItem": { "message": "Jakiego rodzaju jest to element?" @@ -464,6 +464,18 @@ "editFolder": { "message": "Edytuj folder" }, + "newFolder": { + "message": "Nowy folder" + }, + "folderName": { + "message": "Nazwa folderu" + }, + "folderHintText": { + "message": "Zagnieżdżaj foldery dodając nazwę folderu nadrzędnego, a następnie “/”. Przykład: Społeczne/Fora" + }, + "deleteFolderPermanently": { + "message": "Czy na pewno chcesz trwale usunąć ten folder?" + }, "baseDomain": { "message": "Domena podstawowa", "description": "Domain name. Example: website.com" @@ -508,7 +520,7 @@ "message": "Wygeneruj hasło" }, "generatePassphrase": { - "message": "Generate passphrase" + "message": "Wygeneruj hasło wyrazowe" }, "checkPassword": { "message": "Sprawdź, czy hasło zostało ujawnione." @@ -611,7 +623,7 @@ "message": "Bezpieczna notatka" }, "typeSshKey": { - "message": "SSH key" + "message": "Klucz SSH" }, "typeLoginPlural": { "message": "Dane logowania" @@ -707,7 +719,7 @@ } }, "viewItemType": { - "message": "Zobacz $TYPE$", + "message": "Zobacz $ITEMTYPE$", "placeholders": { "itemtype": { "content": "$1", @@ -728,15 +740,6 @@ "itemName": { "message": "Nazwa elementu" }, - "cannotRemoveViewOnlyCollections": { - "message": "Nie można usunąć kolekcji z uprawnieniami tylko do przeglądania: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "np.", "description": "Short abbreviation for 'example'." @@ -772,11 +775,11 @@ "description": "Copy password to clipboard" }, "copyPassphrase": { - "message": "Copy passphrase", + "message": "Skopiuj hasło wyrazowe", "description": "Copy passphrase to clipboard" }, "passwordCopied": { - "message": "Password copied" + "message": "Hasło zostało skopiowane" }, "copyUsername": { "message": "Kopiuj nazwę użytkownika", @@ -1033,7 +1036,7 @@ "message": "Logowanie za pomocą urządzenia musi być włączone w ustawieniach aplikacji Bitwarden. Potrzebujesz innej opcji?" }, "needAnotherOptionV1": { - "message": "Need another option?" + "message": "Potrzebujesz innego sposobu?" }, "loginWithMasterPassword": { "message": "Logowanie hasłem głównym" @@ -1048,13 +1051,13 @@ "message": "Użyj innej metody logowania" }, "logInWithPasskey": { - "message": "Log in with passkey" + "message": "Logowanie się za pomocą Passkey" }, "useSingleSignOn": { - "message": "Use single sign-on" + "message": "Użyj jednokrotnego logowania" }, "welcomeBack": { - "message": "Welcome back" + "message": "Witaj ponownie" }, "invalidPasskeyPleaseTryAgain": { "message": "Błędny passkey. Spróbuj ponownie." @@ -1138,7 +1141,7 @@ "message": "Utwórz konto" }, "newToBitwarden": { - "message": "New to Bitwarden?" + "message": "Nowy na Bitwarden?" }, "setAStrongPassword": { "message": "Ustaw silne hasło" @@ -1156,32 +1159,35 @@ "message": "Zaloguj się" }, "logInToBitwarden": { - "message": "Log in to Bitwarden" + "message": "Zaloguj do Bitwarden" }, "authenticationTimeout": { - "message": "Authentication timeout" + "message": "Limit czasu uwierzytelniania" }, "authenticationSessionTimedOut": { - "message": "The authentication session timed out. Please restart the login process." + "message": "Upłynął limit czasu uwierzytelniania. Uruchom ponownie proces logowania." }, "verifyIdentity": { "message": "Zweryfikuj swoją tożsamość" }, "weDontRecognizeThisDevice": { - "message": "We don't recognize this device. Enter the code sent to your email to verify your identity." + "message": "Nie rozpoznajemy tego urządzenia. Wpisz kod wysłany na Twój e-mail, aby zweryfikować tożsamość." }, "continueLoggingIn": { - "message": "Continue logging in" + "message": "Kontynuuj logowanie" }, "whatIsADevice": { - "message": "What is a device?" + "message": "Czym jest urządzenie?" }, "aDeviceIs": { - "message": "A device is a unique installation of the Bitwarden app where you have logged in. Reinstalling, clearing app data, or clearing your cookies could result in a device appearing multiple times." + "message": "Urządzenie to unikalna instalacja aplikacji Bitwarden, w której się zalogowano. Ponowna instalacja, wyczyszczenie danych aplikacji lub usunięcie plików cookie może spowodować, że urządzenie pojawi się wielokrotnie." }, "logInInitiated": { "message": "Logowanie rozpoczęte" }, + "logInRequestSent": { + "message": "Żądanie wysłane" + }, "submit": { "message": "Wyślij" }, @@ -1305,10 +1311,10 @@ "message": "Adres e-mail" }, "yourVaultIsLockedV2": { - "message": "Twój sejf jest zablokowany." + "message": "Twój sejf jest zablokowany" }, "yourAccountIsLocked": { - "message": "Your account is locked" + "message": "Twoje konto jest zablokowane" }, "uuid": { "message": "UUID" @@ -1345,7 +1351,7 @@ "message": "Nie masz uprawnień do przeglądania wszystkich elementów w tej kolekcji." }, "youDoNotHavePermissions": { - "message": "You do not have permissions to this collection" + "message": "Nie masz uprawnień do tej kolekcji" }, "noCollectionsInList": { "message": "Brak kolekcji do wyświetlenia." @@ -1371,11 +1377,38 @@ "notificationSentDevice": { "message": "Powiadomienie zostało wysłane na urządzenie." }, - "aNotificationWasSentToYourDevice": { - "message": "A notification was sent to your device" + "notificationSentDevicePart1": { + "message": "Odblokuj Bitwarden na swoim urządzeniu lub w" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" + "areYouTryingToAccessYourAccount": { + "message": "Czy próbujesz uzyskać dostęp do swojego konta?" + }, + "accessAttemptBy": { + "message": "Próba dostępu przez $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Potwierdź dostęp" + }, + "denyAccess": { + "message": "Odmów dostępu" + }, + "notificationSentDeviceAnchor": { + "message": "aplikacji internetowej" + }, + "notificationSentDevicePart2": { + "message": "Upewnij się, że fraza odcisku palca zgadza się z tą poniżej, zanim zatwierdzisz." + }, + "notificationSentDeviceComplete": { + "message": "Odblokuj Bitwarden na swoim urządzeniu. Przed zatwierdzeniem upewnij się, że fraza odcisku palca pasuje do tej poniżej." + }, + "aNotificationWasSentToYourDevice": { + "message": "Powiadomienie zostało wysłane na twoje urządzenie" }, "versionNumber": { "message": "Wersja $VERSION_NUMBER$", @@ -1468,7 +1501,7 @@ "message": "Klucz bezpieczeństwa FIDO U2F" }, "webAuthnTitle": { - "message": "FIDO2 WebAuthn" + "message": "Klucz dostępu" }, "webAuthnDesc": { "message": "Użyj dowolnego klucza bezpieczeństwa WebAuthn, aby uzyskać dostęp do swojego konta." @@ -1661,12 +1694,9 @@ "description": "deprecated. Use avoidAmbiguous instead." }, "avoidAmbiguous": { - "message": "Avoid ambiguous characters", + "message": "Unikaj niejednoznacznych znaków", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Wygeneruj ponownie hasło" - }, "length": { "message": "Długość" }, @@ -1709,25 +1739,25 @@ "message": "Historia hasła" }, "generatorHistory": { - "message": "Generator history" + "message": "Historia generatora" }, "clearGeneratorHistoryTitle": { - "message": "Clear generator history" + "message": "Wyczyść historię generatora" }, "cleargGeneratorHistoryDescription": { - "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + "message": "Jeśli zatwierdzisz, wszystkie wygenerowane hasła zostaną usunięte z historii generatora. Czy chcesz kontynuować mimo to?" }, "noPasswordsInList": { "message": "Brak haseł." }, "clearHistory": { - "message": "Clear history" + "message": "Wyczyść historię" }, "nothingToShow": { - "message": "Nothing to show" + "message": "Brak zawartości do pokazania" }, "nothingGeneratedRecently": { - "message": "You haven't generated anything recently" + "message": "Nic nie zostało wygenerowane przez ciebie w ostatnim czasie" }, "clear": { "message": "Wyczyść", @@ -1767,10 +1797,10 @@ "message": "Zaloguj się ponownie." }, "currentSession": { - "message": "Current session" + "message": "Aktualna sesja" }, "requestPending": { - "message": "Request pending" + "message": "Zapytanie oczekuje" }, "logBackInOthersToo": { "message": "Zaloguj się ponownie. Jeśli używasz innych aplikacji Bitwarden, wyloguj się i zaloguj ponownie również w nich." @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Niebezpieczna strefa" }, - "dangerZoneDesc": { - "message": "Uwaga - te operacje są nieodwracalne!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Zakończ sesje" }, @@ -1854,11 +1878,32 @@ "deauthorizeSessionsWarning": { "message": "Ta czynność spowoduje wylogowanie z bieżącej sesji, przez co konieczne będzie ponowne zalogowanie się. Zostaniesz również poproszony o ponowne logowanie dwustopniowe, jeśli masz włączoną tę opcję. Aktywne sesje na innych urządzeniach mogą pozostać aktywne przez maksymalnie godzinę." }, + "newDeviceLoginProtection": { + "message": "Logowanie nowego urządzenia" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Wyłącz ochronę logowania na nowym urządzeniu" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Włącz ochronę logowania na nowym urządzeniu" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Przejdź poniżej, aby wyłączyć e-maile weryfikacyjne wysyłane przez Bitwarden podczas logowania z nowego urządzenia." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Przejdź poniżej, aby Bitwarden wysyłał Ci e-maile weryfikacyjne podczas logowania z nowego urządzenia." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "Po wyłączeniu ochrony logowania na nowym urządzeniu, każdy, kto zna Twoje hasło główne, może uzyskać dostęp do Twojego konta z dowolnego urządzenia. Aby chronić swoje konto bez e-maili weryfikacyjnych, skonfiguruj dwuetapowe logowanie." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "Zapisano nowe zmiany ochrony logowania" + }, "sessionsDeauthorized": { "message": "Wszystkie sesje zostały zakończone" }, "accountIsOwnedMessage": { - "message": "This account is owned by $ORGANIZATIONNAME$", + "message": "To konto jest własnością $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -1923,7 +1968,7 @@ "description": "This will be part of a larger sentence, that will read like this: If you don't have any data to import, you can create a new item instead. (Optional second half: You may need to wait until your administrator confirms your organization membership.)" }, "onboardingImportDataDetailsLoginLink": { - "message": "new login", + "message": "Nowe dane logowania", "description": "This will be part of a larger sentence, that will read like this: If you don't have any data to import, you can create a new login instead. (Optional second half: You may need to wait until your administrator confirms your organization membership.)" }, "onboardingImportDataDetailsPartTwoNoOrgs": { @@ -2155,8 +2200,20 @@ "manage": { "message": "Zarządzaj" }, - "canManage": { - "message": "Może zarządzać" + "manageCollection": { + "message": "Zarządzaj kolekcją" + }, + "viewItems": { + "message": "Zobacz elementy" + }, + "viewItemsHidePass": { + "message": "Zobacz elementy, ukryte hasła" + }, + "editItems": { + "message": "Edytuj elementy" + }, + "editItemsHidePass": { + "message": "Edytuj elementy, ukryte hasła" }, "disable": { "message": "Wyłącz" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "Wystąpił problem z odczytem klucza bezpieczeństwa. Spróbuj ponownie." }, - "twoFactorWebAuthnWarning": { - "message": "Z powodu ograniczeń platformy, klucze WebAuthn nie mogą być używane we wszystkich aplikacjach Bitwarden. Musisz włączyć inną metodę logowania dwustopniowego, aby zachować dostęp do konta w pozostałych sytuacjach. Wspierane platformy:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Sejf internetowy i rozszerzenia przeglądarki na komputerze/laptopie z przeglądarką obsługującą WebAuthn (Chrome, Opera, Vivaldi lub Firefox z włączoną obsługą FIDO U2F)." + "twoFactorWebAuthnWarning1": { + "message": "Z powodu ograniczeń platformy, klucze WebAuthn nie mogą być używane we wszystkich aplikacjach Bitwarden. Musisz włączyć inną metodę logowania dwustopniowego, aby zachować dostęp do konta w pozostałych sytuacjach." }, "twoFactorRecoveryYourCode": { "message": "Kod odzyskiwania konta Bitwarden" @@ -2462,7 +2516,7 @@ "message": "Sprawdź ujawnione hasła" }, "timesExposed": { - "message": "Times exposed" + "message": "Ujawniono" }, "exposedXTimes": { "message": "Ujawnione $COUNT$ raz(y)", @@ -2499,7 +2553,7 @@ "message": "Brak elementów zawierających słabe hasła." }, "weakness": { - "message": "Weakness" + "message": "Słabe" }, "reusedPasswordsReport": { "message": "Identyczne hasła" @@ -2527,7 +2581,7 @@ "message": "Nie znaleźliśmy identycznych haseł w sejfie." }, "timesReused": { - "message": "Times reused" + "message": "Ponownie użyto" }, "reusedXTimes": { "message": "Wykorzystane $COUNT$ razy", @@ -2827,7 +2881,7 @@ "message": "Pobierz licencję" }, "viewBillingToken": { - "message": "View Billing Token" + "message": "Pokaż token płatności" }, "updateLicense": { "message": "Zaktualizuj licencję" @@ -2876,10 +2930,10 @@ "message": "Faktury" }, "noUnpaidInvoices": { - "message": "No unpaid invoices." + "message": "Brak nieopłaconych faktur." }, "noPaidInvoices": { - "message": "No paid invoices." + "message": "Brak opłaconych faktur." }, "paid": { "message": "Zapłacono", @@ -3324,10 +3378,10 @@ } }, "inviteSingleEmailDesc": { - "message": "You have 1 invite remaining." + "message": "Pozostało Ci 1 zaproszenie." }, "inviteZeroEmailDesc": { - "message": "You have 0 invites remaining." + "message": "Pozostało Ci 0 zaproszeń." }, "userUsingTwoStep": { "message": "Ten użytkownik korzysta z logowania dwustopniowego, aby chronić swoje konto." @@ -3363,7 +3417,7 @@ "message": "Użytkownik" }, "userDesc": { - "message": "Standardowy użytkownik, posiadający dostęp do kolekcji w Twojej organizacji." + "message": "Standardowy użytkownik, posiadający dostęp do kolekcji w Twojej organizacji" }, "all": { "message": "Wszyscy" @@ -3493,7 +3547,7 @@ } }, "viewAllLogInOptions": { - "message": "View all log in options" + "message": "Zobacz wszystkie sposoby logowania" }, "viewAllLoginOptions": { "message": "Zobacz wszystkie sposoby logowania" @@ -3781,7 +3835,7 @@ } }, "unlinkedSso": { - "message": "Unlinked SSO." + "message": "Odłączone SSO" }, "unlinkedSsoUser": { "message": "Odłącz logowanie jednokrotne SSO dla użytkownika %$ID$.", @@ -3832,22 +3886,22 @@ "message": "Urządzenie" }, "loginStatus": { - "message": "Login status" + "message": "Status zalogowania" }, "firstLogin": { - "message": "First login" + "message": "Pierwsze logowanie" }, "trusted": { - "message": "Trusted" + "message": "Zaufane" }, "needsApproval": { - "message": "Needs approval" + "message": "Wymaga zatwierdzenia" }, "areYouTryingtoLogin": { - "message": "Are you trying to log in?" + "message": "Próbujesz się zalogować?" }, "logInAttemptBy": { - "message": "Login attempt by $EMAIL$", + "message": "Próba logowania przez $EMAIL$", "placeholders": { "email": { "content": "$1", @@ -3856,22 +3910,22 @@ } }, "deviceType": { - "message": "Device Type" + "message": "Typ urządenia" }, "ipAddress": { - "message": "IP Address" + "message": "Adres IP" }, "confirmLogIn": { - "message": "Confirm login" + "message": "Potwierdź logowanie" }, "denyLogIn": { - "message": "Deny login" + "message": "Odrzuć logowanie" }, "thisRequestIsNoLongerValid": { - "message": "This request is no longer valid." + "message": "To żądanie jest już nieważne." }, "logInConfirmedForEmailOnDevice": { - "message": "Login confirmed for $EMAIL$ on $DEVICE$", + "message": "Logowanie potwierdzone dla $EMAIL$ na $DEVICE$", "placeholders": { "email": { "content": "$1", @@ -3884,16 +3938,16 @@ } }, "youDeniedALogInAttemptFromAnotherDevice": { - "message": "You denied a login attempt from another device. If this really was you, try to log in with the device again." + "message": "Odrzucono próby logowania z innego urządzenia. Jeśli to naprawdę Ty, spróbuj ponownie zalogować się za pomocą urządzenia." }, "loginRequestHasAlreadyExpired": { - "message": "Login request has already expired." + "message": "Prośba logowania wygasła." }, "justNow": { - "message": "Just now" + "message": "Teraz" }, "requestedXMinutesAgo": { - "message": "Requested $MINUTES$ minutes ago", + "message": "Poproszono $MINUTES$ minut temu", "placeholders": { "minutes": { "content": "$1", @@ -4019,13 +4073,13 @@ "message": "Aktualizuj przeglądarkę" }, "generatingRiskInsights": { - "message": "Generating your risk insights..." + "message": "Generowanie informacji o ryzyku..." }, "updateBrowserDesc": { "message": "Używasz nieobsługiwanej przeglądarki. Sejf internetowy może działać niewłaściwie." }, "freeTrialEndPromptCount": { - "message": "Your free trial ends in $COUNT$ days.", + "message": "Twój okres próbny kończy się za $COUNT$ dni.", "placeholders": { "count": { "content": "$1", @@ -4034,7 +4088,7 @@ } }, "freeTrialEndPromptMultipleDays": { - "message": "$ORGANIZATION$, your free trial ends in $COUNT$ days.", + "message": "$ORGANIZATION$, twoja darmowa wersja próbna kończy się za $COUNT$ dni.", "placeholders": { "count": { "content": "$2", @@ -4047,7 +4101,7 @@ } }, "freeTrialEndPromptTomorrow": { - "message": "$ORGANIZATION$, your free trial ends tomorrow.", + "message": "$ORGANIZATION$, twoja darmowa wersja próbna kończy się jutro", "placeholders": { "organization": { "content": "$1", @@ -4056,10 +4110,10 @@ } }, "freeTrialEndPromptTomorrowNoOrgName": { - "message": "Your free trial ends tomorrow." + "message": "Twój okres próbny kończy się jutro." }, "freeTrialEndPromptToday": { - "message": "$ORGANIZATION$, your free trial ends today.", + "message": "$ORGANIZATION$, twoja darmowa wersja próbna kończy się dzisiaj", "placeholders": { "organization": { "content": "$1", @@ -4068,10 +4122,10 @@ } }, "freeTrialEndingTodayWithoutOrgName": { - "message": "Your free trial ends today." + "message": "Twój okres próbny kończy się dzisiaj." }, "clickHereToAddPaymentMethod": { - "message": "Click here to add a payment method." + "message": "Kliknij tutaj, aby dodać metodę płatności." }, "joinOrganization": { "message": "Dołącz do organizacji" @@ -4628,7 +4682,7 @@ "description": "A 'fingerprint phrase' is a unique word phrase (similar to a passphrase) that a user can use to authenticate their public key with another user, for the purposes of sharing." }, "youWillBeNotifiedOnceTheRequestIsApproved": { - "message": "You will be notified once the request is approved" + "message": "Zostaniesz powiadomiony po zatwierdzeniu prośby" }, "free": { "message": "Darmowy", @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Ustaw minimalne wymagania dla generatora hasła." }, - "passwordGeneratorPolicyInEffect": { - "message": "Co najmniej jedna zasada organizacji wpływa na ustawienia generatora." - }, "masterPasswordPolicyInEffect": { "message": "Co najmniej jedna zasada organizacji wymaga, aby hasło główne spełniało następujące wymagania:" }, @@ -4861,10 +4912,10 @@ "message": "Zaloguj się za pomocą logowania jednokrotnego SSO swojej organizacji. Aby rozpocząć, wpisz swój identyfikator organizacji." }, "singleSignOnEnterOrgIdentifier": { - "message": "Enter your organization's SSO identifier to begin" + "message": "Wprowadź identyfikator SSO swojej organizacji, aby rozpocząć" }, "singleSignOnEnterOrgIdentifierText": { - "message": "To log in with your SSO provider, enter your organization's SSO identifier to begin. You may need to enter this SSO identifier when you log in from a new device." + "message": "Aby zalogować się za pomocą dostawcy SSO, wprowadź identyfikator SSO organizacji, aby rozpocząć. Może być konieczne wprowadzenie identyfikatora SSO podczas logowania z nowego urządzenia." }, "enterpriseSingleSignOn": { "message": "Logowanie jednokrotne" @@ -4934,7 +4985,7 @@ "message": "Zablokuj użytkownikom możliwość dołączania do innych organizacji." }, "singleOrgPolicyDesc": { - "message": "Restrict members from joining other organizations. This policy is required for organizations that have enabled domain verification." + "message": "Ogranicz członków do dołączania do innych organizacji. Ta polityka jest wymagana dla organizacji, które włączyły weryfikację domeny." }, "singleOrgBlockCreateMessage": { "message": "Twoja obecna organizacja posiada zasady, które nie pozwalają na dołączanie do więcej niż jednej organizacji. Skontaktuj się z administratorami swojej organizacji lub zarejestruj się z innego konta Bitwarden." @@ -4943,7 +4994,7 @@ "message": "Członkowie organizacji, którzy nie są właścicielami lub administratorami i są już członkami innej organizacji zostaną usunięci z Twojej organizacji." }, "singleOrgPolicyMemberWarning": { - "message": "Non-compliant members will be placed in revoked status until they leave all other organizations. Administrators are exempt and can restore members once compliance is met." + "message": "Niezgodni członkowie zostaną objęci cofniętym statusem do czasu opuszczenia przez nich wszystkich innych organizacji. Administratorzy są zwolnieni i mogą przywrócić członków po osiągnięciu zgodności." }, "requireSso": { "message": "Uwierzytelnianie logowaniem jednokrotnym" @@ -5323,7 +5374,7 @@ "message": "Niestandardowe" }, "customDesc": { - "message": "Umożliwia zaawansowaną kontrolę uprawnień użytkownika." + "message": "Umożliwia zaawansowaną kontrolę uprawnień użytkownika" }, "customDescNonEnterpriseStart": { "message": "Role niestandardowe to ", @@ -5669,7 +5720,7 @@ "message": "Hasło zostało zresetowane!" }, "resetPasswordEnrollmentWarning": { - "message": "Rejestracja zezwala administratorom organizacji na zmianę Twojego hasła głównego. Czy na pewno chcesz się zarejestrować?" + "message": "Rejestracja zezwala administratorom organizacji na zmianę Twojego hasła głównego" }, "accountRecoveryPolicy": { "message": "Administracja odzyskiwaniem konta" @@ -5768,13 +5819,13 @@ "message": "Przywrócono dostęp do organizacji" }, "bulkFilteredMessage": { - "message": "Wykluczono, nie dotyczy tej akcji." + "message": "Wykluczono, nie dotyczy tej akcji" }, "nonCompliantMembersTitle": { - "message": "Non-compliant members" + "message": "Niezgodni członkowie" }, "nonCompliantMembersError": { - "message": "Members that are non-compliant with the Single organization or Two-step login policy cannot be restored until they adhere to the policy requirements" + "message": "Niezgodni członkowie z jedną organizacją lub dwustopniową regułą logowania nie mogą zostać przywróceni, dopóki nie będą przestrzegali wymogów polityki" }, "fingerprint": { "message": "Unikalny identyfikator konta" @@ -5792,17 +5843,17 @@ "message": "Błąd" }, "decryptionError": { - "message": "Decryption error" + "message": "Błąd odszyfrowywania" }, "couldNotDecryptVaultItemsBelow": { - "message": "Bitwarden could not decrypt the vault item(s) listed below." + "message": "Bitwarden nie mógł odszyfrować elementów sejfu wymienionych poniżej." }, "contactCSToAvoidDataLossPart1": { - "message": "Contact customer success", + "message": "Skontaktuj się z działem obsługi klienta,", "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": "aby uniknąć dalszej utraty danych.", "description": "This is part of a larger sentence. The full sentence will read 'Contact customer success to avoid additional data loss.'" }, "accountRecoveryManageUsers": { @@ -5821,7 +5872,7 @@ "message": "Nazwa dostawcy" }, "providerSetup": { - "message": "Dostawca został skonfigurowany." + "message": "Dostawca został skonfigurowany" }, "clients": { "message": "Klienci" @@ -6376,11 +6427,11 @@ "message": "Key Connector" }, "memberDecryptionKeyConnectorDescStart": { - "message": "Połącz logowanie za pomocą SSO z Twoim serwerem kluczy odszyfrowania. Używając tej opcji, członkowie nie będą musieli używać swoich haseł głównych, aby odszyfrować dane sejfu.", + "message": "Połącz logowanie za pomocą SSO z Twoim serwerem kluczy odszyfrowania. Używając tej opcji, członkowie nie będą musieli używać swoich haseł głównych, aby odszyfrować dane sejfu", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Connect login with SSO to your self-hosted decryption key server. Using this option, members won’t need to use their master passwords to decrypt vault data. The require SSO authentication and single organization policies are required to set up Key Connector decryption. Contact Bitwarden Support for set up assistance.'" }, "memberDecryptionKeyConnectorDescLink": { - "message": "Wymaga uwierzytelniania SSO i polityki jednej organizacji", + "message": "wymaga uwierzytelniania SSO i polityki jednej organizacji", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Connect login with SSO to your self-hosted decryption key server. Using this option, members won’t need to use their master passwords to decrypt vault data. The require SSO authentication and single organization policies are required to set up Key Connector decryption. Contact Bitwarden Support for set up assistance.'" }, "memberDecryptionKeyConnectorDescEnd": { @@ -6442,7 +6493,7 @@ "message": "Pokaż token synchronizacji płatności" }, "generateBillingToken": { - "message": "Generate billing token" + "message": "Wygeneruj token płatności" }, "copyPasteBillingSync": { "message": "Skopiuj i wklej ten token do ustawień synchronizacji rozliczeniowej swojej organizacji." @@ -6451,7 +6502,7 @@ "message": "Twój token synchronizacji płatności może edytować ustawienia subskrypcji tej organizacji." }, "manageBillingTokenSync": { - "message": "Manage Billing Token" + "message": "Zarządzaj tokenami płatności" }, "setUpBillingSync": { "message": "Skonfiguruj synchronizację płatności" @@ -6517,7 +6568,7 @@ "message": "Token synchronizacji płatności" }, "automaticBillingSyncDesc": { - "message": "Automatic sync unlocks Families sponsorships and allows you to sync your license without uploading a file. After making updates in the Bitwarden cloud server, select Sync License to apply changes." + "message": "Automatyczna synchronizacja odblokowuje sponsorowanie rodzin i pozwala na synchronizację licencji bez przesyłania pliku. Po aktualizacjach w chmurze Bitwarden, wybierz licencję synchronizacji aby zastosować zmiany." }, "active": { "message": "Aktywny" @@ -6587,7 +6638,7 @@ "message": "Wymagane, jeśli identyfikatorem podmiotu nie jest adres URL." }, "offerNoLongerValid": { - "message": "This offer is no longer valid. Contact your organization administrators for more information." + "message": "Ta oferta nie jest już ważna. Aby uzyskać więcej informacji, skontaktuj się z administratorami organizacji." }, "openIdOptionalCustomizations": { "message": "Opcjonalne dostosowania" @@ -6666,23 +6717,14 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "Co chcesz wygenerować?" - }, - "passwordType": { - "message": "Rodzaj hasła" - }, - "regenerateUsername": { - "message": "Wygeneruj ponownie nazwę użytkownika" - }, "generateUsername": { "message": "Wygeneruj nazwę użytkownika" }, "generateEmail": { - "message": "Generate email" + "message": "Wygeneruj e-mail" }, "spinboxBoundariesHint": { - "message": "Value must be between $MIN$ and $MAX$.", + "message": "Wartość musi być pomiędzy $MIN$ a $MAX$.", "description": "Explains spin box minimum and maximum values to the user", "placeholders": { "min": { @@ -6696,7 +6738,7 @@ } }, "passwordLengthRecommendationHint": { - "message": " Use $RECOMMENDED$ characters or more to generate a strong password.", + "message": " Użyj $RECOMMENDED$ znaków lub więcej, aby wygenerować silne hasło.", "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": { @@ -6706,7 +6748,7 @@ } }, "passphraseNumWordsRecommendationHint": { - "message": " Use $RECOMMENDED$ words or more to generate a strong passphrase.", + "message": " Użyj $RECOMMENDED$ słów lub więcej, aby wygenerować silne hasło.", "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": { @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Rodzaj nazwy użytkownika" - }, "plusAddressedEmail": { "message": "Adres e-mail z plusem", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Użyj skonfigurowanej skrzynki catch-all w swojej domenie." }, + "useThisEmail": { + "message": "Użyj tego adresu e-mail" + }, "random": { "message": "Losowa", "description": "Generates domain-based username using random letters" @@ -6821,11 +6863,11 @@ "message": "Wygeneruj alias adresu e-mail z zewnętrznej usługi przekierowania." }, "forwarderDomainName": { - "message": "Email domain", + "message": "Domena e-mail", "description": "Labels the domain name email forwarder service option" }, "forwarderDomainNameHint": { - "message": "Choose a domain that is supported by the selected service", + "message": "Wybierz domenę, która jest obsługiwana przez wybraną usługę", "description": "Guidance provided for email forwarding services that support multiple email domains." }, "forwarderError": { @@ -6934,9 +6976,6 @@ "message": "Nazwa hosta", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "Token dostępu API" - }, "deviceVerification": { "message": "Weryfikacja urządzenia" }, @@ -6970,7 +7009,7 @@ "description": "the text, 'SCIM', is an acronym and should not be translated." }, "scimIntegrationDescription": { - "message": "Automatically provision users and groups with your preferred identity provider via SCIM provisioning. Find supported integrations", + "message": "Automatycznie dostarczaj użytkownikom i grupom preferowanego dostawcy tożsamości za pomocą usługi SCIM. Znajdź obsługiwane integracje", "description": "the text, 'SCIM', is an acronym and should not be translated." }, "scimEnabledCheckboxDesc": { @@ -7648,18 +7687,6 @@ "noCollection": { "message": "Brak kolekcji" }, - "canView": { - "message": "Może wyświetlać" - }, - "canViewExceptPass": { - "message": "Może wyświetlać z wyjątkiem haseł" - }, - "canEdit": { - "message": "Można edytować" - }, - "canEditExceptPass": { - "message": "Może edytować z wyjątkiem haseł" - }, "noCollectionsAdded": { "message": "Nie dodano kolekcji" }, @@ -7982,7 +8009,7 @@ "message": "Przesyłanie ręczne" }, "manualBillingTokenUploadDesc": { - "message": "If you do not want to opt into billing sync, manually upload your license here. This will not automatically unlock Families sponsorships." + "message": "Jeśli nie chcesz zrezygnować z synchronizacji rozliczeniowej, ręcznie prześlij swoją licencję tutaj. Nie odblokuje to automatycznie sponsorowania dla rodziny." }, "syncLicense": { "message": "Synchronizuj licencję" @@ -8251,16 +8278,16 @@ "message": "Logowanie rozpoczęte" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "Zapamiętaj to urządzenie, aby przyszłe logowania były bezproblemowe" }, "deviceApprovalRequired": { "message": "Wymagane zatwierdzenie urządzenia. Wybierz opcję zatwierdzenia poniżej:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "Wymagane zatwierdzenie urządzenia" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "Wybierz opcję zatwierdzenia poniżej" }, "rememberThisDevice": { "message": "Zapamiętaj to urządzenie" @@ -8284,31 +8311,31 @@ "message": "Zaufane urządzenia" }, "memberDecryptionOptionTdeDescPart1": { - "message": "Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The", + "message": "Członkowie nie będą potrzebowali hasła głównego podczas logowania się za pomocą SSO. Hasło główne jest zastąpione kluczem szyfrowania przechowywanym na urządzeniu, co sprawia, że urządzenie jest zaufane. Pierwsze urządzenie, do którego użytkownik tworzy swoje konto i logi, będą zaufane. Nowe urządzenia będą musiały zostać zatwierdzone przez istniejące zaufane urządzenie lub przez administratora.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescLink1": { - "message": "single organization", + "message": "pojedyncza organizacja", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescPart2": { - "message": "policy,", + "message": "polityka,", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescLink2": { - "message": "SSO required", + "message": "Wymagane SSO", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescPart3": { - "message": "policy, and", + "message": "polityka i ", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescLink3": { - "message": "account recovery administration", + "message": "Administracja odzyskiwaniem konta", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescPart4": { - "message": "policy will turn on when this option is used.", + "message": "polityka włączy się, gdy ta opcja zostanie wykorzystana.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "orgPermissionsUpdatedMustSetPassword": { @@ -8387,16 +8414,16 @@ "message": "Zatwierdź prośbę" }, "deviceApproved": { - "message": "Device approved" + "message": "Urządzenie zostało zatwierdzone" }, "deviceRemoved": { - "message": "Device removed" + "message": "Urządzenie zostało usunięte" }, "removeDevice": { - "message": "Remove device" + "message": "Usuń urządzenie" }, "removeDeviceConfirmation": { - "message": "Are you sure you want to remove this device?" + "message": "Czy na pewno chcesz usunąć to urządzenie?" }, "noDeviceRequests": { "message": "Brak urządzeń do zatwierdzenia" @@ -8453,7 +8480,7 @@ "message": "Poproszono o zatwierdzenie urządzenia." }, "tdeOffboardingPasswordSet": { - "message": "User set a master password during TDE offboarding." + "message": "Użytkownik ustawił hasło główne podczas wyłączania TDE." }, "startYour7DayFreeTrialOfBitwardenFor": { "message": "Rozpocznij 7-dniowy darmowy okres próbny Bitwarden dla $ORG$", @@ -8504,7 +8531,7 @@ "message": "Brak adresu e-mail użytkownika" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "Nie znaleziono aktywnego adresu e-mail. Trwa wylogowanie." }, "deviceTrusted": { "message": "Zaufano urządzeniu" @@ -8602,10 +8629,13 @@ "message": "Zarządzaj zachowaniami kolekcji w organizacji" }, "limitCollectionCreationDesc": { - "message": "Limit collection creation to owners and admins" + "message": "Ogranicz tworzenie kolekcji do właścicieli i administratorów" }, "limitCollectionDeletionDesc": { - "message": "Limit collection deletion to owners and admins" + "message": "Ogranicz usuwanie kolekcji do właścicieli i administratorów" + }, + "limitItemDeletionDesc": { + "message": "Ogranicz usuwanie elementów do członków z uprawnieniami do zarządzania" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Właściciele i administratorzy mogą zarządzać wszystkimi zbiorami i elementami" @@ -8653,12 +8683,9 @@ "message": "Adres URL serwera" }, "selfHostBaseUrl": { - "message": "Self-host server URL", + "message": "URL samodzielnie hostowanego serwera", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Domena aliasu" - }, "alreadyHaveAccount": { "message": "Masz już konto?" }, @@ -8720,10 +8747,10 @@ "readOnlyCollectionAccess": { "message": "Nie masz dostępu do zarządzania tą kolekcją." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Brak uprawnienia Zarządzaj Uprawnieniami" + "grantManageCollectionWarningTitle": { + "message": "Brak uprawnień do zarządzania kolekcją" }, - "grantAddAccessCollectionWarning": { + "grantManageCollectionWarning": { "message": "Przyznaj uprawnienie Zarządzaj Uprawnieniami w celu umożliwienia pełnego zarządzania kolekcją, w tym usuwania kolekcji." }, "grantCollectionAccess": { @@ -9180,47 +9207,47 @@ "message": "Użyj SDK Menedżera Sekretów Bitwarden w następujących językach programowania, aby zbudować własne aplikacje." }, "ssoDescStart": { - "message": "Configure", + "message": "Konfiguruj", "description": "This represents the beginning of a sentence, broken up to include links. The full sentence will be 'Configure single sign-on for Bitwarden using the implementation guide for your Identity Provider." }, "ssoDescEnd": { - "message": "for Bitwarden using the implementation guide for your Identity Provider.", + "message": "dla Bitwarden przy użyciu instrukcji implementacyjnych dla Twojego dostawcy tożsamości.", "description": "This represents the end of a sentence, broken up to include links. The full sentence will be 'Configure single sign-on for Bitwarden using the implementation guide for your Identity Provider." }, "userProvisioning": { - "message": "User provisioning" + "message": "Aprowizacja użytkowników" }, "scimIntegration": { "message": "SCIM" }, "scimIntegrationDescStart": { - "message": "Configure ", + "message": "Konfiguruj", "description": "This represents the beginning of a sentence, broken up to include links. The full sentence will be 'Configure SCIM (System for Cross-domain Identity Management) to automatically provision users and groups to Bitwarden using the implementation guide for your Identity Provider" }, "scimIntegrationDescEnd": { - "message": "(System for Cross-domain Identity Management) to automatically provision users and groups to Bitwarden using the implementation guide for your Identity Provider.", + "message": "(System do zarządzania tożsamością międzydomeną) w celu automatycznej aprowizacji użytkowników i grup do Bitwarden przy użyciu instrukcji implementacji dla Twojego dostawcy tożsamości.", "description": "This represents the end of a sentence, broken up to include links. The full sentence will be 'Configure SCIM (System for Cross-domain Identity Management) to automatically provision users and groups to Bitwarden using the implementation guide for your Identity Provider" }, "bwdc": { "message": "Bitwarden Directory Connector" }, "bwdcDesc": { - "message": "Configure Bitwarden Directory Connector to automatically provision users and groups using the implementation guide for your Identity Provider." + "message": "Skonfiguruj Bitwarden Directory Connector do automatycznej aprowizacji użytkowników i grup za pomocą przewodnika implementacyjnego dla dostawcy tożsamości." }, "eventManagement": { - "message": "Event management" + "message": "Zarządzanie zdarzeniami" }, "eventManagementDesc": { - "message": "Integrate Bitwarden event logs with your SIEM (system information and event management) system by using the implementation guide for your platform." + "message": "Zintegruj dzienniki zdarzeń Bitwarden ze swoim systemem SIEM (Security Information and Event Management), korzystając z poradnika implementacyjnego dla Twojej platformy." }, "deviceManagement": { - "message": "Device management" + "message": "Zarządzanie urządzeniem" }, "deviceManagementDesc": { - "message": "Configure device management for Bitwarden using the implementation guide for your platform." + "message": "Skonfiguruj zarządzanie urządzeniem Bitwarden za pomocą instrukcji implementacyjnych dla Twojej platformy." }, "integrationCardTooltip": { - "message": "Launch $INTEGRATION$ implementation guide.", + "message": "Uruchom przewodnik implementacyjny $INTEGRATION$.", "placeholders": { "integration": { "content": "$1", @@ -9229,7 +9256,7 @@ } }, "smIntegrationTooltip": { - "message": "Set up $INTEGRATION$.", + "message": "Skonfiguruj $INTEGRATION$.", "placeholders": { "integration": { "content": "$1", @@ -9238,7 +9265,7 @@ } }, "smSdkTooltip": { - "message": "View $SDK$ repository", + "message": "Zobacz repozytorium $SDK$", "placeholders": { "sdk": { "content": "$1", @@ -9247,7 +9274,7 @@ } }, "integrationCardAriaLabel": { - "message": "open $INTEGRATION$ implementation guide in a new tab.", + "message": "otwórz przewodnik implementacji $INTEGRATION$ w nowej karcie.", "placeholders": { "integration": { "content": "$1", @@ -9256,7 +9283,7 @@ } }, "smSdkAriaLabel": { - "message": "view $SDK$ repository in a new tab.", + "message": "wyświetl repozytorium $SDK$ w nowej karcie.", "placeholders": { "sdk": { "content": "$1", @@ -9265,7 +9292,7 @@ } }, "smIntegrationCardAriaLabel": { - "message": "set up $INTEGRATION$ implementation guide in a new tab.", + "message": "ustaw przewodnik implementacji $INTEGRATION$ w nowej karcie.", "placeholders": { "integration": { "content": "$1", @@ -9286,7 +9313,7 @@ "message": "miesięcznie za członka" }, "monthPerMemberBilledAnnually": { - "message": "month per member billed annually" + "message": "miesięcznie na członka, rozliczanie rocznie" }, "seats": { "message": "Miejsca" @@ -9325,13 +9352,13 @@ "message": "Kontynuuj konfigurację darmowego okresu próbnego Menedżera Sekretnych Bitwarden" }, "enterTeamsOrgInfo": { - "message": "Enter your Teams organization information" + "message": "Wprowadź informacje o organizacji Teams" }, "enterFamiliesOrgInfo": { "message": "Wprowadź informacje o swojej organizacji rodzinnej" }, "enterEnterpriseOrgInfo": { - "message": "Enter your Enterprise organization information" + "message": "Wprowadź informacje o organizacji Enterprise" }, "viewItemsIn": { "message": "Zobacz elementy w $NAME$", @@ -9386,10 +9413,10 @@ "message": "Dostawca usług zarządzanych" }, "managedServiceProvider": { - "message": "Managed service provider" + "message": "Zarządzany dostawca usług" }, "multiOrganizationEnterprise": { - "message": "Multi-organization enterprise" + "message": "Przedsiębiorstwo wielu organizacji" }, "orgSeats": { "message": "Miejsca w organizacji" @@ -9437,16 +9464,16 @@ "message": "Zaktualizowane informacje podatkowe" }, "billingInvalidTaxIdError": { - "message": "Invalid tax ID, if you believe this is an error please contact support." + "message": "Nieprawidłowy numer identyfikacji podatkowej, jeśli uważasz, że jest to błąd, skontaktuj się z pomocą techniczną." }, "billingTaxIdTypeInferenceError": { - "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + "message": "Nie mogliśmy zweryfikować Twojego identyfikatora podatkowego, jeśli uważasz, że jest to błąd, skontaktuj się z pomocą techniczną." }, "billingPreviewInvalidTaxIdError": { - "message": "Invalid tax ID, if you believe this is an error please contact support." + "message": "Nieprawidłowy numer identyfikacji podatkowej, jeśli uważasz, że jest to błąd, skontaktuj się z pomocą techniczną." }, "billingPreviewInvoiceError": { - "message": "An error occurred while previewing the invoice. Please try again later." + "message": "Wystąpił błąd podczas podglądu faktury. Spróbuj ponownie później." }, "unverified": { "message": "Niezweryfikowane" @@ -9713,13 +9740,13 @@ "message": "Dowiedz się więcej o API Bitwarden" }, "fileSends": { - "message": "File Sends" + "message": "Wysyłki plików" }, "textSends": { - "message": "Text Sends" + "message": "Wysyłki tekstów" }, "includesXMembers": { - "message": "for $COUNT$ member", + "message": "dla $COUNT$ członków", "placeholders": { "count": { "content": "$1", @@ -9806,37 +9833,37 @@ "message": "GB dodatkowej przestrzeni" }, "sshKeyAlgorithm": { - "message": "Key algorithm" + "message": "Algorytm klucza" }, "sshPrivateKey": { - "message": "Private key" + "message": "Klucz prywatny" }, "sshPublicKey": { - "message": "Public key" + "message": "Klucz publiczny" }, "sshFingerprint": { - "message": "Fingerprint" + "message": "Odcisk palca" }, "sshKeyFingerprint": { - "message": "Fingerprint" + "message": "Odcisk palca" }, "sshKeyPrivateKey": { - "message": "Private key" + "message": "Klucz prywatny" }, "sshKeyPublicKey": { - "message": "Public key" + "message": "Klucz publiczny" }, "sshKeyAlgorithmED25519": { "message": "ED25519" }, "sshKeyAlgorithmRSA2048": { - "message": "RSA 2048-Bit" + "message": "RSA 2048-bitowy" }, "sshKeyAlgorithmRSA3072": { - "message": "RSA 3072-Bit" + "message": "RSA 3072-bitowy" }, "sshKeyAlgorithmRSA4096": { - "message": "RSA 4096-Bit" + "message": "RSA 4096-bitowy" }, "premiumAccounts": { "message": "6 kont premium" @@ -9854,7 +9881,7 @@ "message": "Monitorowanie zdarzeń" }, "directoryIntegration": { - "message": "Directory integration" + "message": "Integracja katalogu" }, "passwordLessSso": { "message": "SSO bez hasła" @@ -9906,22 +9933,22 @@ "message": "Edytuj dostęp" }, "textHelpText": { - "message": "Use text fields for data like security questions" + "message": "Użyj pól tekstowych dla danych takich jak pytania bezpieczeństwa" }, "hiddenHelpText": { - "message": "Use hidden fields for sensitive data like a password" + "message": "Użyj ukrytych pól dla danych poufnych, takich jak hasło" }, "checkBoxHelpText": { - "message": "Use checkboxes if you'd like to autofill a form's checkbox, like a remember email" + "message": "Użyj pól wyboru, jeśli chcesz automatycznie wypełnić pole wyboru formularza, np. jak zapamiętywanie e-mail" }, "linkedHelpText": { - "message": "Use a linked field when you are experiencing autofill issues for a specific website." + "message": "Użyj powiązanego pola, gdy masz problemy z autouzupełnianiem na konkretnej stronie internetowej." }, "linkedLabelHelpText": { - "message": "Enter the the field's html id, name, aria-label, or placeholder." + "message": "Wprowadź atrybut z: html id, name, aria-label lub placeholder." }, "uppercaseDescription": { - "message": "Include uppercase characters", + "message": "Uwzględnij wielkie litery", "description": "Tooltip for the password generator uppercase character checkbox" }, "uppercaseLabel": { @@ -9962,23 +9989,23 @@ "message": "Czy na pewno chcesz trwale usunąć ten załącznik?" }, "manageSubscriptionFromThe": { - "message": "Manage subscription from the", + "message": "Zarządzaj subskrypcją z", "description": "This represents the beginning of a sentence. The full sentence will be 'Manage subscription from the Provider Portal', but 'Provider Portal' will be a link and thus cannot be included in the translation file." }, "toHostBitwardenOnYourOwnServer": { - "message": "To host Bitwarden on your own server, you will need to upload your license file. To support Free Families plans and advanced billing capabilities for your self-hosted organization, you will need to set up automatic sync in your self-hosted organization." + "message": "Aby hostować Bitwarden na własnym serwerze, musisz przesłać plik licencyjny. Aby wspierać darmowe plany rodzinne i zaawansowane możliwości rozliczeniowe dla Twojej własnej organizacji, musisz skonfigurować automatyczną synchronizację w swojej własnej organizacji." }, "selfHostingTitleProper": { - "message": "Self-Hosting" + "message": "Samodzielne hostowanie" }, "claim-domain-single-org-warning": { - "message": "Claiming a domain will turn on the single organization policy." + "message": "Rejestracja domeny włączy politykę jednej organizacji." }, "single-org-revoked-user-warning": { - "message": "Non-compliant members will be revoked. Administrators can restore members once they leave all other organizations." + "message": "Niezgodni członkowie zostaną odwołani. Administratorzy mogą przywrócić członków po opuszczeniu wszystkich innych organizacji." }, "deleteOrganizationUser": { - "message": "Delete $NAME$", + "message": "Usuń $NAME$", "placeholders": { "name": { "content": "$1", @@ -9988,7 +10015,7 @@ } }, "deleteOrganizationUserWarningDesc": { - "message": "This will permanently delete all items owned by $NAME$. Collection items are not impacted.", + "message": "Spowoduje to trwałe usunięcie wszystkich elementów należących do $NAME$. Nie ma to wpływu na elementy w kolekcji.", "description": "Warning description for the delete organization user dialog", "placeholders": { "name": { @@ -9998,11 +10025,11 @@ } }, "deleteManyOrganizationUsersWarningDesc": { - "message": "This will permanently delete all items owned by the following members. Collection items are not impacted.", + "message": "Spowoduje to trwałe usunięcie wszystkich elementów należących do następujących członków. Nie ma to wpływu na elementy w kolekcji.", "description": "Warning description for the bulk delete organization users dialog" }, "organizationUserDeleted": { - "message": "Deleted $NAME$", + "message": "Usunięto $NAME$", "placeholders": { "name": { "content": "$1", @@ -10011,10 +10038,10 @@ } }, "organizationUserDeletedDesc": { - "message": "The user was removed from the organization and all associated user data has been deleted." + "message": "Użytkownik został usunięty z organizacji i wszystkie powiązane dane z tym użytkownikiem zostały usunięte." }, "deletedUserId": { - "message": "Deleted user $ID$ - an owner / admin deleted the user account", + "message": "Usunięto użytkownika $ID$ - właściciel / administrator usunął te konto użytkownika", "placeholders": { "id": { "content": "$1", @@ -10023,7 +10050,7 @@ } }, "userLeftOrganization": { - "message": "User $ID$ left organization", + "message": "Użytkownik $ID$ opuścił organizację", "placeholders": { "id": { "content": "$1", @@ -10032,7 +10059,7 @@ } }, "suspendedOrganizationTitle": { - "message": "The $ORGANIZATION$ is suspended", + "message": "$ORGANIZATION$ jest zawieszona", "placeholders": { "organization": { "content": "$1", @@ -10041,52 +10068,61 @@ } }, "suspendedUserOrgMessage": { - "message": "Contact your organization owner for assistance." + "message": "Skontaktuj się z właścicielem organizacji, aby uzyskać pomoc." }, "suspendedOwnerOrgMessage": { - "message": "To regain access to your organization, add a payment method." + "message": "Aby odzyskać dostęp do swojej organizacji, dodaj metodę płatności." }, "deleteMembers": { - "message": "Delete members" + "message": "Usuń członków" }, "noSelectedMembersApplicable": { - "message": "This action is not applicable to any of the selected members." + "message": "Ta akcja nie ma zastosowania do żadnego z wybranych członków." }, "deletedSuccessfully": { - "message": "Deleted successfully" + "message": "Usunięto pomyślnie" }, "freeFamiliesSponsorship": { - "message": "Remove Free Bitwarden Families sponsorship" + "message": "Usuń darmowe sponsorowanie rodzin Bitwarden" }, "freeFamiliesSponsorshipPolicyDesc": { - "message": "Do not allow members to redeem a Families plan through this organization." + "message": "Nie zezwalaj członkom na wykupienie planu rodzin za pośrednictwem tej organizacji." }, "verifyBankAccountWithStatementDescriptorWarning": { - "message": "Payment with a bank account is only available to customers in the United States. You will be required to verify your bank account. We will make a micro-deposit within the next 1-2 business days. Enter the statement descriptor code from this deposit on the organization's billing page to verify the bank account. Failure to verify the bank account will result in a missed payment and your subscription being suspended." + "message": "Płatność na rachunku bankowym jest dostępna tylko dla klientów w Stanach Zjednoczonych. Będziesz musiał zweryfikować swoje konto bankowe. Dokonamy mikrowpłaty w ciągu następnych 1-2 dni roboczych. Wprowadź kod deskryptora instrukcji z tej wpłaty na stronie rozliczeniowej organizacji, aby zweryfikować konto bankowe. Niezweryfikowanie konta bankowego spowoduje nieodebraną płatność, a subskrypcja zostanie zawieszona." }, "verifyBankAccountWithStatementDescriptorInstructions": { - "message": "We have made a micro-deposit to your bank account (this may take 1-2 business days). Enter the six-digit code starting with 'SM' found on the deposit description. Failure to verify the bank account will result in a missed payment and your subscription being suspended." + "message": "Dokonaliśmy mikrowpłaty na Twoje konto bankowe (może to zająć 1-2 dni robocze). Wprowadź sześciocyfrowy kod zaczynający się od 'SM' znaleziony w opisie depozytu. Niezweryfikowanie konta bankowego spowoduje nieodebraną płatność, a subskrypcja zostanie zawieszona." }, "descriptorCode": { - "message": "Descriptor code" + "message": "Kod deskryptora" + }, + "cannotRemoveViewOnlyCollections": { + "message": "Nie można usunąć kolekcji z uprawnieniami tylko do przeglądania: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } }, "importantNotice": { - "message": "Important notice" + "message": "Ważna informacja" }, "setupTwoStepLogin": { - "message": "Set up two-step login" + "message": "Skonfiguruj dwustopniowe logowanie" }, "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + "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": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + "message": "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": "Remind me later" + "message": "Przypomnij mi później" }, "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", + "message": "Czy masz pewny dostęp do swojego adresu e-mail, $EMAIL$?", "placeholders": { "email": { "content": "$1", @@ -10095,49 +10131,49 @@ } }, "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" + "message": "Nie, nie mam" }, "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" + "message": "Tak, mam pewny dostęp do mojego adresu e-mail" }, "turnOnTwoStepLogin": { - "message": "Turn on two-step login" + "message": "Włącz dwustopniowe logowanie" }, "changeAcctEmail": { - "message": "Change account email" + "message": "Zmień adres e-mail konta" }, "removeMembers": { - "message": "Remove members" + "message": "Usuń użytkowników" }, "devices": { - "message": "Devices" + "message": "Urządzenia" }, "deviceListDescription": { - "message": "Your account was logged in to each of the devices below. If you do not recognize a device, remove it now." + "message": "Twoje konto zostało zalogowane na każdym z poniższych urządzeń. Jeśli nie rozpoznajesz urządzenia, usuń je teraz." }, "deviceListDescriptionTemp": { - "message": "Your account was logged in to each of the devices below." + "message": "Twoje konto zostało zalogowane na każdym z poniższych urządzeń." }, "claimedDomains": { - "message": "Claimed domains" + "message": "Zarejestrowane domeny" }, "claimDomain": { - "message": "Claim domain" + "message": "Zarejestruj domenę" }, "reclaimDomain": { - "message": "Reclaim domain" + "message": "Wyrejestruj domenę" }, "claimDomainNameInputHint": { - "message": "Example: mydomain.com. Subdomains require separate entries to be claimed." + "message": "Przykład: mydomain.com. Subdomeny wymagają osobnych wpisów celem weryfikacji." }, "automaticClaimedDomains": { - "message": "Automatic Claimed Domains" + "message": "Automatycznie zarejestrowane domeny" }, "automaticDomainClaimProcess": { - "message": "Bitwarden will attempt to claim the domain 3 times during the first 72 hours. If the domain can’t be claimed, check the DNS record in your host and manually claim. The domain will be removed from your organization in 7 days if it is not claimed." + "message": "Bitwarden spróbuje zweryfikować domenę 3 razy w ciągu pierwszych 72 godzin. Jeśli nie będzie można zweryfikować domeny, sprawdź rekord DNS na swoim serwerze i wprowadź go ręcznie. Domena zostanie usunięta z Twojej organizacji w ciągu 7 dni, jeśli nie zostanie zweryfikowana" }, "domainNotClaimed": { - "message": "$DOMAIN$ not claimed. Check your DNS records.", + "message": "$DOMAIN$ nie została zweryfikowana. Sprawdź swój rekord DNS.", "placeholders": { "DOMAIN": { "content": "$1", @@ -10146,19 +10182,19 @@ } }, "domainStatusClaimed": { - "message": "Claimed" + "message": "Zweryfikowano" }, "domainStatusUnderVerification": { - "message": "Under verification" + "message": "Podczas weryfikacji" }, "claimedDomainsDesc": { - "message": "Claim a domain to own all member accounts whose email address matches the domain. Members will be able to skip the SSO identifier when logging in. Administrators will also be able to delete member accounts." + "message": "Zweryfikuj domenę do posiadania wszystkich kont użytkowników, których adres e-mail pasuje do domeny. Członkowie będą mogli pominąć identyfikator SSO podczas logowania. Administratorzy będą również mogli usuwać konta członków." }, "invalidDomainNameClaimMessage": { - "message": "Input is not a valid format. Format: mydomain.com. Subdomains require separate entries to be claimed." + "message": "Wprowadzone dane są niepoprawne. Format: mydomain.com. Subdomeny wymagają osobnych wpisów celem weryfikacji." }, "domainClaimedEvent": { - "message": "$DOMAIN$ claimed", + "message": "Zweryfikowano $DOMAIN$", "placeholders": { "DOMAIN": { "content": "$1", @@ -10167,7 +10203,7 @@ } }, "domainNotClaimedEvent": { - "message": "$DOMAIN$ not claimed", + "message": "$DOMAIN$ nie została zweryfikowana", "placeholders": { "DOMAIN": { "content": "$1", @@ -10176,7 +10212,7 @@ } }, "updatedRevokeSponsorshipConfirmationForSentSponsorship": { - "message": "If you remove $EMAIL$, the sponsorship for this Family plan cannot be redeemed. Are you sure you want to continue?", + "message": "Jeśli usuniesz $EMAIL$, sponsorowanie tego planu rodziny nie może zostać zrealizowane. Czy na pewno chcesz kontynuować?", "placeholders": { "email": { "content": "$1", @@ -10185,7 +10221,7 @@ } }, "updatedRevokeSponsorshipConfirmationForAcceptedSponsorship": { - "message": "If you remove $EMAIL$, the sponsorship for this Family plan will end and the saved payment method will be charged $40 + applicable tax on $DATE$. You will not be able to redeem a new sponsorship until $DATE$. Are you sure you want to continue?", + "message": "Jeśli usuniesz $EMAIL$, sponsorowanie tego planu rodzinnego zakończy się, a zapisana metoda płatności zostanie naliczona 40 USD + obowiązujący podatek od $DATE$. Nie będziesz w stanie wykupić nowego sponsora do dnia $DATE$. Czy na pewno chcesz kontynuować?", "placeholders": { "email": { "content": "$1", @@ -10198,13 +10234,13 @@ } }, "domainClaimed": { - "message": "Domain claimed" + "message": "Domena zarejestrowana" }, "organizationNameMaxLength": { - "message": "Organization name cannot exceed 50 characters." + "message": "Nazwa organizacji nie może przekraczać 50 znaków." }, "resellerRenewalWarningMsg": { - "message": "Your subscription will renew soon. To ensure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "message": "Twoja subskrypcja zostanie wkrótce odnowiona. Aby zapewnić nieprzerwaną usługę, skontaktuj się z $RESELLER$ , aby potwierdzić odnowienie przed $RENEWAL_DATE$.", "placeholders": { "reseller": { "content": "$1", @@ -10217,7 +10253,7 @@ } }, "resellerOpenInvoiceWarningMgs": { - "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To ensure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "message": "Faktura za subskrypcję została wystawiona dnia $ISSUED_DATE$. Aby zapewnić nieprzerwaną usługę, skontaktuj się z $RESELLER$ , aby potwierdzić odnowienie przed dniem $DUE_DATE$.", "placeholders": { "reseller": { "content": "$1", @@ -10234,7 +10270,7 @@ } }, "resellerPastDueWarningMsg": { - "message": "The invoice for your subscription has not been paid. To ensure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "message": "Faktura za subskrypcję nie została zapłacona. Aby zapewnić nieprzerwaną usługę, skontaktuj się z $RESELLER$ , aby potwierdzić odnowienie przed $GRACE_PERIOD_END$.", "placeholders": { "reseller": { "content": "$1", @@ -10247,18 +10283,67 @@ } }, "restartOrganizationSubscription": { - "message": "Organization subscription restarted" + "message": "Subskrypcja organizacji zrestartowana" }, "restartSubscription": { - "message": "Restart your subscription" + "message": "Zrestartuj swoją subskrypcję" }, "suspendedManagedOrgMessage": { - "message": "Contact $PROVIDER$ for assistance.", + "message": "Skontaktuj się z $PROVIDER$ w celu uzyskania pomocy.", "placeholders": { "provider": { "content": "$1", "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administratorzy mają teraz możliwość usunięcia kont członków, które należą do zarejestrowanej domeny." + }, + "deleteManagedUserWarningDesc": { + "message": "Ta akcja usunie konto członka, w tym wszystkie elementy w ich sejfie. To zastępuje poprzednią akcję Usunięcia." + }, + "deleteManagedUserWarning": { + "message": "Usuń jest nową akcją!" + }, + "seatsRemaining": { + "message": "Pozostało $REMAINING$ miejsc z $TOTAL$ miejsc przypisanych do tej organizacji. Skontaktuj się z dostawcą, aby zarządzać subskrypcją.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Istniejąca organizacja" + }, + "selectOrganizationProviderPortal": { + "message": "Wybierz organizację, aby dodać do portalu dostawcy." + }, + "noOrganizations": { + "message": "Nie ma organizacji, którą można by wyświetlić" + }, + "yourProviderSubscriptionCredit": { + "message": "Subskrypcja twojego dostawcy otrzyma kredyt za pozostały czas w subskrypcji organizacji." + }, + "doYouWantToAddThisOrg": { + "message": "Czy chcesz dodać tę organizację do $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Dodano istniejącą organizację" + }, + "assignedExceedsAvailable": { + "message": "Przypisane miejsca przekraczają dostępne miejsca." } } diff --git a/apps/web/src/locales/pt_BR/messages.json b/apps/web/src/locales/pt_BR/messages.json index 42f3876df45..85efb0c1027 100644 --- a/apps/web/src/locales/pt_BR/messages.json +++ b/apps/web/src/locales/pt_BR/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Editar Pasta" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Domínio de base", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Nome do item" }, - "cannotRemoveViewOnlyCollections": { - "message": "Você não pode remover coleções com permissões de Somente leitura: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "ex.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Login iniciado" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Enviar" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "Uma notificação foi enviada para seu dispositivo." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "Uma notificação foi enviada para seu dispositivo." }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Certifique-se que sua conta esteja desbloqueado e que a frase de impressão digital corresponda à do outro dispositivo." - }, "versionNumber": { "message": "Versão $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Evitar caracteres ambíguos", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Gerar Nova Senha" - }, "length": { "message": "Comprimento" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Zona de perigo" }, - "dangerZoneDesc": { - "message": "Cuidado, essas ações não são reversíveis!" - }, - "dangerZoneDescSingular": { - "message": "Cuidado, esta ação não é reversível!" - }, "deauthorizeSessions": { "message": "Desautorizar sessões" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "O processo também desconectará você da sua sessão atual, exigindo que você inicie a sessão novamente. Você também será solicitado a efetuar login em duas etapas novamente, se estiver ativado. Sessões ativas em outros dispositivos podem continuar ativas por até uma hora." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "Todas as Sessões Desautorizadas" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Gerenciar" }, - "canManage": { - "message": "Pode gerenciar" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Desabilitar" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "Houve um problema ao ler a chave de segurança. Tente novamente." }, - "twoFactorWebAuthnWarning": { - "message": "Devido às limitações da plataforma, o WebAuthn não pode ser usado em todos os aplicativos do Bitwarden. Você deve habilitar outro provedor de login em duas etapas, para que você possa acessar a sua conta quando o WebAuthn não puder ser usado. Plataformas suportadas:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Cofre web e extensões de navegador em um desktop/laptop com um navegador habilitado para WebAuthn (Chrome, Opera, Vivaldi ou Firefox com o FIDO U2F ativado)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Seu código de recuperação de login em duas etapas do Bitwarden" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Defina os requisitos mínimos para configuração do gerador de senhas." }, - "passwordGeneratorPolicyInEffect": { - "message": "Uma ou mais políticas da organização estão afetando as suas configurações do gerador." - }, "masterPasswordPolicyInEffect": { "message": "Uma ou mais políticas da organização exigem que a sua senha mestra cumpra aos seguintes requisitos:" }, @@ -6666,15 +6717,6 @@ "message": "Gerador", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "O que você gostaria de gerar?" - }, - "passwordType": { - "message": "Tipo de Senha" - }, - "regenerateUsername": { - "message": "Recriar Usuário" - }, "generateUsername": { "message": "Gerar Usuário" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Tipo de Usuário" - }, "plusAddressedEmail": { "message": "E-mail alternativo (com um +)", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Use o catch-all configurado no seu domínio." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Aleatório", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Hostname", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "Token de acesso API" - }, "deviceVerification": { "message": "Verificação do dispositivo" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "Sem coleções" }, - "canView": { - "message": "Pode ver" - }, - "canViewExceptPass": { - "message": "Pode ver, exceto senhas" - }, - "canEdit": { - "message": "Pode editar" - }, - "canEditExceptPass": { - "message": "Pode editar, exceto senhas" - }, "noCollectionsAdded": { "message": "Nenhuma coleção adicionada" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limitar exclusão de coleção a proprietários e administradores" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Proprietários e administradores podem gerenciar todas as coleções e itens" }, @@ -8656,9 +8686,6 @@ "message": "URL do servidor auto-host", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias do domínio" - }, "alreadyHaveAccount": { "message": "Já tem uma conta?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "Você não tem acesso para gerenciar esta coleção." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Falta conceder o Poder de Gerenciar Permissões" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Conceda o poder de gerenciar permissões para habilitar o gerenciamento completo da coleção, incluindo a exclusão da coleção." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Conceder acesso de grupos ou membros a esta coleção." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Código do descritor" }, + "cannotRemoveViewOnlyCollections": { + "message": "Você não pode remover coleções com permissões de Somente leitura: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/pt_PT/messages.json b/apps/web/src/locales/pt_PT/messages.json index 9f37d8c158e..a9d5e461086 100644 --- a/apps/web/src/locales/pt_PT/messages.json +++ b/apps/web/src/locales/pt_PT/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Editar pasta" }, + "newFolder": { + "message": "Nova pasta" + }, + "folderName": { + "message": "Nome da pasta" + }, + "folderHintText": { + "message": "Crie uma subpasta adicionando o nome da pasta principal seguido de um \"/\". Exemplo: Redes Sociais/Fóruns" + }, + "deleteFolderPermanently": { + "message": "Tem a certeza de que pretende eliminar permanentemente esta pasta?" + }, "baseDomain": { "message": "Domínio de base", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Nome do item" }, - "cannotRemoveViewOnlyCollections": { - "message": "Não é possível remover coleções com permissões de Apenas visualização: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "ex.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "A preparar o início de sessão" }, + "logInRequestSent": { + "message": "Pedido enviado" + }, "submit": { "message": "Submeter" }, @@ -1219,7 +1225,7 @@ "message": "Dica da palavra-passe mestra" }, "masterPassHintText": { - "message": "Se se esquecer da sua palavra-passe, a dica da palavra-passe pode ser enviada para o seu e-mail. Máximo de $CURRENT$/$MAXIMUM$ caracteres.", + "message": "Se se esquecer da sua palavra-passe, a dica da palavra-passe pode ser enviada para o seu e-mail. Máximo de $CURRENT$/$MAXIMUM$ carateres.", "placeholders": { "current": { "content": "$1", @@ -1268,7 +1274,7 @@ "message": "É necessário reescrever a palavra-passe mestra." }, "masterPasswordMinlength": { - "message": "A palavra-passe mestra deve ter pelo menos $VALUE$ caracteres.", + "message": "A palavra-passe mestra deve ter pelo menos $VALUE$ carateres.", "description": "The Master Password must be at least a specific number of characters long.", "placeholders": { "value": { @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "Foi enviada uma notificação para o seu dispositivo." }, + "notificationSentDevicePart1": { + "message": "Desbloqueie o Bitwarden no seu dispositivo ou no " + }, + "areYouTryingToAccessYourAccount": { + "message": "Está a tentar aceder à sua conta?" + }, + "accessAttemptBy": { + "message": "Tentativa de acesso por $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirmar acesso" + }, + "denyAccess": { + "message": "Recusar acesso" + }, + "notificationSentDeviceAnchor": { + "message": "aplicação web" + }, + "notificationSentDevicePart2": { + "message": "Certifique-se de que a frase da impressão digital corresponde à frase abaixo indicada antes de a aprovar." + }, + "notificationSentDeviceComplete": { + "message": "Desbloqueie o Bitwarden no seu dispositivo. Certifique-se de que a frase da impressão digital corresponde à frase abaixo antes de a aprovar." + }, "aNotificationWasSentToYourDevice": { "message": "Foi enviada uma notificação para o seu dispositivo" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Certifique-se de que a sua conta está desbloqueada e que a frase de impressão digital corresponde à do outro dispositivo" - }, "versionNumber": { "message": "Versão $VERSION_NUMBER$", "placeholders": { @@ -1653,20 +1686,17 @@ "message": "Mínimo de números" }, "minSpecial": { - "message": "Mínimo de caracteres especiais", + "message": "Mínimo de carateres especiais", "description": "Minimum special characters" }, "ambiguous": { - "message": "Evitar caracteres ambíguos", + "message": "Evitar carateres ambíguos", "description": "deprecated. Use avoidAmbiguous instead." }, "avoidAmbiguous": { - "message": "Evitar caracteres ambíguos", + "message": "Evitar carateres ambíguos", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Regenerar palavra-passe" - }, "length": { "message": "Comprimento" }, @@ -1686,7 +1716,7 @@ "description": "deprecated. Use numbersLabel instead." }, "specialCharacters": { - "message": "Caracteres especiais (!@#$%^&*)" + "message": "Carateres especiais (!@#$%^&*)" }, "numWords": { "message": "Número de palavras" @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Zona de risco" }, - "dangerZoneDesc": { - "message": "Cuidado, estas ações são irreversíveis!" - }, - "dangerZoneDescSingular": { - "message": "Cuidado, esta ação não é reversível!" - }, "deauthorizeSessions": { "message": "Desautorizar sessões" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Ao prosseguir, também terminará a sua sessão atual e terá de iniciar sessão novamente. Ser-lhe-á também pedido que volte efetuar a verificação de dois passos, se estiver configurada. As sessões ativas noutros dispositivos podem continuar ativas até uma hora." }, + "newDeviceLoginProtection": { + "message": "Início de sessão de um novo dispositivo" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Desativar a proteção de início de sessão de novos dispositivos" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Ativar a proteção de início de sessão de novos dispositivos" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceda da seguinte forma para desativar os e-mails de verificação que o Bitwarden envia quando inicia sessão a partir de um novo dispositivo." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceda da seguinte forma para que o Bitwarden lhe envie e-mails de verificação quando iniciar sessão a partir de um novo dispositivo." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "Com a proteção de início de sessão de novos dispositivos desativada, qualquer pessoa com a sua palavra-passe mestra pode aceder à sua conta a partir de qualquer dispositivo. Para proteger a sua conta sem e-mails de verificação, configure a verificação de dois passos." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "Alterações na proteção do início de sessão do novo dispositivo guardadas" + }, "sessionsDeauthorized": { "message": "Todas as sessões desautorizadas" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Gerir" }, - "canManage": { - "message": "Pode gerir" + "manageCollection": { + "message": "Gerir coleção" + }, + "viewItems": { + "message": "Ver itens" + }, + "viewItemsHidePass": { + "message": "Ver itens, palavras-passe ocultas" + }, + "editItems": { + "message": "Editar itens" + }, + "editItemsHidePass": { + "message": "Editar itens, palavras-passe ocultas" }, "disable": { "message": "Desativar" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "Ocorreu um problema ao ler a chave de segurança. Tente novamente." }, - "twoFactorWebAuthnWarning": { - "message": "Devido a limitações da plataforma, o WebAuthn não pode ser utilizado em todas as aplicações Bitwarden. Deve configurar outro fornecedor de verificação de dois passos para que possa aceder à sua conta quando o WebAuthn não puder ser utilizado. Plataformas suportadas:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Cofre web e extensões do navegador num computador de secretária/portátil com um navegador compatível com WebAuthn (Chrome, Opera, Vivaldi ou Firefox com FIDO U2F ativado)." + "twoFactorWebAuthnWarning1": { + "message": "Devido a limitações da plataforma, o WebAuthn não pode ser utilizado em todas as aplicações Bitwarden. Deve configurar outro fornecedor de verificação de dois passos para poder aceder à sua conta quando o WebAuthn não puder ser utilizado." }, "twoFactorRecoveryYourCode": { "message": "O seu código Bitwarden de recuperação da verificação de dois passos" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Definir requisitos para o gerador de palavras-passe." }, - "passwordGeneratorPolicyInEffect": { - "message": "Uma ou mais políticas da organização estão a afetar as suas definições do gerador." - }, "masterPasswordPolicyInEffect": { "message": "Uma ou mais políticas da organização exigem que a sua palavra-passe mestra cumpra os seguintes requisitos:" }, @@ -4720,16 +4771,16 @@ } }, "policyInEffectUppercase": { - "message": "Contém um ou mais caracteres em maiúsculas" + "message": "Contém um ou mais carateres em maiúsculas" }, "policyInEffectLowercase": { - "message": "Contém um ou mais caracteres em minúsculas" + "message": "Contém um ou mais carateres em minúsculas" }, "policyInEffectNumbers": { "message": "Contém um ou mais números" }, "policyInEffectSpecial": { - "message": "Contém um ou mais dos seguintes caracteres especiais $CHARS$", + "message": "Contém um ou mais dos seguintes carateres especiais $CHARS$", "placeholders": { "chars": { "content": "$1", @@ -6562,7 +6613,7 @@ "message": "obrigatório" }, "charactersCurrentAndMaximum": { - "message": "$CURRENT$/$MAX$ máximo de caracteres", + "message": "$CURRENT$/$MAX$ máximo de carateres", "placeholders": { "current": { "content": "$1", @@ -6575,7 +6626,7 @@ } }, "characterMaximum": { - "message": "Máximo de $MAX$ caracteres", + "message": "Máximo de $MAX$ carateres", "placeholders": { "max": { "content": "$1", @@ -6666,15 +6717,6 @@ "message": "Gerador", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "O que é que gostaria de gerar?" - }, - "passwordType": { - "message": "Tipo de palavra-passe" - }, - "regenerateUsername": { - "message": "Regenerar nome de utilizador" - }, "generateUsername": { "message": "Gerar nome de utilizador" }, @@ -6696,7 +6738,7 @@ } }, "passwordLengthRecommendationHint": { - "message": " Utilize $RECOMMENDED$ caracteres ou mais para gerar uma palavra-passe forte.", + "message": " Utilize $RECOMMENDED$ carateres ou mais para gerar uma palavra-passe forte.", "description": "Appended to `spinboxBoundariesHint` to recommend a length to the user. This must include any language-specific 'sentence' separator characters (e.g. a space in english).", "placeholders": { "recommended": { @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Tipo de nome de utilizador" - }, "plusAddressedEmail": { "message": "E-mail com subendereço", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Utilize a caixa de entrada de captura geral configurada para o seu domínio." }, + "useThisEmail": { + "message": "Utilizar este e-mail" + }, "random": { "message": "Aleatório", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Nome de domínio", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "Token de acesso à API" - }, "deviceVerification": { "message": "Verificação do dispositivo" }, @@ -7026,7 +7065,7 @@ "message": "O campo não é um endereço de e-mail." }, "inputMinLength": { - "message": "O campo deve ter pelo menos $COUNT$ caracteres.", + "message": "O campo deve ter pelo menos $COUNT$ carateres.", "placeholders": { "count": { "content": "$1", @@ -7035,7 +7074,7 @@ } }, "inputMaxLength": { - "message": "O campo não pode exceder os $COUNT$ caracteres de comprimento.", + "message": "O campo não pode exceder os $COUNT$ carateres de comprimento.", "placeholders": { "count": { "content": "$1", @@ -7044,7 +7083,7 @@ } }, "inputForbiddenCharacters": { - "message": "Não são permitidos os seguintes caracteres: $CHARACTERS$", + "message": "Não são permitidos os seguintes carateres: $CHARACTERS$", "placeholders": { "characters": { "content": "$1", @@ -7053,7 +7092,7 @@ } }, "inputMinValue": { - "message": "O valor do campo tem de ser, pelo menos, $MIN$ caracteres.", + "message": "O valor do campo tem de ser, pelo menos, $MIN$ carateres.", "placeholders": { "min": { "content": "$1", @@ -7062,7 +7101,7 @@ } }, "inputMaxValue": { - "message": "O valor do campo não pode exceder os $MAX$ caracteres.", + "message": "O valor do campo não pode exceder os $MAX$ carateres.", "placeholders": { "max": { "content": "$1", @@ -7194,11 +7233,11 @@ "message": "Limpar tudo" }, "toggleCharacterCount": { - "message": "Mostrar/ocultar contagem de caracteres", + "message": "Mostrar/ocultar contagem de carateres", "description": "'Character count' describes a feature that displays a number next to each character of the password." }, "passwordCharacterCount": { - "message": "Contagem de caracteres da palavra-passe", + "message": "Contagem de carateres da palavra-passe", "description": "'Character count' describes a feature that displays a number next to each character of the password." }, "hide": { @@ -7648,18 +7687,6 @@ "noCollection": { "message": "Sem coleções" }, - "canView": { - "message": "Pode ver" - }, - "canViewExceptPass": { - "message": "Pode ver, excepto palavras-passe" - }, - "canEdit": { - "message": "Pode editar" - }, - "canEditExceptPass": { - "message": "Pode editar, excepto palavras-passe" - }, "noCollectionsAdded": { "message": "Não foram adicionadas coleções" }, @@ -8202,7 +8229,7 @@ "message": "Palavra-passe fraca identificada e encontrada numa violação de dados. Utilize uma palavra-passe forte e única para proteger a sua conta. Tem a certeza de que pretende utilizar esta palavra-passe?" }, "characterMinimum": { - "message": "$LENGTH$ caracteres no mínimo", + "message": "$LENGTH$ carateres no mínimo", "placeholders": { "length": { "content": "$1", @@ -8211,7 +8238,7 @@ } }, "masterPasswordMinimumlength": { - "message": "A palavra-passe mestra deve ter pelo menos $LENGTH$ caracteres.", + "message": "A palavra-passe mestra deve ter pelo menos $LENGTH$ carateres.", "placeholders": { "length": { "content": "$1", @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limitar a eliminação de coleções aos proprietários e administradores" }, + "limitItemDeletionDesc": { + "message": "Limitar a eliminação de itens a membros com a permissão Pode gerir" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Os proprietários e administradores podem gerir todas as coleções e itens" }, @@ -8656,9 +8686,6 @@ "message": "URL do servidor auto-hospedado", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias de domínio" - }, "alreadyHaveAccount": { "message": "Já tem uma conta?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "Não tem acesso para gerir esta coleção." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Faltam permissões Pode gerir" + "grantManageCollectionWarningTitle": { + "message": "Permissões de gestão de coleções em falta" }, - "grantAddAccessCollectionWarning": { - "message": "Conceda permissões Pode gerir para permitir a gestão completa da coleção, incluindo a eliminação da coleção." + "grantManageCollectionWarning": { + "message": "Conceda permissões Gerir coleção para permitir a gestão completa da coleção, incluindo a eliminação da mesma." }, "grantCollectionAccess": { "message": "Conceder a grupos ou membros acesso a esta coleção." @@ -9897,10 +9924,10 @@ "description": "The text, 'API', is an acronym and should not be translated." }, "showCharacterCount": { - "message": "Mostrar contagem de caracteres" + "message": "Mostrar contagem de carateres" }, "hideCharacterCount": { - "message": "Ocultar contagem de caracteres" + "message": "Ocultar contagem de carateres" }, "editAccess": { "message": "Editar acesso" @@ -9921,7 +9948,7 @@ "message": "Introduza o ID do HTML, o nome, a aria-label ou o placeholder do campo." }, "uppercaseDescription": { - "message": "Incluir caracteres em maiúsculas", + "message": "Incluir carateres em maiúsculas", "description": "Tooltip for the password generator uppercase character checkbox" }, "uppercaseLabel": { @@ -9929,7 +9956,7 @@ "description": "Label for the password generator uppercase character checkbox" }, "lowercaseDescription": { - "message": "Incluir caracteres em minúsculas", + "message": "Incluir carateres em minúsculas", "description": "Full description for the password generator lowercase character checkbox" }, "lowercaseLabel": { @@ -9945,7 +9972,7 @@ "description": "Label for the password generator numbers checkbox" }, "specialCharactersDescription": { - "message": "Incluir caracteres especiais", + "message": "Incluir carateres especiais", "description": "Full description for the password generator special characters checkbox" }, "specialCharactersLabel": { @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Código descritor" }, + "cannotRemoveViewOnlyCollections": { + "message": "Não é possível remover coleções com permissões de Apenas visualização: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Aviso importante" }, @@ -10201,7 +10237,7 @@ "message": "Domínio reivindicado" }, "organizationNameMaxLength": { - "message": "O nome da organização não pode exceder 50 caracteres." + "message": "O nome da organização não pode exceder 50 carateres." }, "resellerRenewalWarningMsg": { "message": "A sua subscrição será renovada em breve. Para garantir um serviço ininterrupto, contacte a $RESELLER$ para confirmar a sua renovação antes de $RENEWAL_DATE$.", @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Os administradores têm agora a capacidade de eliminar contas de membros que pertençam a um domínio reivindicado." + }, + "deleteManagedUserWarningDesc": { + "message": "Esta ação elimina a conta do membro, incluindo todos os itens no seu cofre. Esta ação substitui a anterior Remover." + }, + "deleteManagedUserWarning": { + "message": "Eliminar é uma nova ação!" + }, + "seatsRemaining": { + "message": "Tem $REMAINING$ lugares restantes dos $TOTAL$ lugares atribuídos a esta organização. Contacte o seu fornecedor para gerir a sua subscrição.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Organização existente" + }, + "selectOrganizationProviderPortal": { + "message": "Selecione uma organização para adicionar ao seu Portal do fornecedor." + }, + "noOrganizations": { + "message": "Não existem organizações para listar" + }, + "yourProviderSubscriptionCredit": { + "message": "A subscrição do fornecedor receberá um crédito por qualquer tempo restante na subscrição da organização." + }, + "doYouWantToAddThisOrg": { + "message": "Pretende adicionar esta organização a $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Organização existente adicionada" + }, + "assignedExceedsAvailable": { + "message": "Os lugares atribuídos excedem os lugares disponíveis." } } diff --git a/apps/web/src/locales/ro/messages.json b/apps/web/src/locales/ro/messages.json index 3c7061dbf31..4db5a16a566 100644 --- a/apps/web/src/locales/ro/messages.json +++ b/apps/web/src/locales/ro/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Editare dosar" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Domeniu de bază", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "ex.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Autentificare inițiată" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Trimitere" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "O notificare a fost trimisă pe dispozitivul dvs." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "Versiunea $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Regenerare parolă" - }, "length": { "message": "Lungime" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Zona de pericol" }, - "dangerZoneDesc": { - "message": "Atenție, aceste acțiuni nu sunt reversibile!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Revocare sesiuni" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Procedând astfel, veți fi deconectat din sesiunea curentă, fiind necesar să vă reconectați. De asemenea, vi se va solicita din nou autentificarea în două etape, dacă este configurată. Sesiunile active de pe alte dispozitive pot rămâne active timp de până la o oră." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "Toate sesiunile au fost dezautorizate" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Gestionare" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Dezactivare" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "A apărut o problemă la citirea cheii de securitate. Încercați din nou." }, - "twoFactorWebAuthnWarning": { - "message": "Din cauza limitărilor de platformă, WebAuthn nu poate fi utilizat pe toate aplicațiile Bitwarden. Ar trebui să configurați un alt furnizor de autentificare în două etape, astfel încât să vă puteți accesa contul atunci când WebAuthn nu se poate utiliza. Platformele acceptate:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Seif web și extensii de browser pe un desktop/laptop cu un browser compatibil cu WebAuthn (Chrome, Opera, Vivaldi sau Firefox cu FIDO U2F activat)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Codul dvs. Bitwarden de recuperare a autentificării în două etape" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Setați cerințele pentru generatorul de parole." }, - "passwordGeneratorPolicyInEffect": { - "message": "Una sau mai multe politici organizaționale vă afectează setările generatorului." - }, "masterPasswordPolicyInEffect": { "message": "Una sau mai multe politici organizaționale necesită ca parola principală să îndeplinească următoarele cerințe:" }, @@ -6666,15 +6717,6 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "Ce doriți să generați?" - }, - "passwordType": { - "message": "Tip de parolă" - }, - "regenerateUsername": { - "message": "Regenerare nume de utilizator" - }, "generateUsername": { "message": "Generare nume de utilizator" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Tip de nume de utilizator" - }, "plusAddressedEmail": { "message": "E-mail Plus adresat", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Utilizați inbox-ul catch-all configurat pentru domeniul dvs." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Aleatoriu", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Nume gazdă", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "Token de acces API" - }, "deviceVerification": { "message": "Verificarea dispozitivului" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "No collection" }, - "canView": { - "message": "Can view" - }, - "canViewExceptPass": { - "message": "Can view, except passwords" - }, - "canEdit": { - "message": "Can edit" - }, - "canEditExceptPass": { - "message": "Can edit, except passwords" - }, "noCollectionsAdded": { "message": "No collections added" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domain" - }, "alreadyHaveAccount": { "message": "Already have an account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/ru/messages.json b/apps/web/src/locales/ru/messages.json index e24312a7d09..0c8ee796b4a 100644 --- a/apps/web/src/locales/ru/messages.json +++ b/apps/web/src/locales/ru/messages.json @@ -156,16 +156,16 @@ "message": "Всего приложений" }, "unmarkAsCriticalApp": { - "message": "Unmark as critical app" + "message": "Снять пометку критического приложения" }, "criticalApplicationSuccessfullyUnmarked": { - "message": "Critical application successfully unmarked" + "message": "Критическое приложение успешно снято" }, "whatTypeOfItem": { "message": "Выберите тип элемента" }, "name": { - "message": "Название" + "message": "Имя" }, "uri": { "message": "URI" @@ -464,6 +464,18 @@ "editFolder": { "message": "Изменить папку" }, + "newFolder": { + "message": "Новая папка" + }, + "folderName": { + "message": "Название папки" + }, + "folderHintText": { + "message": "Создайте вложенную папку, добавив название родительской папки и символ \"/\". Пример: Сообщества/Форумы" + }, + "deleteFolderPermanently": { + "message": "Вы действительно хотите безвозвратно удалить эту папку?" + }, "baseDomain": { "message": "Основной домен", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Название элемента" }, - "cannotRemoveViewOnlyCollections": { - "message": "Вы не можете удалить коллекции с правами только на просмотр: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "напр.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Вход инициирован" }, + "logInRequestSent": { + "message": "Запрос отправлен" + }, "submit": { "message": "Подтвердить" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "На ваше устройство отправлено уведомление." }, + "notificationSentDevicePart1": { + "message": "Разблокируйте Bitwarden на своем устройстве или " + }, + "areYouTryingToAccessYourAccount": { + "message": "Вы пытаетесь получить доступ к своему аккаунту?" + }, + "accessAttemptBy": { + "message": "Попытка доступа $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Подтвердить доступ" + }, + "denyAccess": { + "message": "Отказать в доступе" + }, + "notificationSentDeviceAnchor": { + "message": "веб-приложении" + }, + "notificationSentDevicePart2": { + "message": "Перед одобрением убедитесь, что фраза отпечатка совпадает с приведенной ниже." + }, + "notificationSentDeviceComplete": { + "message": "Разблокируйте Bitwarden на своем устройстве. Перед одобрением убедитесь, что фраза отпечатка совпадает с приведенной ниже." + }, "aNotificationWasSentToYourDevice": { "message": "На ваше устройство было отправлено уведомление" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Убедитесь, что ваш аккаунт разблокирован и фраза отпечатка совпадает с фразой на другом устройстве" - }, "versionNumber": { "message": "Версия $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Избегать неоднозначных символов", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Создать новый пароль" - }, "length": { "message": "Длина" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Зона риска" }, - "dangerZoneDesc": { - "message": "Осторожно, эти действия необратимы!" - }, - "dangerZoneDescSingular": { - "message": "Будьте внимательны - это действие не обратимо!" - }, "deauthorizeSessions": { "message": "Деавторизовать сессии" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "В случае продолжения, ваша сессия будет завершена и вам будет предложено авторизоваться повторно. Вам также будет предложено выполнить двухэтапную аутентификацию, если она настроена. Сессии на других устройствах могут оставаться активными в течение одного часа." }, + "newDeviceLoginProtection": { + "message": "Авторизация с нового устройства" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Отключить защиту авторизации с нового устройства" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Включить защиту авторизации с нового устройства" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Продолжите, чтобы отключить письма от bitwarden отправляемые при авторизации с нового устройства." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Продолжите, чтобы включить письма от bitwarden отправляемые при авторизации с нового устройства." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "Если защита авторизации с нового устройства отключена, любой с вашим мастер-паролем может получить доступ к вашему аккаунту с любого устройства. Чтобы обезопасить аккаунт при отключении писем от bitwarden настройте двухэтапную аутентификацию." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "Изменения защиты авторизации сохранены" + }, "sessionsDeauthorized": { "message": "Все сессии деавторизованы" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Управление" }, - "canManage": { - "message": "Может управлять" + "manageCollection": { + "message": "Управление коллекцией" + }, + "viewItems": { + "message": "Просмотр элементов" + }, + "viewItemsHidePass": { + "message": "Просмотр элементов, скрытых паролей" + }, + "editItems": { + "message": "Изменить элементы" + }, + "editItemsHidePass": { + "message": "Изменить элементы, скрытые пароли" }, "disable": { "message": "Отключить" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "Не удалось прочитать ключ безопасности. Попробуйте снова." }, - "twoFactorWebAuthnWarning": { - "message": "Из-за ограничений платформы WebAuthn нельзя использовать во всех приложениях Bitwarden. Вы должны настроить другого провайдера двухэтапной аутентификации, чтобы иметь возможность получить доступ к своей учетной записи, когда WebAuthn не может быть использован. Поддерживаемые платформы:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Веб-хранилище и расширения браузера на компьютере/ноутбуке с браузером с поддержкой WebAuthn (Chrome, Opera, Vivaldi или Firefox с включенным FIDO U2F)." + "twoFactorWebAuthnWarning1": { + "message": "Из-за ограничений платформы WebAuthn нельзя использовать во всех приложениях Bitwarden. Вы должны настроить другого провайдера двухэтапной аутентификации, чтобы иметь возможность получить доступ к своей учетной записи, когда WebAuthn не может быть использован." }, "twoFactorRecoveryYourCode": { "message": "Ваш код восстановления двухэтапной аутентификации Bitwarden" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Установить требования к генератору паролей." }, - "passwordGeneratorPolicyInEffect": { - "message": "На настройки генератора влияют одна или несколько политик организации." - }, "masterPasswordPolicyInEffect": { "message": "Согласно одной или нескольким политикам организации необходимо, чтобы ваш мастер-пароль отвечал следующим требованиям:" }, @@ -6666,15 +6717,6 @@ "message": "Генератор", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "Что вы хотите сгенерировать?" - }, - "passwordType": { - "message": "Тип пароля" - }, - "regenerateUsername": { - "message": "Пересоздать имя пользователя" - }, "generateUsername": { "message": "Создать имя пользователя" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Тип имени пользователя" - }, "plusAddressedEmail": { "message": "Субадресованные email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Использовать общий email домена." }, + "useThisEmail": { + "message": "Использовать этот email" + }, "random": { "message": "Случайно", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Имя хоста", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "Токен доступа к API" - }, "deviceVerification": { "message": "Проверка устройства" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "Нет коллекций" }, - "canView": { - "message": "Может просматривать" - }, - "canViewExceptPass": { - "message": "Может просматривать, кроме паролей" - }, - "canEdit": { - "message": "Может редактировать" - }, - "canEditExceptPass": { - "message": "Может редактировать, кроме паролей" - }, "noCollectionsAdded": { "message": "Нет добавленных коллекций" }, @@ -8288,19 +8315,19 @@ "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescLink1": { - "message": "single organization", + "message": "одна организация", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescPart2": { - "message": "policy,", + "message": "политика,", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescLink2": { - "message": "SSO required", + "message": "Требуется SSO", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescPart3": { - "message": "policy, and", + "message": "политика, и", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescLink3": { @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Ограничить удаление коллекций владельцам и администраторам" }, + "limitItemDeletionDesc": { + "message": "Ограничить удаление элементов для пользователей с разрешением «Может управлять»" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Владельцы и администраторы могут управлять всеми коллекциями и элементами" }, @@ -8656,9 +8686,6 @@ "message": "URL собственного сервера", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Псевдоним домена" - }, "alreadyHaveAccount": { "message": "Уже зарегистрированы?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "У вас нет доступа к управлению этой коллекцией." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Недостаточно полномочий для управления" + "grantManageCollectionWarningTitle": { + "message": "Отсутствуют разрешения на управление коллекцией" }, - "grantAddAccessCollectionWarning": { - "message": "Предоставить возможность управлять разрешениями коллекций, включая их удаление." + "grantManageCollectionWarning": { + "message": "Представить разрешения на управление коллекцией, включая ее удаление." }, "grantCollectionAccess": { "message": "Предоставить группам или участникам доступ к этой коллекции." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Код дескриптора" }, + "cannotRemoveViewOnlyCollections": { + "message": "Вы не можете удалить коллекции с правами только на просмотр: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Важное уведомление" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Администраторы теперь могут удалять аккаунты пользователей, принадлежащие заявленному домену." + }, + "deleteManagedUserWarningDesc": { + "message": "Это действие удалит аккаунт пользователя, включая все элементы в его хранилище. Это действие заменяет предыдущее действие Удалить." + }, + "deleteManagedUserWarning": { + "message": "Удалить - это новое действие!" + }, + "seatsRemaining": { + "message": "У вас осталось $REMAINING$ мест из $TOTAL$, закрепленных за этой организацией. Обратитесь к своему провайдеру для управления подпиской.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Существующая организация" + }, + "selectOrganizationProviderPortal": { + "message": "Выберите организацию для добавления на ваш портал провайдеров." + }, + "noOrganizations": { + "message": "Нет организаций для отображения" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Вы хотите добавить эту организацию в $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Добавлена ​​существующая организация" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/si/messages.json b/apps/web/src/locales/si/messages.json index 4e434ea80f4..058528cb18d 100644 --- a/apps/web/src/locales/si/messages.json +++ b/apps/web/src/locales/si/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "බහාලුම සංස්කරණය" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Base domain", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "උදා.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Log in initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Submit" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "Version $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Regenerate password" - }, "length": { "message": "Length" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Danger zone" }, - "dangerZoneDesc": { - "message": "Careful, these actions are not reversible!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Deauthorize sessions" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Proceeding will also log you out of your current session, requiring you to log back in. You will also be prompted for two-step login again, if set up. Active sessions on other devices may continue to remain active for up to one hour." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "All sessions deauthorized" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Manage" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Turn off" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "There was a problem reading the security key. Try again." }, - "twoFactorWebAuthnWarning": { - "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used. Supported platforms:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Web vault and browser extensions on a desktop/laptop with a WebAuthn supported browser (Chrome, Opera, Vivaldi, or Firefox with FIDO U2F turned on)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Your Bitwarden two-step login recovery code" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Set requirements for password generator." }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organization policies are affecting your generator settings." - }, "masterPasswordPolicyInEffect": { "message": "One or more organization policies require your master password to meet the following requirements:" }, @@ -6666,15 +6717,6 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Use your domain's configured catch-all inbox." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Random", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Hostname", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API access token" - }, "deviceVerification": { "message": "Device verification" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "No collection" }, - "canView": { - "message": "Can view" - }, - "canViewExceptPass": { - "message": "Can view, except passwords" - }, - "canEdit": { - "message": "Can edit" - }, - "canEditExceptPass": { - "message": "Can edit, except passwords" - }, "noCollectionsAdded": { "message": "No collections added" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domain" - }, "alreadyHaveAccount": { "message": "Already have an account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/sk/messages.json b/apps/web/src/locales/sk/messages.json index 791d6a65e33..bee2d072f91 100644 --- a/apps/web/src/locales/sk/messages.json +++ b/apps/web/src/locales/sk/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Upraviť priečinok" }, + "newFolder": { + "message": "Nový priečinok" + }, + "folderName": { + "message": "Názov priečinka" + }, + "folderHintText": { + "message": "Vnorte priečinok pridaním názvu nadradeného priečinka a znaku \"/\". Príklad: Sociálne siete/Fóra" + }, + "deleteFolderPermanently": { + "message": "Naozaj chcete natrvalo odstrániť tento priečinok?" + }, "baseDomain": { "message": "Základná doména", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Názov položky" }, - "cannotRemoveViewOnlyCollections": { - "message": "Zbierky, ktoré môžete len zobraziť nemôžete odstrániť: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "napr.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Iniciované prihlásenie" }, + "logInRequestSent": { + "message": "Požiadavka bola odoslaná" + }, "submit": { "message": "Potvrdiť" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "Do vášho zariadenia bolo odoslané upozornenie." }, + "notificationSentDevicePart1": { + "message": "Odomknúť Bitwarden vo svojom zariadení alebo vo " + }, + "areYouTryingToAccessYourAccount": { + "message": "Snažíte sa získať prístup k svojmu účtu?" + }, + "accessAttemptBy": { + "message": "Pokus o prístup z $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Potvrďte prístup" + }, + "denyAccess": { + "message": "Zamietnuť prístup" + }, + "notificationSentDeviceAnchor": { + "message": "webovej aplikácii" + }, + "notificationSentDevicePart2": { + "message": "Pred schválením sa uistite, že sa odtlačok prístupovej frázy zhoduje s tou uvedenou nižšie." + }, + "notificationSentDeviceComplete": { + "message": "Odomknite Bitwarden na vašom zariadení. Pred schválením sa uistite, že sa odtlačok prístupovej frázy zhoduje s tým uvedeným nižšie." + }, "aNotificationWasSentToYourDevice": { "message": "Do vášho zariadenia bolo odoslané upozornenie" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Uistite sa, že je váš účet odomknutý a fráza odtlačku prsta sa zhoduje s frázou na druhom zariadení" - }, "versionNumber": { "message": "Verzia $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Vyhnúť sa zameniteľným znakom", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Vygenerovať nové heslo" - }, "length": { "message": "Dĺžka" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Riziková zóna" }, - "dangerZoneDesc": { - "message": "Opatrne, tieto zmeny nemožno vrátiť späť!" - }, - "dangerZoneDescSingular": { - "message": "Opatrne, túto zmenu nemožno vrátiť späť!" - }, "deauthorizeSessions": { "message": "Odhlásiť sedenia" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Ak budete pokračovať, budete tiež odhlásený z vášho súčasného sedenia a budete sa musieť opäť prihlásiť. Tiež budete opäť požiadaný o dvojstupňové prihlásenie ak ho máte zapnuté. Aktívne sedenia na iných zariadeniach môžu ostať aktívne až po dobu jednej hodiny." }, + "newDeviceLoginProtection": { + "message": "Prihlásenie z nového zariadenia" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Vypnúť ochranu pri prihlásení z nového zariadenia" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Zapnúť ochranu pri prihlásení z nového zariadenia" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Ak chcete vypnúť overovacie emaily, ktoré Bitwarden posiela keď sa prihlasujete z nového zariadenia, pokračujte nižšie." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Ak chcete aby Bitwarden posielal overovacie emaily keď sa prihlasujete z nového zariadenia, pokračujte nižšie." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "S vypnutou ochranou pri prihlásení z nového zariadenia môže ktokoľvek, kto pozná vaše hlavne heslo, pristupovať k vášmu účtu z ľubovoľného zariadenia. Ak chcete ochrániť váš účet bez overovacích emailov, nastavte si dvojstupňové overovanie pri prihlasovaní." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "Zmeny v nastavení ochrany prihlasovania z nového zariadenia boli uložené" + }, "sessionsDeauthorized": { "message": "Všetky sedenia odhlásené" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Spravovať" }, - "canManage": { - "message": "Môže spravovať" + "manageCollection": { + "message": "Spravovať zbierku" + }, + "viewItems": { + "message": "Zobraziť položky" + }, + "viewItemsHidePass": { + "message": "Zobraziť položky, skryté heslá" + }, + "editItems": { + "message": "Upraviť položky" + }, + "editItemsHidePass": { + "message": "Upraviť položky, skryté heslá" }, "disable": { "message": "Vypnúť" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "Problém pri čítaní bezpečnostného kľúča. Skúste to znova." }, - "twoFactorWebAuthnWarning": { - "message": "Vzhľadom na obmedzenia platform, WebAuthn nemôže byť použitý vo všetkých Bitwarden aplikáciách. Mali by ste povoliť inú formu dvojitého overenia, aby ste sa mohli prihlásiť k svojmu účtu ak nie je možné použiť WebAuthn. Podporované platformy:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Webový trezor a rozšírenia prehliadača na pracovnej stanici s prehliadačom podporujúcim WebAuthn (Chrome, Opera, Vivaldi, alebo Firefox so zapnutou podporou FIDO U2F)." + "twoFactorWebAuthnWarning1": { + "message": "Vzhľadom na obmedzenia platforiem, WebAuthn nemôže byť použitý vo všetkých Bitwarden aplikáciách. Mali by ste nastaviť inú formu dvojitého overenia, aby ste sa mohli prihlásiť k svojmu účtu ak nie je možné použiť WebAuthn." }, "twoFactorRecoveryYourCode": { "message": "Váš Bitwarden záchranný kód pre dvojstupňové overovanie" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Zvoľte minimálne požiadavky pre nastavenie generátora hesiel." }, - "passwordGeneratorPolicyInEffect": { - "message": "Jedno alebo viac nastavení organizácie ovplyvňujú vaše nastavenia generátora." - }, "masterPasswordPolicyInEffect": { "message": "Jedno alebo viac pravidiel organizácie požadujú aby vaše hlavné heslo spĺňalo nasledujúce požiadavky:" }, @@ -6666,15 +6717,6 @@ "message": "Generátor", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "Čo by ste chceli vygenerovať?" - }, - "passwordType": { - "message": "Typ hesla" - }, - "regenerateUsername": { - "message": "Vygenerovať nové používateľské meno" - }, "generateUsername": { "message": "Vygenerovať používateľské meno" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Typ používateľského mena" - }, "plusAddressedEmail": { "message": "E-mail s plusovým aliasom", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Použiť doručenú poštu typu catch-all nastavenú na doméne." }, + "useThisEmail": { + "message": "Použiť tento e-mail" + }, "random": { "message": "Náhodné", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Názov hostiteľa", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "Prístupový token API" - }, "deviceVerification": { "message": "Overenie zariadenia" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "Žiadna zbierka" }, - "canView": { - "message": "Môže zobraziť" - }, - "canViewExceptPass": { - "message": "Môže zobraziť okrem hesiel" - }, - "canEdit": { - "message": "Môže upraviť" - }, - "canEditExceptPass": { - "message": "Môže upravovať okrem hesiel" - }, "noCollectionsAdded": { "message": "Nebolí pridané žiadne zbierky" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Obmedziť vymazávanie zbierky len pre vlastníkov a administrátorov" }, + "limitItemDeletionDesc": { + "message": "Obmedziť vymazávanie položiek na členov s oprávnením \"Môže spravovať\"" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Vlastníci a správcovia môžu spravovať všetky zbierky a položky" }, @@ -8656,9 +8686,6 @@ "message": "Adresa URL vlastného hostingu", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias doména" - }, "alreadyHaveAccount": { "message": "Už máte účet?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "Nemáte prístup k spravovaniu tejto zbierky." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Chýbajúce oprávnenia pre správu zbierky" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Pre povolenie kompletnej správy zbierky vrátane jej vymazania, udeľte oprávnenia na správu zbierky." }, "grantCollectionAccess": { "message": "Povoľte skupinám, alebo jednotlivcom prístup k tejto zbierke." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Kód výpisu" }, + "cannotRemoveViewOnlyCollections": { + "message": "Zbierky, ktoré môžete len zobraziť nemôžete odstrániť: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Dôležité upozornenie" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Odteraz majú správcovia právomoc vymazať konta členov, ktorí prináležia do privlastnenej domény." + }, + "deleteManagedUserWarningDesc": { + "message": "Táto akcia vymaže člena vrátane všetkých ich položiek v trezore. Tato akcia nahrádza predchádzajúcu akciu Odstrániť." + }, + "deleteManagedUserWarning": { + "message": "\"Vymazať\" je nová akcia!" + }, + "seatsRemaining": { + "message": "Z celkovo $TOTAL$ sedení pridelených tejto organizácii vám zostava $REMAINING$ sedení. Pre správu predplatného kontaktujte vášho poskytovateľa.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existujúca organizácia" + }, + "selectOrganizationProviderPortal": { + "message": "Vyberte organizáciu ktorú chcete pridať do portálu poskytovateľa." + }, + "noOrganizations": { + "message": "Neexistujú žiadne organizácie na zobrazenie" + }, + "yourProviderSubscriptionCredit": { + "message": "Váš poskytovateľ predplatného obdrží kredit za zostávajúci čas predplatného vašej organizácie." + }, + "doYouWantToAddThisOrg": { + "message": "Chcete pridať tuto organizáciu k $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Existujúca organizácia pridaná" + }, + "assignedExceedsAvailable": { + "message": "Počet pridelených sedení presahuje počet dostupných sedení." } } diff --git a/apps/web/src/locales/sl/messages.json b/apps/web/src/locales/sl/messages.json index 1a7cb1dda29..c440f0cfcf1 100644 --- a/apps/web/src/locales/sl/messages.json +++ b/apps/web/src/locales/sl/messages.json @@ -1,18 +1,18 @@ { "allApplications": { - "message": "All applications" + "message": "Vse aplikacije" }, "criticalApplications": { - "message": "Critical applications" + "message": "Kritične aplikacije" }, "accessIntelligence": { - "message": "Access Intelligence" + "message": "Analiza dostopa" }, "riskInsights": { - "message": "Risk Insights" + "message": "Vpogled v tveganja" }, "passwordRisk": { - "message": "Password Risk" + "message": "Varnostno tveganje gesla" }, "reviewAtRiskPasswords": { "message": "Review at-risk passwords (weak, exposed, or reused) across applications. Select your most critical applications to prioritize security actions for your users to address at-risk passwords." @@ -464,6 +464,18 @@ "editFolder": { "message": "Uredi mapo" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Bazna domena", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "npr.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Prijava se je začela" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Potrdi" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "Na vašo napravo smo poslali obvestilo." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "Različica $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Ponovno generiraj geslo" - }, "length": { "message": "Dolžina" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Območje nevarnosti" }, - "dangerZoneDesc": { - "message": "Previdno, ta dejanja so nepovratna!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Prekini seje" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Proceeding will also log you out of your current session, requiring you to log back in. You will also be prompted for two-step login again, if set up. Active sessions on other devices may continue to remain active for up to one hour." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "Vse seje prekinjene" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Upravljaj" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Onemogočeno" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "There was a problem reading the security key. Try again." }, - "twoFactorWebAuthnWarning": { - "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used. Supported platforms:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Web vault and browser extensions on a desktop/laptop with a WebAuthn supported browser (Chrome, Opera, Vivaldi, or Firefox with FIDO U2F turned on)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Your Bitwarden two-step login recovery code" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Set requirements for password generator." }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organization policies are affecting your generator settings." - }, "masterPasswordPolicyInEffect": { "message": "One or more organization policies require your master password to meet the following requirements:" }, @@ -6666,15 +6717,6 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "Kaj želite generirati?" - }, - "passwordType": { - "message": "Vrsta gesla" - }, - "regenerateUsername": { - "message": "Ponovno generiraj uporabniško ime" - }, "generateUsername": { "message": "Generate username" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Vrsta uporabniškega imena" - }, "plusAddressedEmail": { "message": "E-naslov s plusom", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Uporabite naslov za vse (\"catch-all\"), ki ste ga nastavili za svojo domeno." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Random", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Hostname", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "Dostopni žeto (\"access token\") za API" - }, "deviceVerification": { "message": "Device verification" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "No collection" }, - "canView": { - "message": "Can view" - }, - "canViewExceptPass": { - "message": "Can view, except passwords" - }, - "canEdit": { - "message": "Can edit" - }, - "canEditExceptPass": { - "message": "Can edit, except passwords" - }, "noCollectionsAdded": { "message": "No collections added" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domain" - }, "alreadyHaveAccount": { "message": "Already have an account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/sr/messages.json b/apps/web/src/locales/sr/messages.json index fd3aeab1042..809fa21d852 100644 --- a/apps/web/src/locales/sr/messages.json +++ b/apps/web/src/locales/sr/messages.json @@ -15,7 +15,7 @@ "message": "Ризик од лозинке" }, "reviewAtRiskPasswords": { - "message": "Review at-risk passwords (weak, exposed, or reused) across applications. Select your most critical applications to prioritize security actions for your users to address at-risk passwords." + "message": "Прегледај ризичне лозинке (слабе, изложене или поново коришћене) у апликацијама. Изабери своје најкритичније апликације да би дао приоритет безбедносним радњама како би твоји корисници адресирали ризичне лозинке." }, "dataLastUpdated": { "message": "Подаци су последњи пут ажурирани: $DATE$", @@ -132,13 +132,13 @@ } }, "atRiskMembersDescription": { - "message": "These members are logging into applications with weak, exposed, or reused passwords." + "message": "Ови чланови се пријављују у апликације са слабим, откривеним или поново коришћеним лозинкама." }, "atRiskApplicationsDescription": { "message": "Ове апликације имају слабу, проваљену или често коришћену лозинку." }, "atRiskMembersDescriptionWithApp": { - "message": "These members are logging into $APPNAME$ with weak, exposed, or reused passwords.", + "message": "Ови чланови се пријављују у $APPNAME$ са слабим, откривеним или поново коришћеним лозинкама.", "placeholders": { "appname": { "content": "$1", @@ -464,6 +464,18 @@ "editFolder": { "message": "Уреди фасциклу" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Главни домен", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Име ставке" }, - "cannotRemoveViewOnlyCollections": { - "message": "Не можете уклонити колекције са дозволама само за приказ: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "нпр.", "description": "Short abbreviation for 'example'." @@ -816,7 +819,7 @@ "message": "Копирати телефон" }, "copyEmail": { - "message": "Копирати имејл" + "message": "Копирај Е-пошту" }, "copyCompany": { "message": "Копирати фирму" @@ -1168,7 +1171,7 @@ "message": "Потврдите идентитет" }, "weDontRecognizeThisDevice": { - "message": "We don't recognize this device. Enter the code sent to your email to verify your identity." + "message": "Не препознајемо овај уређај. Унесите код послат на адресу ваше електронске поште да би сте потврдили ваш идентитет." }, "continueLoggingIn": { "message": "Настави са пријављивањем" @@ -1177,16 +1180,19 @@ "message": "Шта је уређај?" }, "aDeviceIs": { - "message": "A device is a unique installation of the Bitwarden app where you have logged in. Reinstalling, clearing app data, or clearing your cookies could result in a device appearing multiple times." + "message": "Уређај је јединствена инсталација Bitwarden апликације на коју сте се пријавили. Поновно инсталирање, брисање података апликације или брисање колачића може довести до тога да се уређај појави више пута." }, "logInInitiated": { "message": "Пријава је покренута" }, + "logInRequestSent": { + "message": "Захтев је послат" + }, "submit": { "message": "Пошаљи" }, "emailAddressDesc": { - "message": "Користите ваш имејл за пријављивање." + "message": "Користи твоју Е-пошту за пријављивање." }, "yourName": { "message": "Ваше име" @@ -1219,7 +1225,7 @@ "message": "Савет Главне Лозинке" }, "masterPassHintText": { - "message": "Ако заборавите лозинку, наговештај за лозинку се може послати на ваш имејл. $CURRENT$/$MAXIMUM$ карактера максимум.", + "message": "Ако заборавиш лозинку, наговештај за лозинку се може послати на твоју Е-пошту. $CURRENT$/$MAXIMUM$ карактера максимум.", "placeholders": { "current": { "content": "$1", @@ -1235,7 +1241,7 @@ "message": "Подешавања" }, "accountEmail": { - "message": "Имејл налога" + "message": "Е-пошта налога" }, "requestHint": { "message": "Захтевај савет" @@ -1244,22 +1250,22 @@ "message": "Затражити савет лозинке" }, "enterYourAccountEmailAddressAndYourPasswordHintWillBeSentToYou": { - "message": "Унесите имејл свог налога и биће вам послат савет за лозинку" + "message": "Унеси адресу Е-поште свог налога и биће ти послат савет за лозинку" }, "passwordHint": { "message": "Помоћ за лозинку" }, "enterEmailToGetHint": { - "message": "Унесите Ваш имејл да би добили савет за Вашу Главну Лозинку." + "message": "Унеси твоју Е-пошту да би добио савет за твоју Главну Лозинку." }, "getMasterPasswordHint": { "message": "Добити савет за Главну Лозинку" }, "emailRequired": { - "message": "Имејл је неопходан." + "message": "Адреса Е-поште је неопходна." }, "invalidEmail": { - "message": "Неисправан имејл." + "message": "Нетачна адреса Е-поште." }, "masterPasswordRequired": { "message": "Главна Лозинка је неопходна." @@ -1302,7 +1308,7 @@ "message": "Изаберите датум истека који је у будућности." }, "emailAddress": { - "message": "Имејл" + "message": "Адреса Е-поште" }, "yourVaultIsLockedV2": { "message": "Ваш сеф је блокиран" @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "Обавештење је послато на ваш уређај." }, + "notificationSentDevicePart1": { + "message": "Откључај Bitwarden на твом уређају или на " + }, + "areYouTryingToAccessYourAccount": { + "message": "Да ли покушавате да приступите вашем налогу?" + }, + "accessAttemptBy": { + "message": "Покушај приступа са $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Потврди приступ" + }, + "denyAccess": { + "message": "Одбиј приступ" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Потврдите да се фраза отиска прста поклапа са овом испод пре одобравања." + }, + "notificationSentDeviceComplete": { + "message": "Октључај Bitwarden на твом уређају. Потврдите да се фраза отиска прста поклапа са овом испод пре одобравања." + }, "aNotificationWasSentToYourDevice": { "message": "Обавештење је послато на ваш уређај" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Уверите се да је ваш налог откључан и да се фраза отиска подудара на другом уређају" - }, "versionNumber": { "message": "Верзија $VERSION_NUMBER$", "placeholders": { @@ -1399,7 +1432,7 @@ } }, "verificationCodeEmailSent": { - "message": "Провера имејла послата на $EMAIL$.", + "message": "Е-пошта за верификацију је послата на $EMAIL$.", "placeholders": { "email": { "content": "$1", @@ -1411,7 +1444,7 @@ "message": "Запамти ме" }, "sendVerificationCodeEmailAgain": { - "message": "Поново послати верификациони код на имејл" + "message": "Поново послати верификациони код на Е-пошту" }, "useAnotherTwoStepMethod": { "message": "Користите другу методу пријављивања у два корака" @@ -1664,9 +1697,6 @@ "message": "Избегавај двосмислене карактере", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Поново генериши лозинку" - }, "length": { "message": "Дужина" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Опасна зона" }, - "dangerZoneDesc": { - "message": "Пажљиво, ове акције су крајне!" - }, - "dangerZoneDescSingular": { - "message": "Пажљиво, ова акција није реверзибилна!" - }, "deauthorizeSessions": { "message": "Одузели овлашћење сесије" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Наставак ће вас такође одјавити из тренутне сесије, што захтева поновно пријављивање. Од вас ће такође бити затражено да се поново пријавите у два корака, ако је омогућено. Активне сесије на другим уређајима могу да остану активне још један сат." }, + "newDeviceLoginProtection": { + "message": "Пријава на новом уређају" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Искључи заштиту пријаве на новом уређају" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Укључи заштиту пријаве на новом уређају" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "Одузето овлашћење свих сесија" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Управљати" }, - "canManage": { - "message": "Може управљати" + "manageCollection": { + "message": "Управљај колекцијом" + }, + "viewItems": { + "message": "Прикажи ставке" + }, + "viewItemsHidePass": { + "message": "Прикажи ставке, сакривене лозинке" + }, + "editItems": { + "message": "Уреди ставке" + }, + "editItemsHidePass": { + "message": "Уреди ставке, сакривене лозинке" }, "disable": { "message": "Онемогући" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "Догодила се грешка приликом читања безбедносног кључа. Покушајте поново." }, - "twoFactorWebAuthnWarning": { - "message": "Због ограничења платформе, WebAuthn се не могу користити на свим Bitwarden апликацијама. Требали бисте омогућити другог добављача услуге пријављивања у два корака како бисте могли да приступите свом налогу када WebAuthn не могу да се користе. Подржане платформе:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Веб сеф и додатке прегледача на рачунару са WebAuthn омогућен прегледач (Chrome, Opera, Vivaldi, или Firefox са FIDO U2F омогућено)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Ваш Bitwarden код за опоравак пријаве у два корака" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Поставите минималне захтеве за конфигурацију генератора лозинки." }, - "passwordGeneratorPolicyInEffect": { - "message": "Једна или више смерница организације утичу на поставке вашег генератора." - }, "masterPasswordPolicyInEffect": { "message": "Једна или више смерница организације захтевају да ваша главна лозинка да би испуњавали следеће захтеве:" }, @@ -5795,14 +5846,14 @@ "message": "Грешка при декрипцији" }, "couldNotDecryptVaultItemsBelow": { - "message": "Bitwarden could not decrypt the vault item(s) listed below." + "message": "Bitwarden није могао да декриптује ставке из трезора наведене испод." }, "contactCSToAvoidDataLossPart1": { - "message": "Contact customer success", + "message": "Обратите се корисничкој подршци", "description": "This is part of a larger sentence. The full sentence will read 'Contact customer success to avoid additional data loss.'" }, "contactCSToAvoidDataLossPart2": { - "message": "to avoid additional data loss.", + "message": "да бисте избегли додатни губитак података.", "description": "This is part of a larger sentence. The full sentence will read 'Contact customer success to avoid additional data loss.'" }, "accountRecoveryManageUsers": { @@ -6666,15 +6717,6 @@ "message": "Генератор", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "Шта желите да генеришете?" - }, - "passwordType": { - "message": "Тип лозинке" - }, - "regenerateUsername": { - "message": "Поново генериши име" - }, "generateUsername": { "message": "Генериши име" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Тип имена" - }, "plusAddressedEmail": { "message": "Плус имејл адресе", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Use your domain's configured catch-all inbox." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Случајно", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Име домаћина", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "Приступни АПИ токен" - }, "deviceVerification": { "message": "Провера уређаја" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "Нема колекције" }, - "canView": { - "message": "Може прегледати" - }, - "canViewExceptPass": { - "message": "Може видетим осим лозинке" - }, - "canEdit": { - "message": "Може уређивати" - }, - "canEditExceptPass": { - "message": "Ноже уређивати осим лозинке" - }, "noCollectionsAdded": { "message": "Ниједна колекција додата" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Ограничите брисање збирке на власнике и администраторе" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Власници и администратори могу да управљају свим колекцијама и ставкама" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Домен алијаса" - }, "alreadyHaveAccount": { "message": "Већ имате налог?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "Немате приступ за управљање овом колекцијом." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Фале дозволе „Може да управља“" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Додатје дозволе „Може да управља“ да би се омогућило потпуно управљање наплатом укључујући брисање колекције." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Одобрите групама или члановима приступ овој колекцији." @@ -9208,19 +9235,19 @@ "message": "Configure Bitwarden Directory Connector to automatically provision users and groups using the implementation guide for your Identity Provider." }, "eventManagement": { - "message": "Event management" + "message": "Управљање догађајима" }, "eventManagementDesc": { "message": "Integrate Bitwarden event logs with your SIEM (system information and event management) system by using the implementation guide for your platform." }, "deviceManagement": { - "message": "Device management" + "message": "Управљање уређајима" }, "deviceManagementDesc": { - "message": "Configure device management for Bitwarden using the implementation guide for your platform." + "message": "Конфигуришите управљање уређајима за Bitwarden помоћу водича за имплементацију за своју платформу." }, "integrationCardTooltip": { - "message": "Launch $INTEGRATION$ implementation guide.", + "message": "Покренути $INTEGRATION$ водич за имплементацију.", "placeholders": { "integration": { "content": "$1", @@ -9229,7 +9256,7 @@ } }, "smIntegrationTooltip": { - "message": "Set up $INTEGRATION$.", + "message": "Подесити $INTEGRATION$.", "placeholders": { "integration": { "content": "$1", @@ -9238,7 +9265,7 @@ } }, "smSdkTooltip": { - "message": "View $SDK$ repository", + "message": "Преглед $SDK$ спремишта", "placeholders": { "sdk": { "content": "$1", @@ -9809,13 +9836,13 @@ "message": "Алгоритам кључа" }, "sshPrivateKey": { - "message": "Private key" + "message": "Приватни кључ" }, "sshPublicKey": { - "message": "Public key" + "message": "Јавни кључ" }, "sshFingerprint": { - "message": "Fingerprint" + "message": "Отисак" }, "sshKeyFingerprint": { "message": "Отисак прста" @@ -9890,7 +9917,7 @@ "message": "Ваша комплементарна једногодишња претплата на Менаџер Лозинки ће надоградити на изабрани план. Неће вам бити наплаћено док се бесплатни период не заврши." }, "fileSavedToDevice": { - "message": "File saved to device. Manage from your device downloads." + "message": "Датотека је сачувана на уређају. Управљајте преузимањима са свог уређаја." }, "publicApi": { "message": "Јавни API", @@ -10068,7 +10095,16 @@ "message": "We have made a micro-deposit to your bank account (this may take 1-2 business days). Enter the six-digit code starting with 'SM' found on the deposit description. Failure to verify the bank account will result in a missed payment and your subscription being suspended." }, "descriptorCode": { - "message": "Descriptor code" + "message": "Кôд дескриптора" + }, + "cannotRemoveViewOnlyCollections": { + "message": "Не можете уклонити колекције са дозволама само за приказ: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } }, "importantNotice": { "message": "Важно обавештење" @@ -10110,13 +10146,13 @@ "message": "Уклони чланове" }, "devices": { - "message": "Devices" + "message": "Уређаји" }, "deviceListDescription": { - "message": "Your account was logged in to each of the devices below. If you do not recognize a device, remove it now." + "message": "Ваш рачун је пријављен на сваку од доле наведених уређаја. Ако не препознајете уређај, извадите га сада." }, "deviceListDescriptionTemp": { - "message": "Your account was logged in to each of the devices below." + "message": "Ваш рачун је пријављен на сваку од доле наведених уређаја." }, "claimedDomains": { "message": "Claimed domains" @@ -10250,15 +10286,64 @@ "message": "Organization subscription restarted" }, "restartSubscription": { - "message": "Restart your subscription" + "message": "Поново покрените претплату" }, "suspendedManagedOrgMessage": { - "message": "Contact $PROVIDER$ for assistance.", + "message": "Контактирајте $PROVIDER$ за помоћ.", "placeholders": { "provider": { "content": "$1", "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/sr_CS/messages.json b/apps/web/src/locales/sr_CS/messages.json index d79275d62fb..ac79efe57e0 100644 --- a/apps/web/src/locales/sr_CS/messages.json +++ b/apps/web/src/locales/sr_CS/messages.json @@ -1,24 +1,24 @@ { "allApplications": { - "message": "All applications" + "message": "Sve aplikacije" }, "criticalApplications": { - "message": "Critical applications" + "message": "Kritične aplikacije" }, "accessIntelligence": { - "message": "Access Intelligence" + "message": "Pristupi inteligenciji" }, "riskInsights": { - "message": "Risk Insights" + "message": "Uvid u rizik" }, "passwordRisk": { - "message": "Password Risk" + "message": "Rizik od lozinke" }, "reviewAtRiskPasswords": { - "message": "Review at-risk passwords (weak, exposed, or reused) across applications. Select your most critical applications to prioritize security actions for your users to address at-risk passwords." + "message": "Pregledaj rizične lozinke (slabe, izložene ili ponovo korišćene) u aplikacijama. Izaberi svoje najkritičnije aplikacije da bi dao prioritet bezbednosnim radnjama kako bi tvoji korisnici adresirali rizične lozinke." }, "dataLastUpdated": { - "message": "Data last updated: $DATE$", + "message": "Podaci su poslednji put ažurirani: $DATE$", "placeholders": { "date": { "content": "$1", @@ -27,19 +27,19 @@ } }, "notifiedMembers": { - "message": "Notified members" + "message": "Obavešteni članovi" }, "revokeMembers": { - "message": "Revoke members" + "message": "Ukloni članove" }, "restoreMembers": { - "message": "Restore members" + "message": "Vrati članove" }, "cannotRestoreAccessError": { - "message": "Cannot restore organization access" + "message": "Nije moguće povratiti pristup organizaciji" }, "allApplicationsWithCount": { - "message": "All applications ($COUNT$)", + "message": "Sve aplikacije ($COUNT$)", "placeholders": { "count": { "content": "$1", @@ -48,10 +48,10 @@ } }, "createNewLoginItem": { - "message": "Create new login item" + "message": "Kreirajte novu stavku za prijavu" }, "criticalApplicationsWithCount": { - "message": "Critical applications ($COUNT$)", + "message": "Kritične aplikacije ($COUNT$)", "placeholders": { "count": { "content": "$1", @@ -60,7 +60,7 @@ } }, "notifiedMembersWithCount": { - "message": "Notified members ($COUNT$)", + "message": "Obavešteni članovi ($COUNT$)", "placeholders": { "count": { "content": "$1", @@ -69,7 +69,7 @@ } }, "noAppsInOrgTitle": { - "message": "No applications found in $ORG NAME$", + "message": "Nije pronađena nijedna aplikacija u $ORG NAME$", "placeholders": { "org name": { "content": "$1", @@ -78,7 +78,7 @@ } }, "noAppsInOrgDescription": { - "message": "As users save logins, applications appear here, showing any at-risk passwords. Mark critical apps and notify users to update passwords." + "message": "Dok korisnici čuvaju prijave, aplikacije se pojavljuju ovde, prikazujući sve rizične lozinke. Označite kritične aplikacije i obavestite korisnike da ažuriraju lozinke." }, "noCriticalAppsTitle": { "message": "You haven't marked any applications as a Critical" @@ -464,6 +464,18 @@ "editFolder": { "message": "Urеdi fasciklu" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Osnovni domen", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "npr.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Log in initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Pošalji" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "Version $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Regeneriši lozinku" - }, "length": { "message": "Dužina" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Opasna zona" }, - "dangerZoneDesc": { - "message": "Pažljivo, ove odluke se ne mogu poništiti!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Deauthorize sessions" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Proceeding will also log you out of your current session, requiring you to log back in. You will also be prompted for two-step login again, if set up. Active sessions on other devices may continue to remain active for up to one hour." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "All sessions deauthorized" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Upravljaj" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Turn off" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "There was a problem reading the security key. Try again." }, - "twoFactorWebAuthnWarning": { - "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used. Supported platforms:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Web vault and browser extensions on a desktop/laptop with a WebAuthn supported browser (Chrome, Opera, Vivaldi, or Firefox with FIDO U2F turned on)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Your Bitwarden two-step login recovery code" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Set requirements for password generator." }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organization policies are affecting your generator settings." - }, "masterPasswordPolicyInEffect": { "message": "One or more organization policies require your master password to meet the following requirements:" }, @@ -6666,15 +6717,6 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Use your domain's configured catch-all inbox." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Random", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Hostname", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API access token" - }, "deviceVerification": { "message": "Device verification" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "No collection" }, - "canView": { - "message": "Can view" - }, - "canViewExceptPass": { - "message": "Can view, except passwords" - }, - "canEdit": { - "message": "Can edit" - }, - "canEditExceptPass": { - "message": "Can edit, except passwords" - }, "noCollectionsAdded": { "message": "No collections added" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domain" - }, "alreadyHaveAccount": { "message": "Already have an account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/sv/messages.json b/apps/web/src/locales/sv/messages.json index d413356e689..b7762e4c4dc 100644 --- a/apps/web/src/locales/sv/messages.json +++ b/apps/web/src/locales/sv/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Redigera mapp" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Basdomän", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Objektnamn" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "t.ex.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Inloggning påbörjad" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Skicka" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "En avisering har skickats till din enhet." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "Version $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Undvik tvetydiga tecken", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Återskapa lösenord" - }, "length": { "message": "Längd" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Farozon" }, - "dangerZoneDesc": { - "message": "Var försiktig, dessa åtgärder går inte att ångra!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Avauktorisera sessioner" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Om du fortsätter kommer du loggas ut från sin nuvarande session vilket kräver att du loggar in igen. Du kommer även behöva verifiera med tvåstegsverifiering om det är aktiverat. Aktiva sessioner på andra enheter kan fortsätta vara aktiva i upp till en timme." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "Alla sessioner avauktoriserades" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Hantera" }, - "canManage": { - "message": "Kan hantera" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Stäng av" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "Det gick inte att läsa säkerhetsnyckeln. Försök igen." }, - "twoFactorWebAuthnWarning": { - "message": "På grund av plattformsbegränsningar kan WebAuthn inte användas i alla Bitwarden-applikationer. Du bör aktivera en annan metod för tvåstegsverifiering så att du kan komma åt ditt konto när WebAuthn inte kan användas. Plattformar som stöds:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Webbvalvet och webbläsartillägg på en stationär eller bärbar dator med en WebAuthn-aktiverad webbläsare (Chrome, Opera, Vivaldi eller Firefox med FIDO U2F aktiverat)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Din återställningskod för tvåstegsverifiering" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Ange minimikrav för lösenordsgeneratorn." }, - "passwordGeneratorPolicyInEffect": { - "message": "En eller flera organisationspolicyer påverkar dina generatorinställningar." - }, "masterPasswordPolicyInEffect": { "message": "En eller flera organisationspolicyer kräver att ditt huvudlösenord uppfyller följande krav:" }, @@ -6666,15 +6717,6 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "Vad skulle du vilja generera?" - }, - "passwordType": { - "message": "Lösenordstyp" - }, - "regenerateUsername": { - "message": "Återskapa användarnamn" - }, "generateUsername": { "message": "Generera användarnamn" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Användarnamnstyp" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Use your domain's configured catch-all inbox." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Slumpmässigt", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Värdnamn", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API-åtkomsttoken" - }, "deviceVerification": { "message": "Device verification" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "Ingen samling" }, - "canView": { - "message": "Kan visa" - }, - "canViewExceptPass": { - "message": "Kan visa, utom lösenord" - }, - "canEdit": { - "message": "Kan redigera" - }, - "canEditExceptPass": { - "message": "Kan redigera, utom lösenord" - }, "noCollectionsAdded": { "message": "Ingen samlingar lades till" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Ägare och administratörer kan hantera alla samlingar och objekt" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Aliasdomän" - }, "alreadyHaveAccount": { "message": "Har du redan ett konto?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Ge grupper eller medlemmar tillgång till denna samling." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/te/messages.json b/apps/web/src/locales/te/messages.json index 486f01ce2cb..7e6f614b9c8 100644 --- a/apps/web/src/locales/te/messages.json +++ b/apps/web/src/locales/te/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Edit folder" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Base domain", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "ex.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Log in initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Submit" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "Version $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Regenerate password" - }, "length": { "message": "Length" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Danger zone" }, - "dangerZoneDesc": { - "message": "Careful, these actions are not reversible!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Deauthorize sessions" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Proceeding will also log you out of your current session, requiring you to log back in. You will also be prompted for two-step login again, if set up. Active sessions on other devices may continue to remain active for up to one hour." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "All sessions deauthorized" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Manage" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Turn off" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "There was a problem reading the security key. Try again." }, - "twoFactorWebAuthnWarning": { - "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used. Supported platforms:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Web vault and browser extensions on a desktop/laptop with a WebAuthn supported browser (Chrome, Opera, Vivaldi, or Firefox with FIDO U2F turned on)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Your Bitwarden two-step login recovery code" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Set requirements for password generator." }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organization policies are affecting your generator settings." - }, "masterPasswordPolicyInEffect": { "message": "One or more organization policies require your master password to meet the following requirements:" }, @@ -6666,15 +6717,6 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Use your domain's configured catch-all inbox." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Random", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Hostname", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API access token" - }, "deviceVerification": { "message": "Device verification" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "No collection" }, - "canView": { - "message": "Can view" - }, - "canViewExceptPass": { - "message": "Can view, except passwords" - }, - "canEdit": { - "message": "Can edit" - }, - "canEditExceptPass": { - "message": "Can edit, except passwords" - }, "noCollectionsAdded": { "message": "No collections added" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domain" - }, "alreadyHaveAccount": { "message": "Already have an account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/th/messages.json b/apps/web/src/locales/th/messages.json index ed3f668fa49..e906b3abfd1 100644 --- a/apps/web/src/locales/th/messages.json +++ b/apps/web/src/locales/th/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "แก้​ไข​โฟลเดอร์" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "โดเมนพื้นฐาน", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Item name" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "เช่น", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Log in initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "ส่ง" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "A notification has been sent to your device." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "Version $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Regenerate password" - }, "length": { "message": "Length" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Danger zone" }, - "dangerZoneDesc": { - "message": "Careful, these actions are not reversible!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Deauthorize sessions" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Proceeding will also log you out of your current session, requiring you to log back in. You will also be prompted for two-step login again, if set up. Active sessions on other devices may continue to remain active for up to one hour." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "All sessions deauthorized" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Manage" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Turn off" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "There was a problem reading the security key. Try again." }, - "twoFactorWebAuthnWarning": { - "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used. Supported platforms:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Web vault and browser extensions on a desktop/laptop with a WebAuthn supported browser (Chrome, Opera, Vivaldi, or Firefox with FIDO U2F turned on)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Your Bitwarden two-step login recovery code" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Set requirements for password generator." }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organization policies are affecting your generator settings." - }, "masterPasswordPolicyInEffect": { "message": "One or more organization policies require your master password to meet the following requirements:" }, @@ -6666,15 +6717,6 @@ "message": "Generator", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Use your domain's configured catch-all inbox." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Random", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Hostname", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API access token" - }, "deviceVerification": { "message": "Device verification" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "No collection" }, - "canView": { - "message": "Can view" - }, - "canViewExceptPass": { - "message": "Can view, except passwords" - }, - "canEdit": { - "message": "Can edit" - }, - "canEditExceptPass": { - "message": "Can edit, except passwords" - }, "noCollectionsAdded": { "message": "No collections added" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias domain" - }, "alreadyHaveAccount": { "message": "Already have an account?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/tr/messages.json b/apps/web/src/locales/tr/messages.json index 3ceb891631a..b9db895499f 100644 --- a/apps/web/src/locales/tr/messages.json +++ b/apps/web/src/locales/tr/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Klasörü düzenle" }, + "newFolder": { + "message": "Yeni klasör" + }, + "folderName": { + "message": "Klasör adı" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Bu klasörü kalıcı olarak silmek istediğinizden emin misiniz?" + }, "baseDomain": { "message": "Ana alan adı", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Kayıt adı" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "örn.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Giriş başlatıldı" }, + "logInRequestSent": { + "message": "İstek gönderildi" + }, "submit": { "message": "Gönder" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "Cihazınıza bir bildirim gönderildi." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Hesabınıza erişmeye mi çalışıyorsunuz?" + }, + "accessAttemptBy": { + "message": "$EMAIL$ erişim denemesi", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Erişimi onayla" + }, + "denyAccess": { + "message": "Erişimi reddet" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "Cihazınıza bir bildirim gönderildi" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Lütfen hesabınızın kilidinin açık olduğundan ve parmak izi ifadesinin diğer cihazla eşleştiğinden emin olun" - }, "versionNumber": { "message": "Sürüm $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Okurken karışabilecek karakterleri kullanma", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Yeni parola oluştur" - }, "length": { "message": "Uzunluk" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Tehlikeli bölge" }, - "dangerZoneDesc": { - "message": "Dikkatli olun, bu işlemleri geri alamazsınız!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Oturumları kapat" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Devam ederseniz geçerli oturumunuz da sonlanacak ve yeniden oturum açmanız gerekecek. İki aşamalı girişi etkinleştirdiyseniz onu da tamamlamanız gerekecek. Diğer cihazlardaki aktif oturumlar bir saate kadar aktif kalabilir." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "Tüm oturumlar kapatıldı" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Yönet" }, - "canManage": { - "message": "Yönetebilir" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Devre dışı bırak" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "Güvenlik anahtarını okurken bir sorun oluştu. Tekrar deneyin." }, - "twoFactorWebAuthnWarning": { - "message": "Platform sınırlamaları nedeniyle WebAuthn tüm Bitwarden uygulamalarında kullanılamaz. WebAuthn kullanılamadığında hesabınıza erişebilmek için başka bir iki aşamalı doğrulama yöntemi ayarlamanız gerekir. Desteklenen platformlar:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "WebAuthn uyumlu bir tarayıcıya (FIDO U2F uyumlu Chrome, Opera, Vivaldi veya Firefox) sahip bir bilgisayardaki tarayıcı uzantıları." + "twoFactorWebAuthnWarning1": { + "message": "Platform sınırlamaları nedeniyle WebAuthn tüm Bitwarden uygulamalarında kullanılamaz. WebAuthn kullanılamadığında hesabınıza erişebilmek için başka bir iki aşamalı doğrulama yöntemi ayarlamanız gerekir." }, "twoFactorRecoveryYourCode": { "message": "Bitwarden iki aşamalı giriş kurtarma kodunuz" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Parola üreticisi gereksinimleri ayarlayın." }, - "passwordGeneratorPolicyInEffect": { - "message": "Bir ya da daha fazla kuruluş ilkesi, oluşturucu ayarlarınızı etkiliyor." - }, "masterPasswordPolicyInEffect": { "message": "Bir veya daha fazla kuruluş ilkesi gereğince ana parolanız aşağıdaki gereksinimleri karşılamalıdır:" }, @@ -6666,15 +6717,6 @@ "message": "Oluşturucu", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "Ne oluşturmak istersiniz?" - }, - "passwordType": { - "message": "Parola türü" - }, - "regenerateUsername": { - "message": "Kullanıcı adını yeniden oluştur" - }, "generateUsername": { "message": "Kullanıcı adı oluştur" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Kullanıcı adı türü" - }, "plusAddressedEmail": { "message": "Artı adresli e-posta", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Alan adınızın tüm iletileri yakalamaya ayarlanmış adresini kullanın." }, + "useThisEmail": { + "message": "Bu e-postayı kullan" + }, "random": { "message": "Rastgele", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Sunucu", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API erişim token'ı" - }, "deviceVerification": { "message": "Cihaz doğrulama" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "Koleksiyon yok" }, - "canView": { - "message": "Görüntüleyebilir" - }, - "canViewExceptPass": { - "message": "Parolalar hariç görüntüleyebilir" - }, - "canEdit": { - "message": "Düzenleyebilir" - }, - "canEditExceptPass": { - "message": "Parolalar hariç düzenleyebilir" - }, "noCollectionsAdded": { "message": "Hiç koleksiyon eklenmedi" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Koleksiyon silmeyi sahipler ve yöneticilerle sınırlandırın" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Sahipler ve yöneticiler tüm koleksiyonları ve öğeleri yönetebilir" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Alias alan adı" - }, "alreadyHaveAccount": { "message": "Zaten hesabınız var mı?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Gruplara veya üyelere bu koleksiyona erişim izni verin." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Önemli uyarı" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/uk/messages.json b/apps/web/src/locales/uk/messages.json index 1c00d760d00..4b9b33182b7 100644 --- a/apps/web/src/locales/uk/messages.json +++ b/apps/web/src/locales/uk/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Редагування" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Основний домен", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Назва запису" }, - "cannotRemoveViewOnlyCollections": { - "message": "Ви не можете вилучати збірки, маючи дозвіл лише на перегляд: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "зразок", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Ініційовано вхід" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Відправити" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "Сповіщення було надіслано на ваш пристрій." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "Сповіщення надіслано на ваш пристрій" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Переконайтеся, що ваш обліковий запис розблоковано і фраза відбитка на іншому пристрої збігається" - }, "versionNumber": { "message": "Версія $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Уникати неоднозначних символів", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Генерувати новий" - }, "length": { "message": "Довжина" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Небезпечна зона" }, - "dangerZoneDesc": { - "message": "Обережно, ці дії неможливо скасувати!" - }, - "dangerZoneDescSingular": { - "message": "Обережно, цю дію неможливо скасувати!" - }, "deauthorizeSessions": { "message": "Завершити сеанси" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Продовжуючи, ви також вийдете з поточного сеансу і необхідно буде виконати вхід знову. Ви також отримаєте повторний запит двоетапної перевірки, якщо вона увімкнена. Активні сеанси на інших пристроях можуть залишатися активними протягом години." }, + "newDeviceLoginProtection": { + "message": "Вхід з нового пристрою" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Вимкнути захист входу з нового пристрою" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Увімкнути захист входу з нового пристрою" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Виконайте наведені нижче дії, щоб вимкнути надсилання підтверджень під час входу з нового пристрою." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Виконайте наведені нижче дії, щоб увімкнути надсилання підтверджень під час входу з нового пристрою." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "Якщо захист входу з нового пристрою вимкнено, будь-хто може отримати доступ до вашого облікового запису з будь-якого пристрою, знаючи головний пароль. Щоб захистити свій обліковий запис і не вмикати надсилання підтверджень, налаштуйте двоетапну перевірку." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "Зміни захисту входу з нового пристрою збережено" + }, "sessionsDeauthorized": { "message": "Усі сеанси завершено" }, @@ -2045,7 +2090,7 @@ "message": "Показувати піктограми вебсайтів" }, "faviconDesc": { - "message": "Показувати впізнаване зображення біля кожного запису." + "message": "Показувати зображення біля кожного запису." }, "default": { "message": "Типово" @@ -2155,8 +2200,20 @@ "manage": { "message": "Керувати" }, - "canManage": { - "message": "Може керувати" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Вимкнути" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "Сталася проблема при читанні ключа безпеки. Спробуйте знову." }, - "twoFactorWebAuthnWarning": { - "message": "У зв'язку з обмеженнями платформи, WebAuthn не можна використовувати в усіх програмах Bitwarden. Вам слід активувати іншого провайдера двоетапної перевірки, щоб мати змогу отримати доступ до свого облікового запису, коли неможливо скористатися WebAuthn. Підтримувані платформи:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Вебсховище і розширення браузера на комп'ютерах і ноутбуках з браузерами, що мають підтримку WebAuthn (Chrome, Opera, Vivaldi, або Firefox з увімкненим FIDO U2F)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Ваш код відновлення двоетапної перевірки Bitwarden" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Встановити вимоги для генерування пароля." }, - "passwordGeneratorPolicyInEffect": { - "message": "На параметри генератора впливають одна чи декілька політик організації." - }, "masterPasswordPolicyInEffect": { "message": "Політика однієї або декількох організацій зобов'язує дотримання таких вимог для головного пароля:" }, @@ -6666,15 +6717,6 @@ "message": "Генератор", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "Що ви бажаєте згенерувати?" - }, - "passwordType": { - "message": "Тип пароля" - }, - "regenerateUsername": { - "message": "Повторно генерувати ім'я користувача" - }, "generateUsername": { "message": "Генерувати ім'я користувача" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Тип імені користувача" - }, "plusAddressedEmail": { "message": "Адреса е-пошти з плюсом", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Використовуйте свою скриньку вхідних Catch-All власного домену." }, + "useThisEmail": { + "message": "Використати цю е-пошту" + }, "random": { "message": "Випадково", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Ім'я вузла", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "Токен доступу до API" - }, "deviceVerification": { "message": "Перевірка пристрою" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "Немає збірки" }, - "canView": { - "message": "Може переглядати" - }, - "canViewExceptPass": { - "message": "Може переглядати, крім паролів" - }, - "canEdit": { - "message": "Може редагувати" - }, - "canEditExceptPass": { - "message": "Може редагувати, крім паролів" - }, "noCollectionsAdded": { "message": "Не додано жодної збірки" }, @@ -8284,31 +8311,31 @@ "message": "Довірені пристрої" }, "memberDecryptionOptionTdeDescPart1": { - "message": "Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The", + "message": "Учасникам не потрібен головний пароль під час входу з використанням SSO. Натомість використовується ключ шифрування, що зберігається на пристрої, роблячи цей пристрій довіреним. Перший пристрій, на якому учасник реєструється і входить до системи, буде довіреним. Нові пристрої необхідно схвалити за допомогою наявного довіреного пристрою або адміністратором.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescLink1": { - "message": "single organization", + "message": "Політику єдиної", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescPart2": { - "message": "policy,", + "message": "організації,", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescLink2": { - "message": "SSO required", + "message": "політику обов'язкового", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescPart3": { - "message": "policy, and", + "message": "SSO та", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescLink3": { - "message": "account recovery administration", + "message": "політику адміністрування облікового", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescPart4": { - "message": "policy will turn on when this option is used.", + "message": "запису буде ввімкнено, якщо використовується цей параметр.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "orgPermissionsUpdatedMustSetPassword": { @@ -8387,16 +8414,16 @@ "message": "Схвалити запит" }, "deviceApproved": { - "message": "Device approved" + "message": "Пристрій схвалено" }, "deviceRemoved": { - "message": "Device removed" + "message": "Пристрій вилучено" }, "removeDevice": { - "message": "Remove device" + "message": "Вилучити пристрій" }, "removeDeviceConfirmation": { - "message": "Are you sure you want to remove this device?" + "message": "Ви дійсно хочете вилучити цей пристрій?" }, "noDeviceRequests": { "message": "Немає запитів з пристрою" @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Дозволити видалення збірок лише власникам та адміністраторам" }, + "limitItemDeletionDesc": { + "message": "Обмежити видалення записів для учасників, які мають дозвіл \"Може керувати\"" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Власники та адміністратори можуть керувати всіма збірками та записами" }, @@ -8656,9 +8686,6 @@ "message": "URL-адреса власного сервера", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Псевдонім домену" - }, "alreadyHaveAccount": { "message": "Вже маєте обліковий запис?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "У вас немає доступу до керування цією збіркою." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Немає дозволу \"Може керувати\"" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Надайте дозвіл \"Може керувати\" для можливості повноцінного керування збірками, включно з видаленням." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Надайте групам або учасникам доступ до цієї збірки." @@ -9286,7 +9313,7 @@ "message": "на місяць за учасника" }, "monthPerMemberBilledAnnually": { - "message": "month per member billed annually" + "message": "місяць за учасника сплачується щороку" }, "seats": { "message": "Місця" @@ -9809,13 +9836,13 @@ "message": "Алгоритм ключа" }, "sshPrivateKey": { - "message": "Private key" + "message": "Закритий ключ" }, "sshPublicKey": { - "message": "Public key" + "message": "Відкритий ключ" }, "sshFingerprint": { - "message": "Fingerprint" + "message": "Цифровий відбиток" }, "sshKeyFingerprint": { "message": "Цифровий відбиток" @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Код дескриптора" }, + "cannotRemoveViewOnlyCollections": { + "message": "Ви не можете вилучати збірки, маючи дозвіл лише на перегляд: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Важлива інформація" }, @@ -10110,13 +10146,13 @@ "message": "Вилучити учасників" }, "devices": { - "message": "Devices" + "message": "Пристрої" }, "deviceListDescription": { - "message": "Your account was logged in to each of the devices below. If you do not recognize a device, remove it now." + "message": "Вхід у ваш обліковий запис виконано на пристроях, зазначених нижче. Якщо ви не розпізнаєте пристрій, вилучіть його." }, "deviceListDescriptionTemp": { - "message": "Your account was logged in to each of the devices below." + "message": "Вхід у ваш обліковий запис виконано на пристроях, зазначених нижче." }, "claimedDomains": { "message": "Заявлені домени" @@ -10204,7 +10240,7 @@ "message": "Назва організації не може перевищувати 50 символів." }, "resellerRenewalWarningMsg": { - "message": "Your subscription will renew soon. To ensure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "message": "Ваша передплата невдовзі поновиться. Щоб забезпечити безперебійну роботу, зверніться до $RESELLER$ для підтвердження поновлення до $RENEWAL_DATE$.", "placeholders": { "reseller": { "content": "$1", @@ -10217,7 +10253,7 @@ } }, "resellerOpenInvoiceWarningMgs": { - "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To ensure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "message": "Рахунок за вашу передплату випущено $ISSUED_DATE$. Щоб забезпечити безперебійну роботу, зверніться до $RESELLER$ для підтвердження поновлення до $DUE_DATE$.", "placeholders": { "reseller": { "content": "$1", @@ -10234,7 +10270,7 @@ } }, "resellerPastDueWarningMsg": { - "message": "The invoice for your subscription has not been paid. To ensure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "message": "Рахунок за вашу передплату ще не сплачено. Щоб забезпечити безперебійну роботу, зверніться до $RESELLER$ для підтвердження поновлення до $GRACE_PERIOD_END$.", "placeholders": { "reseller": { "content": "$1", @@ -10247,18 +10283,67 @@ } }, "restartOrganizationSubscription": { - "message": "Organization subscription restarted" + "message": "Передплату організації розпочато повторно" }, "restartSubscription": { - "message": "Restart your subscription" + "message": "Розпочніть повторно свою передплату" }, "suspendedManagedOrgMessage": { - "message": "Contact $PROVIDER$ for assistance.", + "message": "Звернутися до $PROVIDER$ по допомогу.", "placeholders": { "provider": { "content": "$1", "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/vi/messages.json b/apps/web/src/locales/vi/messages.json index 36f6385875f..4b7ce90344a 100644 --- a/apps/web/src/locales/vi/messages.json +++ b/apps/web/src/locales/vi/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "Chỉnh sửa thư mục" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "Tên miền cơ sở", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "Tên mục" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "vd.", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "Log in initiated" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "Gửi" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "Một thông báo đã được gửi đến thiết bị của bạn." }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "A notification was sent to your device" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "Phiên bản $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "Tạo lại mật khẩu" - }, "length": { "message": "Độ dài" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "Vùng nguy hiểm" }, - "dangerZoneDesc": { - "message": "Cẩn thận, thao tác này không thể khôi phục!" - }, - "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" - }, "deauthorizeSessions": { "message": "Gỡ phiên" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "Sẽ đăng xuất bạn ra khỏi phiên hiện tại, sau đó cần đăng nhập lại. Bạn cũng sẽ phải đăng nhập hai bước lại nếu bạn có đăng nhập hai bước. Những phiên đăng nhập trên các thiết bị khác sẽ tiếp tục có hiệu lực lên đến 1 tiếng." }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "Tất cả phiên đăng nhập đã bị gỡ" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "Quản lý" }, - "canManage": { - "message": "Can manage" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "Vô hiệu hoá" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "There was a problem reading the security key. Try again." }, - "twoFactorWebAuthnWarning": { - "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used. Supported platforms:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "Web vault and browser extensions on a desktop/laptop with a WebAuthn supported browser (Chrome, Opera, Vivaldi, or Firefox with FIDO U2F turned on)." + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "Your Bitwarden two-step login recovery code" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "Set requirements for password generator." }, - "passwordGeneratorPolicyInEffect": { - "message": "Các chính sách của tổ chức đang ảnh hưởng đến cài đặt tạo mật khẩu của bạn." - }, "masterPasswordPolicyInEffect": { "message": "One or more organization policies require your master password to meet the following requirements:" }, @@ -6666,15 +6717,6 @@ "message": "Trình tạo", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Địa chỉ email có hậu tố", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "Use your domain's configured catch-all inbox." }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "Random", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "Hostname", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API access token" - }, "deviceVerification": { "message": "Device verification" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "No collection" }, - "canView": { - "message": "Can view" - }, - "canViewExceptPass": { - "message": "Can view, except passwords" - }, - "canEdit": { - "message": "Can edit" - }, - "canEditExceptPass": { - "message": "Can edit, except passwords" - }, "noCollectionsAdded": { "message": "No collections added" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Chủ sở hữu và quản trị viên có thể quản lý tất cả các bộ sưu tập và mục" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "Tên miền thay thế" - }, "alreadyHaveAccount": { "message": "Bạn đã có tài khoản?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/locales/zh_CN/messages.json b/apps/web/src/locales/zh_CN/messages.json index c17a3ae7b2d..72b3b470031 100644 --- a/apps/web/src/locales/zh_CN/messages.json +++ b/apps/web/src/locales/zh_CN/messages.json @@ -199,7 +199,7 @@ "message": "备注" }, "note": { - "message": "备注" + "message": "笔记" }, "customFields": { "message": "自定义字段" @@ -254,7 +254,7 @@ } }, "websiteAdded": { - "message": "网址已添加" + "message": "网站已添加" }, "addWebsite": { "message": "添加网站" @@ -464,6 +464,18 @@ "editFolder": { "message": "编辑文件夹" }, + "newFolder": { + "message": "新增文件夹" + }, + "folderName": { + "message": "文件夹名称" + }, + "folderHintText": { + "message": "通过在父文件夹名后面添加「/」来嵌套文件夹。示例:Social/Forums" + }, + "deleteFolderPermanently": { + "message": "您确定要永久删除这个文件夹吗?" + }, "baseDomain": { "message": "基础域", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "项目名称" }, - "cannotRemoveViewOnlyCollections": { - "message": "您无法删除仅具有「查看」权限的集合:$COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "例如", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "登录已发起" }, + "logInRequestSent": { + "message": "请求已发送" + }, "submit": { "message": "提交" }, @@ -1198,7 +1204,7 @@ "message": "主密码" }, "masterPassDesc": { - "message": "主密码是您访问密码库的密码。它非常重要,请您不要忘记。一旦忘记,无任何办法恢复此密码。" + "message": "主密码是用于访问您的密码库的密码。不要忘记您的主密码,这一点非常重要。一旦忘记,无任何办法恢复此密码。" }, "masterPassImportant": { "message": "主密码忘记后,将无法恢复!" @@ -1213,7 +1219,7 @@ "message": "主密码提示(可选)" }, "newMasterPassHint": { - "message": "新的主密码提示(可选)" + "message": "新主密码提示(可选)" }, "masterPassHintLabel": { "message": "主密码提示" @@ -1363,7 +1369,7 @@ "message": "没有可列出的事件。" }, "newOrganization": { - "message": "新建组织" + "message": "新增组织" }, "noOrganizationsList": { "message": "您没有加入任何组织。同一组织的用户可以安全地与其他用户共享项目。" @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "通知已发送到您的设备。" }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "您正在尝试访问您的账户吗?" + }, + "accessAttemptBy": { + "message": "$EMAIL$ 的访问尝试", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "确认访问" + }, + "denyAccess": { + "message": "拒绝访问" + }, + "notificationSentDeviceAnchor": { + "message": "网页 App" + }, + "notificationSentDevicePart2": { + "message": "在批准前,请确保指纹短语与下面的相匹配。" + }, + "notificationSentDeviceComplete": { + "message": "在您的设备上解锁 Bitwarden。在批准前,请确保指纹短语与下面的相匹配。" + }, "aNotificationWasSentToYourDevice": { "message": "通知已发送到您的设备" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "确保您的账户已解锁,并且指纹短语与其他设备上的相匹配。" - }, "versionNumber": { "message": "版本: $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "避免易混淆的字符", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "重新生成密码" - }, "length": { "message": "长度" }, @@ -1743,7 +1773,7 @@ "message": "继续操作将更改您的账户电子邮箱地址。这不会更改用于双重身份验证的电子邮箱地址。您可以在两步登录设置中更改它。" }, "newEmail": { - "message": "新的电子邮箱" + "message": "新电子邮箱" }, "code": { "message": "代码" @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "危险操作区" }, - "dangerZoneDesc": { - "message": "当心,这些操作无法撤销!" - }, - "dangerZoneDescSingular": { - "message": "当心,此操作无法撤销!" - }, "deauthorizeSessions": { "message": "取消会话授权" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "继续操作还将使您退出当前会话,并要求您重新登录。如果有设置两步登录,也需要重新验证。其他设备上的活动会话可能会继续保持活动状态长达一小时。" }, + "newDeviceLoginProtection": { + "message": "新设备登录" + }, + "turnOffNewDeviceLoginProtection": { + "message": "关闭新设备登录保护" + }, + "turnOnNewDeviceLoginProtection": { + "message": "开启新设备登录保护" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "按照以下步骤关闭 Bitwarden 在您从新设备登录时发送验证电子邮件的功能。" + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "按照以下步骤开启 Bitwarden 在您从新设备登录时发送验证电子邮件的功能。" + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "关闭新设备登录保护后,任何拥有您的主密码的人都可以从任何设备访问您的账户。要在没有验证电子邮件的情况下保护您的账户,请设置两步登录。" + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "新设备登录保护更改已保存" + }, "sessionsDeauthorized": { "message": "已取消所有会话授权" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "管理" }, - "canManage": { - "message": "可以管理" + "manageCollection": { + "message": "管理集合" + }, + "viewItems": { + "message": "查看项目" + }, + "viewItemsHidePass": { + "message": "查看项目,隐藏密码" + }, + "editItems": { + "message": "编辑项目" + }, + "editItemsHidePass": { + "message": "编辑项目,隐藏密码" }, "disable": { "message": "停用" @@ -2264,7 +2321,7 @@ } }, "webAuthnkeyX": { - "message": "WebAuthn 密钥 $INDEX$", + "message": "WebAuthn 钥匙 $INDEX$", "placeholders": { "index": { "content": "$1", @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "读取安全钥匙时出现问题,请重试。" }, - "twoFactorWebAuthnWarning": { - "message": "由于平台限制,WebAuthn 不能在所有 Bitwarden 应用程序上使用。您应该启用另一个两步登录提供程序,以便在 WebAuthn 无法使用时可以访问您的账户。支持的平台有:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "桌面/笔记本电脑上支持 WebAuthn 的浏览器(启用了 FIDO U2F 的 Chrome、Opera、Vivaldi 或 Firefox)中的网页密码库和浏览器扩展。" + "twoFactorWebAuthnWarning1": { + "message": "由于平台限制,WebAuthn 不能在所有 Bitwarden 应用程序上使用。您应该启用另一个两步登录提供程序,以便在无法使用 WebAuthn 时可以访问您的账户。" }, "twoFactorRecoveryYourCode": { "message": "您的 Bitwarden 两步登录恢复代码" @@ -2443,7 +2497,7 @@ "message": "发现暴露的密码" }, "exposedPasswordsFoundReportDesc": { - "message": "我们在您的 $VAULT$ 中发现了 $COUNT$ 个在已知的数据泄露事件中暴露了密码的项目。您应更改它们以使用新的密码。", + "message": "我们在您的 $VAULT$ 中发现了 $COUNT$ 个在已知的数据泄露中暴露了密码的项目。您应更改它们以使用新的密码。", "placeholders": { "count": { "content": "$1", @@ -2456,7 +2510,7 @@ } }, "noExposedPasswords": { - "message": "您的密码库中没有在已知数据泄露事件中被暴露密码的项目。" + "message": "您的密码库中没有在已知数据泄露中暴露了密码的项目。" }, "checkExposedPasswords": { "message": "检查暴露的密码" @@ -2629,7 +2683,7 @@ "message": "请确保您的账户有足够的信用额度来用于此购买。如果您的账户信用额度不足,您的默认付款方式将用于补足差额。您可以从「计费」页面向您的账户添加信用额度。" }, "creditAppliedDesc": { - "message": "您账户的信用额度可用于进行消费。任何可用的信用额度将用于自动支付此账户的账单。" + "message": "您账户的信用额度可用于进行消费。任何可用的信用额度将用于自动抵扣此账户的账单。" }, "goPremium": { "message": "升级高级会员", @@ -2764,7 +2818,7 @@ "message": "任何未付费订阅都将通过您的付款方式收取费用。" }, "paymentChargedWithTrial": { - "message": "您的计划包含了 7 天的免费试用期。在试用期结束前,不会从您的付款方式中扣款。您可以随时取消。" + "message": "您的计划包含了 7 天的免费试用。在试用期结束前,不会从您的付款方式中扣款。您可以随时取消。" }, "paymentInformation": { "message": "支付信息" @@ -2905,7 +2959,7 @@ "description": "Noun. A refunded payment that was charged." }, "chargesStatement": { - "message": "任何费用将在您的对账单上以 $STATEMENT_NAME$ 显示。", + "message": "任何费用将以 $STATEMENT_NAME$ 出现在您的对账单上。", "placeholders": { "statement_name": { "content": "$1", @@ -2923,7 +2977,7 @@ "message": "添加存储空间将会调整计费总金额,并立即通过您的付款方式进行扣款。第一笔费用将按当前计费周期的剩余时间按比例分配。" }, "storageRemoveNote": { - "message": "移除存储空间将会调整计费总金额,这笔费用将按比例返回下一笔账单费用中。" + "message": "移除存储空间将会调整计费总金额,这笔调整费用将按比例作为信用额度抵扣您的下一笔账单费用。" }, "adjustedStorage": { "message": "已调整 $AMOUNT$ GB 的存储空间。", @@ -3420,7 +3474,7 @@ "message": "更改了帐户密码" }, "enabledUpdated2fa": { - "message": "保存了两步登录" + "message": "两步登录已保存" }, "disabled2fa": { "message": "停用了两步登录" @@ -3781,7 +3835,7 @@ } }, "unlinkedSso": { - "message": "未链接 SSO。" + "message": "取消链接 SSO。" }, "unlinkedSsoUser": { "message": "为用户 $ID$ 取消链接 SSO。", @@ -4395,7 +4449,7 @@ "message": "添加用户席位将会调整计费总金额,并立即通过您的付款方式进行扣款。第一笔费用将按当前计费周期的剩余时间按比例分配。" }, "seatsRemoveNote": { - "message": "移除用户席位将会调整计费总金额,这笔费用将按比例返回下一笔账单费用中。" + "message": "移除用户席位将会调整计费总金额,这笔调整费用将按比例作为信用额度抵扣您的下一笔账单费用。" }, "adjustedSeats": { "message": "调整了 $AMOUNT$ 个用户席位。", @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "设置密码生成器要求。" }, - "passwordGeneratorPolicyInEffect": { - "message": "一个或多个组织策略正在影响您的生成器设置。" - }, "masterPasswordPolicyInEffect": { "message": "一个或多个组织策略要求您的主密码满足以下要求:" }, @@ -5060,7 +5111,7 @@ "message": "确定移除此密码?" }, "hideEmail": { - "message": "对收件人隐藏我的电子邮箱地址。" + "message": "对接收者隐藏我的电子邮箱地址。" }, "disableThisSend": { "message": "停用此 Send 确保无人能访问它。", @@ -5074,7 +5125,7 @@ "description": "This text will be displayed after a Send has been accessed the maximum amount of times." }, "pendingDeletion": { - "message": "等待删除" + "message": "待删除" }, "expired": { "message": "已过期" @@ -5088,7 +5139,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendProtectedPasswordDontKnow": { - "message": "不知道密码?请向提供此 Send 的发件人索要密码。", + "message": "不知道密码吗?请向发送者索取访问此 Send 所需的密码。", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendHiddenByDefault": { @@ -5129,7 +5180,7 @@ "message": "添加紧急联系人" }, "designatedEmergencyContacts": { - "message": "已指定为紧急联系人" + "message": "指定为紧急联系人" }, "noGrantedAccess": { "message": "您尚未被任何人指定为紧急联系人。" @@ -5294,14 +5345,14 @@ "message": "可以管理组织策略的组织成员豁免此策略。" }, "disableHideEmail": { - "message": "在创建或编辑 Send 时,始终向收件人显示成员的电子邮箱地址。", + "message": "创建或编辑 Send 时,始终向接收者显示成员的电子邮箱地址。", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendOptionsPolicyInEffect": { "message": "以下组织策略目前正起作用:" }, "sendDisableHideEmailInEffect": { - "message": "创建或编辑 Send 时,不允许用户对收件人隐藏他们的电子邮箱地址。", + "message": "创建或编辑 Send 时,不允许用户对接收者隐藏他们的电子邮箱地址。", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "modifiedPolicyId": { @@ -5489,7 +5540,7 @@ "message": "发送请求" }, "addANote": { - "message": "添加备注" + "message": "添加笔记" }, "bitwardenSecretsManager": { "message": "Bitwarden 机密管理器" @@ -5864,7 +5915,7 @@ "message": "提供商" }, "newClientOrganization": { - "message": "新建客户组织" + "message": "新增客户组织" }, "newClientOrganizationDesc": { "message": "创建一个新的客户组织,该组织将作为提供商与你关联。您将可以访问和管理这个组织。" @@ -6148,7 +6199,7 @@ "message": "最小入站签名算法" }, "spWantAssertionsSigned": { - "message": "要求使用签名的断言" + "message": "期望已签名的断言" }, "spValidateCertificates": { "message": "验证证书" @@ -6184,7 +6235,7 @@ "message": "允许出站注销请求" }, "idpSignAuthenticationRequests": { - "message": "签名身份验证请求" + "message": "签署身份验证请求" }, "ssoSettingsSaved": { "message": "单点登录配置已保存" @@ -6211,7 +6262,7 @@ "message": "链接已失效。请让赞助方重新发送邀请。" }, "reclaimedFreePlan": { - "message": "重新认领免费计划" + "message": "重新申领免费计划" }, "redeem": { "message": "兑换" @@ -6283,7 +6334,7 @@ "message": "立即兑换" }, "recipient": { - "message": "收件人" + "message": "接收者" }, "removeSponsorship": { "message": "移除赞助" @@ -6666,15 +6717,6 @@ "message": "生成器", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "您想要生成什么?" - }, - "passwordType": { - "message": "密码类型" - }, - "regenerateUsername": { - "message": "重新生成用户名" - }, "generateUsername": { "message": "生成用户名" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "用户名类型" - }, "plusAddressedEmail": { "message": "附加地址电子邮箱", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "使用您的域名配置的 Catch-all 收件箱。" }, + "useThisEmail": { + "message": "使用此电子邮箱" + }, "random": { "message": "随机", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "主机名", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API 访问令牌" - }, "deviceVerification": { "message": "设备验证" }, @@ -7326,7 +7365,7 @@ "description": "Message to encourage the user to start creating service accounts." }, "serviceAccountsNoItemsTitle": { - "message": "还没有要显示的内容", + "message": "还没有可显示的内容", "description": "Title to indicate that there are no service accounts to display." }, "searchSecrets": { @@ -7648,18 +7687,6 @@ "noCollection": { "message": "没有集合" }, - "canView": { - "message": "可以查看" - }, - "canViewExceptPass": { - "message": "除密码外,可以查看" - }, - "canEdit": { - "message": "可以编辑" - }, - "canEditExceptPass": { - "message": "除密码外,可以编辑" - }, "noCollectionsAdded": { "message": "未添加任何集合" }, @@ -8320,7 +8347,7 @@ "description": "Used as a card title description on the set password page to explain why the user is there" }, "cardMetrics": { - "message": "$TOTAL$ 不足", + "message": "总计 $TOTAL$", "placeholders": { "total": { "content": "$1", @@ -8602,10 +8629,13 @@ "message": "管理组织的集合行为" }, "limitCollectionCreationDesc": { - "message": "限制为仅所有者和管理员可以创建集合" + "message": "限制为所有者和管理员可以创建集合" }, "limitCollectionDeletionDesc": { - "message": "限制为仅所有者和管理员可以删除集合" + "message": "限制为所有者和管理员可以删除集合" + }, + "limitItemDeletionDesc": { + "message": "限制为拥有「可以管理」权限的成员可以删除项目" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "所有者和管理员可以管理所有集合和项目" @@ -8656,9 +8686,6 @@ "message": "自托管服务器 URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "别名域" - }, "alreadyHaveAccount": { "message": "已经拥有账户了吗?" }, @@ -8669,7 +8696,7 @@ "message": "跳转到内容" }, "managePermissionRequired": { - "message": "必须至少有一个成员或群组拥有「可以管理」的权限。" + "message": "必须至少有一个成员或群组拥有「可以管理」权限。" }, "typePasskey": { "message": "通行密钥" @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "您没有管理此集合的权限。" }, - "grantAddAccessCollectionWarningTitle": { - "message": "缺少「可以管理」权限" + "grantManageCollectionWarningTitle": { + "message": "缺少「管理集合」权限" }, - "grantAddAccessCollectionWarning": { - "message": "授予「可以管理」权限以允许完整的集合管理,包括删除集合。" + "grantManageCollectionWarning": { + "message": "授予「管理集合」权限以允许完整的集合管理,包括删除集合。" }, "grantCollectionAccess": { "message": "授予群组或成员对此集合的访问权限。" @@ -8975,7 +9002,7 @@ "description": "Message to encourage the user to start creating machine accounts." }, "machineAccountsNoItemsTitle": { - "message": "暂无要显示的内容", + "message": "还没有可显示的内容", "description": "Title to indicate that there are no machine accounts to display." }, "deleteMachineAccounts": { @@ -9283,10 +9310,10 @@ "message": "35% 折扣" }, "monthPerMember": { - "message": " /成员 /月" + "message": "月 /成员" }, "monthPerMemberBilledAnnually": { - "message": " /成员 /月(按年计费)" + "message": "月 /成员(按年计费)" }, "seats": { "message": "席位" @@ -10062,14 +10089,23 @@ "message": "不允许成员通过此组织兑换家庭计划。" }, "verifyBankAccountWithStatementDescriptorWarning": { - "message": "使用银行账户付款仅对美国用户开放。您将被要求验证您的银行账户。我们将在 1-2 个工作日内进行一笔小额转账,请在组织的计费页面输入该转账的语句描述符代码以验证银行账户。验证银行账户失败将会错过支付,您的订阅将失效。" + "message": "使用银行账户付款仅对美国用户开放。您将被要求验证您的银行账户。我们将在 1-2 个工作日内进行一笔小额转账,请在组织的计费页面输入该转账的对账单描述符代码以验证银行账户。验证银行账户失败将会错过支付,您的订阅将失效。" }, "verifyBankAccountWithStatementDescriptorInstructions": { - "message": "我们已向您的银行账户存入了一笔小额转账(可能需要 1-2 个工作日到账)。请输入转账说明中以 \"SM\" 开头的六位数代码。验证银行账户失败将会错过支付,您的订阅将失效。" + "message": "我们已向您的银行账户存入了一笔小额转账(可能需要 1-2 个工作日到账)。请输入转账描述中以「SM」开头的六位数代码。验证银行账户失败将会错过支付,您的订阅将失效。" }, "descriptorCode": { "message": "描述符代码" }, + "cannotRemoveViewOnlyCollections": { + "message": "您无法删除仅具有「查看」权限的集合:$COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "重要通知" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "管理员现在可以删除已声明域名下的成员账户。" + }, + "deleteManagedUserWarningDesc": { + "message": "此操作将删除成员账户及其密码库中的所有项目。其取代了之前的「移除」操作。" + }, + "deleteManagedUserWarning": { + "message": "「删除」是一个新的操作!" + }, + "seatsRemaining": { + "message": "该组织已分配 $TOTAL$ 个席位,您还剩余 $REMAINING$ 个席位。请联系提供商管理您的订阅。", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "现有组织" + }, + "selectOrganizationProviderPortal": { + "message": "选择一个要添加到您的提供商门户的组织。" + }, + "noOrganizations": { + "message": "没有可列出的组织" + }, + "yourProviderSubscriptionCredit": { + "message": "您的提供商订阅将获得此组织订阅剩余时间内的信用额度。" + }, + "doYouWantToAddThisOrg": { + "message": "您想将该组织添加到 $PROVIDER$ 吗?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "添加了现有组织" + }, + "assignedExceedsAvailable": { + "message": "分配的席位超过可用席位。" } } diff --git a/apps/web/src/locales/zh_TW/messages.json b/apps/web/src/locales/zh_TW/messages.json index 06e4e5ad6c8..fc1bf0b63f1 100644 --- a/apps/web/src/locales/zh_TW/messages.json +++ b/apps/web/src/locales/zh_TW/messages.json @@ -464,6 +464,18 @@ "editFolder": { "message": "編輯資料夾" }, + "newFolder": { + "message": "New folder" + }, + "folderName": { + "message": "Folder name" + }, + "folderHintText": { + "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + }, + "deleteFolderPermanently": { + "message": "Are you sure you want to permanently delete this folder?" + }, "baseDomain": { "message": "基底網域", "description": "Domain name. Example: website.com" @@ -728,15 +740,6 @@ "itemName": { "message": "項目名" }, - "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", - "placeholders": { - "collections": { - "content": "$1", - "example": "Work, Personal" - } - } - }, "ex": { "message": "例如", "description": "Short abbreviation for 'example'." @@ -1182,6 +1185,9 @@ "logInInitiated": { "message": "登入已發起" }, + "logInRequestSent": { + "message": "Request sent" + }, "submit": { "message": "送出" }, @@ -1371,12 +1377,39 @@ "notificationSentDevice": { "message": "通知已傳送至您的裝置。" }, + "notificationSentDevicePart1": { + "message": "Unlock Bitwarden on your device or on the " + }, + "areYouTryingToAccessYourAccount": { + "message": "Are you trying to access your account?" + }, + "accessAttemptBy": { + "message": "Access attempt by $EMAIL$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, + "confirmAccess": { + "message": "Confirm access" + }, + "denyAccess": { + "message": "Deny access" + }, + "notificationSentDeviceAnchor": { + "message": "web app" + }, + "notificationSentDevicePart2": { + "message": "Make sure the Fingerprint phrase matches the one below before approving." + }, + "notificationSentDeviceComplete": { + "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + }, "aNotificationWasSentToYourDevice": { "message": "已傳送通知至您的裝置" }, - "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" - }, "versionNumber": { "message": "版本 $VERSION_NUMBER$", "placeholders": { @@ -1664,9 +1697,6 @@ "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." }, - "regeneratePassword": { - "message": "重新產生密碼" - }, "length": { "message": "長度" }, @@ -1839,12 +1869,6 @@ "dangerZone": { "message": "危險區域" }, - "dangerZoneDesc": { - "message": "小心,這些動作無法復原!" - }, - "dangerZoneDescSingular": { - "message": "小心,此操作無法復原!" - }, "deauthorizeSessions": { "message": "取消工作階段授權" }, @@ -1854,6 +1878,27 @@ "deauthorizeSessionsWarning": { "message": "接下來會登出目前的工作階段,並要求您重新登入。若您有設定兩步驟登入,也需重新驗證。其他裝置上的活動工作階段最多會保持一個小時。" }, + "newDeviceLoginProtection": { + "message": "New device login" + }, + "turnOffNewDeviceLoginProtection": { + "message": "Turn off new device login protection" + }, + "turnOnNewDeviceLoginProtection": { + "message": "Turn on new device login protection" + }, + "turnOffNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + }, + "turnOnNewDeviceLoginProtectionModalDesc": { + "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + }, + "turnOffNewDeviceLoginProtectionWarning": { + "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + }, + "accountNewDeviceLoginProtectionSaved": { + "message": "New device login protection changes saved" + }, "sessionsDeauthorized": { "message": "已取消所有工作階段授權" }, @@ -2155,8 +2200,20 @@ "manage": { "message": "管理" }, - "canManage": { - "message": "可以管理" + "manageCollection": { + "message": "Manage collection" + }, + "viewItems": { + "message": "View items" + }, + "viewItemsHidePass": { + "message": "View items, hidden passwords" + }, + "editItems": { + "message": "Edit items" + }, + "editItemsHidePass": { + "message": "Edit items, hidden passwords" }, "disable": { "message": "停用" @@ -2353,11 +2410,8 @@ "twoFactorU2fProblemReadingTryAgain": { "message": "讀取安全鑰匙時發生問題。請再試一次。" }, - "twoFactorWebAuthnWarning": { - "message": "由於平台限制,無法於所有 Bitwarden 應用程式中使用 WebAuthn。請設定另一套兩步驟登入方式,以確保在 WebAuthn 無法使用時還能存取您的帳戶。支援的平台有:" - }, - "twoFactorWebAuthnSupportWeb": { - "message": "桌上型電腦/筆記型電腦上支援 WebAuthn 功能的瀏覽器(啟用了 FIDO U2F 的 Chrome、Opera、Vivaldi 或 Firefox)上的網頁版密碼庫和瀏覽器擴充套件。" + "twoFactorWebAuthnWarning1": { + "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." }, "twoFactorRecoveryYourCode": { "message": "您的 Bitwarden 兩步驟登入復原碼" @@ -4695,9 +4749,6 @@ "passwordGeneratorPolicyDesc": { "message": "設定密碼產生器要求。" }, - "passwordGeneratorPolicyInEffect": { - "message": "一個或多個組織原則正影響密碼產生器設定。" - }, "masterPasswordPolicyInEffect": { "message": "一個或多個組織原則要求您的主密碼須符合下列條件:" }, @@ -6666,15 +6717,6 @@ "message": "產生器", "description": "Short for 'credential generator'." }, - "whatWouldYouLikeToGenerate": { - "message": "您想要產生什麼?" - }, - "passwordType": { - "message": "密碼類型" - }, - "regenerateUsername": { - "message": "重新產生使用者名稱" - }, "generateUsername": { "message": "產生使用者名稱" }, @@ -6715,9 +6757,6 @@ } } }, - "usernameType": { - "message": "使用者名稱類型" - }, "plusAddressedEmail": { "message": "加號地址電子郵件", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -6731,6 +6770,9 @@ "catchallEmailDesc": { "message": "使用您的網域設定的 Catch-all 收件匣。" }, + "useThisEmail": { + "message": "Use this email" + }, "random": { "message": "隨機", "description": "Generates domain-based username using random letters" @@ -6934,9 +6976,6 @@ "message": "主機名稱", "description": "Part of a URL." }, - "apiAccessToken": { - "message": "API 存取權杖" - }, "deviceVerification": { "message": "裝置驗證" }, @@ -7648,18 +7687,6 @@ "noCollection": { "message": "沒有分類" }, - "canView": { - "message": "可以檢視" - }, - "canViewExceptPass": { - "message": "可以檢視(除了密碼)" - }, - "canEdit": { - "message": "可以編輯" - }, - "canEditExceptPass": { - "message": "可以編輯(除了密碼)" - }, "noCollectionsAdded": { "message": "未新增任何分類" }, @@ -8607,6 +8634,9 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, + "limitItemDeletionDesc": { + "message": "Limit item deletion to members with the Can manage permission" + }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "擁有人與管理員可以管理所有分類與項目" }, @@ -8656,9 +8686,6 @@ "message": "Self-host server URL", "description": "Label for field requesting a self-hosted integration service URL" }, - "aliasDomain": { - "message": "別名網域" - }, "alreadyHaveAccount": { "message": "已經有一個帳戶了嗎?" }, @@ -8720,11 +8747,11 @@ "readOnlyCollectionAccess": { "message": "You do not have access to manage this collection." }, - "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "grantManageCollectionWarningTitle": { + "message": "Missing Manage Collection Permissions" }, - "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "grantManageCollectionWarning": { + "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." @@ -10070,6 +10097,15 @@ "descriptorCode": { "message": "Descriptor code" }, + "cannotRemoveViewOnlyCollections": { + "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "placeholders": { + "collections": { + "content": "$1", + "example": "Work, Personal" + } + } + }, "importantNotice": { "message": "Important notice" }, @@ -10260,5 +10296,54 @@ "example": "Acme c" } } + }, + "accountDeprovisioningNotification": { + "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + }, + "deleteManagedUserWarningDesc": { + "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + }, + "deleteManagedUserWarning": { + "message": "Delete is a new action!" + }, + "seatsRemaining": { + "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "placeholders": { + "remaining": { + "content": "$1", + "example": "5" + }, + "total": { + "content": "$2", + "example": "10" + } + } + }, + "existingOrganization": { + "message": "Existing organization" + }, + "selectOrganizationProviderPortal": { + "message": "Select an organization to add to your Provider Portal." + }, + "noOrganizations": { + "message": "There are no organizations to list" + }, + "yourProviderSubscriptionCredit": { + "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + }, + "doYouWantToAddThisOrg": { + "message": "Do you want to add this organization to $PROVIDER$?", + "placeholders": { + "provider": { + "content": "$1", + "example": "Cool MSP" + } + } + }, + "addedExistingOrganization": { + "message": "Added existing organization" + }, + "assignedExceedsAvailable": { + "message": "Assigned seats exceed available seats." } } diff --git a/apps/web/src/scss/pages.scss b/apps/web/src/scss/pages.scss index 684d45a1a66..1e5c233e326 100644 --- a/apps/web/src/scss/pages.scss +++ b/apps/web/src/scss/pages.scss @@ -1,37 +1,3 @@ -app-generator { - #lengthRange { - width: 100%; - } - - .card-generated { - .card-body { - @include themify($themes) { - background: themed("foregroundColor"); - } - align-items: center; - display: flex; - flex-wrap: wrap; - font-family: $font-family-monospace; - font-size: $font-size-lg; - justify-content: center; - text-align: center; - } - } -} - -app-password-generator-history { - .list-group-item { - line-height: 1; - @include themify($themes) { - background: themed("backgroundColor"); - } - - .password { - font-family: $font-family-monospace; - } - } -} - tools-import { textarea { height: 150px; diff --git a/apps/web/tsconfig.build.json b/apps/web/tsconfig.build.json index b10c4f9d899..39ab37efbb8 100644 --- a/apps/web/tsconfig.build.json +++ b/apps/web/tsconfig.build.json @@ -1,5 +1,8 @@ { "extends": "./tsconfig.json", "files": ["src/polyfills.ts", "src/main.ts", "src/theme.ts"], - "include": ["src/connectors/*.ts", "../../libs/common/src/platform/services/**/*.worker.ts"] + "include": [ + "src/connectors/*.ts", + "../../libs/common/src/key-management/crypto/services/encrypt.worker.ts" + ] } diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json index c88b41d6f0e..68ac8c80085 100644 --- a/apps/web/tsconfig.json +++ b/apps/web/tsconfig.json @@ -18,8 +18,8 @@ "@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/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"], @@ -43,6 +43,6 @@ "src/connectors/*.ts", "src/**/*.stories.ts", "src/**/*.spec.ts", - "../../libs/common/src/platform/services/**/*.worker.ts" + "../../libs/common/src/key-management/crypto/services/encrypt.worker.ts" ] } diff --git a/bitwarden_license/bit-cli/tsconfig.json b/bitwarden_license/bit-cli/tsconfig.json index e3d6cc5c7b7..4a972b540a7 100644 --- a/bitwarden_license/bit-cli/tsconfig.json +++ b/bitwarden_license/bit-cli/tsconfig.json @@ -18,7 +18,7 @@ "@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/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"], diff --git a/bitwarden_license/bit-common/src/admin-console/auth-requests/organization-auth-request.service.spec.ts b/bitwarden_license/bit-common/src/admin-console/auth-requests/organization-auth-request.service.spec.ts index e893b2dfe8c..448399a8bb0 100644 --- a/bitwarden_license/bit-common/src/admin-console/auth-requests/organization-auth-request.service.spec.ts +++ b/bitwarden_license/bit-common/src/admin-console/auth-requests/organization-auth-request.service.spec.ts @@ -4,8 +4,8 @@ import { OrganizationUserApiService, OrganizationUserResetPasswordDetailsResponse, } from "@bitwarden/admin-console/common"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { ListResponse } from "@bitwarden/common/models/response/list.response"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { KeyService } from "@bitwarden/key-management"; diff --git a/bitwarden_license/bit-common/src/admin-console/auth-requests/organization-auth-request.service.ts b/bitwarden_license/bit-common/src/admin-console/auth-requests/organization-auth-request.service.ts index 4c4507e5cb8..025b021f83d 100644 --- a/bitwarden_license/bit-common/src/admin-console/auth-requests/organization-auth-request.service.ts +++ b/bitwarden_license/bit-common/src/admin-console/auth-requests/organization-auth-request.service.ts @@ -4,7 +4,7 @@ import { OrganizationUserApiService, OrganizationUserResetPasswordDetailsResponse, } from "@bitwarden/admin-console/common"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; diff --git a/bitwarden_license/bit-common/src/tools/reports/risk-insights/models/password-health.ts b/bitwarden_license/bit-common/src/tools/reports/risk-insights/models/password-health.ts index 2260f9257ad..723d737d5bd 100644 --- a/bitwarden_license/bit-common/src/tools/reports/risk-insights/models/password-health.ts +++ b/bitwarden_license/bit-common/src/tools/reports/risk-insights/models/password-health.ts @@ -85,6 +85,7 @@ export type WeakPasswordScore = { * How many times a password has been exposed */ export type ExposedPasswordDetail = { + cipherId: string; exposedXTimes: number; } | null; diff --git a/bitwarden_license/bit-common/src/tools/reports/risk-insights/services/critical-apps.service.spec.ts b/bitwarden_license/bit-common/src/tools/reports/risk-insights/services/critical-apps.service.spec.ts index 5b89a2abb1e..64f55ccf99f 100644 --- a/bitwarden_license/bit-common/src/tools/reports/risk-insights/services/critical-apps.service.spec.ts +++ b/bitwarden_license/bit-common/src/tools/reports/risk-insights/services/critical-apps.service.spec.ts @@ -4,7 +4,7 @@ import { fakeAsync, flush } from "@angular/core/testing"; import { mock } from "jest-mock-extended"; import { of } from "rxjs"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { CsprngArray } from "@bitwarden/common/types/csprng"; diff --git a/bitwarden_license/bit-common/src/tools/reports/risk-insights/services/critical-apps.service.ts b/bitwarden_license/bit-common/src/tools/reports/risk-insights/services/critical-apps.service.ts index 00b4dc78dae..7db34757b96 100644 --- a/bitwarden_license/bit-common/src/tools/reports/risk-insights/services/critical-apps.service.ts +++ b/bitwarden_license/bit-common/src/tools/reports/risk-insights/services/critical-apps.service.ts @@ -13,7 +13,7 @@ import { zip, } from "rxjs"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { OrganizationId } from "@bitwarden/common/types/guid"; import { OrgKey } from "@bitwarden/common/types/key"; diff --git a/bitwarden_license/bit-common/src/tools/reports/risk-insights/services/risk-insights-data.service.ts b/bitwarden_license/bit-common/src/tools/reports/risk-insights/services/risk-insights-data.service.ts index 668fb187251..386c6fd6865 100644 --- a/bitwarden_license/bit-common/src/tools/reports/risk-insights/services/risk-insights-data.service.ts +++ b/bitwarden_license/bit-common/src/tools/reports/risk-insights/services/risk-insights-data.service.ts @@ -28,6 +28,7 @@ export class RiskInsightsDataService { dataLastUpdated$ = this.dataLastUpdatedSubject.asObservable(); openDrawer = false; + drawerInvokerId: string = ""; activeDrawerType: DrawerType = DrawerType.None; atRiskMemberDetails: AtRiskMemberDetail[] = []; appAtRiskMembers: AppAtRiskMembersDialogParams | null = null; @@ -73,25 +74,35 @@ export class RiskInsightsDataService { return this.activeDrawerType === drawerType; }; - setDrawerForOrgAtRiskMembers = (atRiskMemberDetails: AtRiskMemberDetail[]): void => { + setDrawerForOrgAtRiskMembers = ( + atRiskMemberDetails: AtRiskMemberDetail[], + invokerId: string = "", + ): void => { this.resetDrawer(DrawerType.OrgAtRiskMembers); this.activeDrawerType = DrawerType.OrgAtRiskMembers; + this.drawerInvokerId = invokerId; this.atRiskMemberDetails = atRiskMemberDetails; this.openDrawer = !this.openDrawer; }; setDrawerForAppAtRiskMembers = ( atRiskMembersDialogParams: AppAtRiskMembersDialogParams, + invokerId: string = "", ): void => { this.resetDrawer(DrawerType.None); this.activeDrawerType = DrawerType.AppAtRiskMembers; + this.drawerInvokerId = invokerId; this.appAtRiskMembers = atRiskMembersDialogParams; this.openDrawer = !this.openDrawer; }; - setDrawerForOrgAtRiskApps = (atRiskApps: AtRiskApplicationDetail[]): void => { + setDrawerForOrgAtRiskApps = ( + atRiskApps: AtRiskApplicationDetail[], + invokerId: string = "", + ): void => { this.resetDrawer(DrawerType.OrgAtRiskApps); this.activeDrawerType = DrawerType.OrgAtRiskApps; + this.drawerInvokerId = invokerId; this.atRiskAppDetails = atRiskApps; this.openDrawer = !this.openDrawer; }; @@ -109,5 +120,6 @@ export class RiskInsightsDataService { this.atRiskMemberDetails = []; this.appAtRiskMembers = null; this.atRiskAppDetails = null; + this.drawerInvokerId = ""; }; } diff --git a/bitwarden_license/bit-common/src/tools/reports/risk-insights/services/risk-insights-report.service.ts b/bitwarden_license/bit-common/src/tools/reports/risk-insights/services/risk-insights-report.service.ts index c3bcc59eca5..027760f678c 100644 --- a/bitwarden_license/bit-common/src/tools/reports/risk-insights/services/risk-insights-report.service.ts +++ b/bitwarden_license/bit-common/src/tools/reports/risk-insights/services/risk-insights-report.service.ts @@ -175,6 +175,7 @@ export class RiskInsightsReportService { ): Promise { const cipherHealthReports: CipherHealthReportDetail[] = []; const passwordUseMap = new Map(); + const exposedDetails = await this.findExposedPasswords(ciphers); for (const cipher of ciphers) { if (this.validateCipher(cipher)) { const weakPassword = this.findWeakPassword(cipher); @@ -189,7 +190,7 @@ export class RiskInsightsReportService { passwordUseMap.set(cipher.login.password, 1); } - const exposedPassword = await this.findExposedPassword(cipher); + const exposedPassword = exposedDetails.find((x) => x.cipherId === cipher.id); // Get the cipher members const cipherMembers = memberDetails.filter((x) => x.cipherId === cipher.id); @@ -255,13 +256,29 @@ export class RiskInsightsReportService { return appReports; } - private async findExposedPassword(cipher: CipherView): Promise { - const exposedCount = await this.auditService.passwordLeaked(cipher.login.password); - if (exposedCount > 0) { - const exposedDetail = { exposedXTimes: exposedCount } as ExposedPasswordDetail; - return exposedDetail; - } - return null; + private async findExposedPasswords(ciphers: CipherView[]): Promise { + const exposedDetails: ExposedPasswordDetail[] = []; + const promises: Promise[] = []; + + ciphers.forEach((ciph) => { + if (this.validateCipher(ciph)) { + const promise = this.auditService + .passwordLeaked(ciph.login.password) + .then((exposedCount) => { + if (exposedCount > 0) { + const detail = { + exposedXTimes: exposedCount, + cipherId: ciph.id, + } as ExposedPasswordDetail; + exposedDetails.push(detail); + } + }); + promises.push(promise); + } + }); + await Promise.all(promises); + + return exposedDetails; } private findWeakPassword(cipher: CipherView): WeakPasswordDetail { diff --git a/bitwarden_license/bit-web/src/app/admin-console/organizations/manage/device-approvals/device-approvals.component.ts b/bitwarden_license/bit-web/src/app/admin-console/organizations/manage/device-approvals/device-approvals.component.ts index ac8ad3112b9..744cf2c4674 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/organizations/manage/device-approvals/device-approvals.component.ts +++ b/bitwarden_license/bit-web/src/app/admin-console/organizations/manage/device-approvals/device-approvals.component.ts @@ -10,8 +10,8 @@ import { OrganizationAuthRequestApiService } from "@bitwarden/bit-common/admin-c import { OrganizationAuthRequestService } from "@bitwarden/bit-common/admin-console/auth-requests/organization-auth-request.service"; import { PendingAuthRequestView } from "@bitwarden/bit-common/admin-console/auth-requests/pending-auth-request.view"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/manage/dialogs/bulk-confirm-dialog.component.ts b/bitwarden_license/bit-web/src/app/admin-console/providers/manage/dialogs/bulk-confirm-dialog.component.ts index 6ab07cc0794..c5b949512d7 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/manage/dialogs/bulk-confirm-dialog.component.ts +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/manage/dialogs/bulk-confirm-dialog.component.ts @@ -13,8 +13,8 @@ import { ProviderUserBulkConfirmRequest } from "@bitwarden/common/admin-console/ import { ProviderUserBulkRequest } from "@bitwarden/common/admin-console/models/request/provider/provider-user-bulk.request"; import { ProviderUserBulkPublicKeyResponse } from "@bitwarden/common/admin-console/models/response/provider/provider-user-bulk-public-key.response"; import { ProviderUserBulkResponse } from "@bitwarden/common/admin-console/models/response/provider/provider-user-bulk.response"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { ListResponse } from "@bitwarden/common/models/response/list.response"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { DialogService } from "@bitwarden/components"; diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/manage/members.component.ts b/bitwarden_license/bit-web/src/app/admin-console/providers/manage/members.component.ts index 16f794bd6d2..03e47569a55 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/manage/members.component.ts +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/manage/members.component.ts @@ -15,8 +15,8 @@ import { ProviderUserStatusType, ProviderUserType } from "@bitwarden/common/admi import { ProviderUserBulkRequest } from "@bitwarden/common/admin-console/models/request/provider/provider-user-bulk.request"; import { ProviderUserConfirmRequest } from "@bitwarden/common/admin-console/models/request/provider/provider-user-confirm.request"; import { ProviderUserUserDetailsResponse } from "@bitwarden/common/admin-console/models/response/provider/provider-user.response"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { ListResponse } from "@bitwarden/common/models/response/list.response"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service"; diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/providers-layout.component.html b/bitwarden_license/bit-web/src/app/admin-console/providers/providers-layout.component.html index a20dd1379e2..bf82fbd160b 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/providers-layout.component.html +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/providers-layout.component.html @@ -37,25 +37,5 @@ > - - {{ "providerClientVaultPrivacyNotification" | i18n }} - - {{ "contactBitwardenSupport" | i18n }} . - diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/providers-layout.component.ts b/bitwarden_license/bit-web/src/app/admin-console/providers/providers-layout.component.ts index 3f1a7ff3989..7e47da95e2b 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/providers-layout.component.ts +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/providers-layout.component.ts @@ -10,27 +10,15 @@ import { JslibModule } from "@bitwarden/angular/jslib.module"; import { ProviderService } from "@bitwarden/common/admin-console/abstractions/provider.service"; import { ProviderStatusType } from "@bitwarden/common/admin-console/enums"; import { Provider } from "@bitwarden/common/admin-console/models/domain/provider"; -import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; -import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; -import { BannerModule, IconModule, LinkModule } from "@bitwarden/components"; +import { IconModule } from "@bitwarden/components"; import { ProviderPortalLogo } from "@bitwarden/web-vault/app/admin-console/icons/provider-portal-logo"; import { WebLayoutModule } from "@bitwarden/web-vault/app/layouts/web-layout.module"; -import { ProviderClientVaultPrivacyBannerService } from "./services/provider-client-vault-privacy-banner.service"; - @Component({ selector: "providers-layout", templateUrl: "providers-layout.component.html", standalone: true, - imports: [ - CommonModule, - RouterModule, - JslibModule, - WebLayoutModule, - IconModule, - LinkModule, - BannerModule, - ], + imports: [CommonModule, RouterModule, JslibModule, WebLayoutModule, IconModule], }) export class ProvidersLayoutComponent implements OnInit, OnDestroy { protected readonly logo = ProviderPortalLogo; @@ -41,15 +29,9 @@ export class ProvidersLayoutComponent implements OnInit, OnDestroy { protected isBillable: Observable; protected canAccessBilling$: Observable; - protected showProviderClientVaultPrivacyWarningBanner$ = this.configService.getFeatureFlag$( - FeatureFlag.ProviderClientVaultPrivacyBanner, - ); - constructor( private route: ActivatedRoute, private providerService: ProviderService, - private configService: ConfigService, - protected providerClientVaultPrivacyBannerService: ProviderClientVaultPrivacyBannerService, ) {} ngOnInit() { diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/providers.module.ts b/bitwarden_license/bit-web/src/app/admin-console/providers/providers.module.ts index 37cb9618b60..c720a94d5ec 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/providers.module.ts +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/providers.module.ts @@ -6,7 +6,7 @@ import { FormsModule } from "@angular/forms"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { SearchModule } from "@bitwarden/components"; import { DangerZoneComponent } from "@bitwarden/web-vault/app/auth/settings/account/danger-zone.component"; -import { OrganizationPlansComponent, TaxInfoComponent } from "@bitwarden/web-vault/app/billing"; +import { OrganizationPlansComponent } from "@bitwarden/web-vault/app/billing"; import { OssModule } from "@bitwarden/web-vault/app/oss.module"; import { @@ -17,6 +17,7 @@ import { ProviderSubscriptionComponent, ProviderSubscriptionStatusComponent, } from "../../billing/providers"; +import { AddExistingOrganizationDialogComponent } from "../../billing/providers/clients/add-existing-organization-dialog.component"; import { AddOrganizationComponent } from "./clients/add-organization.component"; import { CreateOrganizationComponent } from "./clients/create-organization.component"; @@ -46,7 +47,6 @@ import { VerifyRecoverDeleteProviderComponent } from "./verify-recover-delete-pr OrganizationPlansComponent, SearchModule, ProvidersLayoutComponent, - TaxInfoComponent, DangerZoneComponent, ScrollingModule, ], @@ -63,6 +63,7 @@ import { VerifyRecoverDeleteProviderComponent } from "./verify-recover-delete-pr SetupProviderComponent, UserAddEditComponent, AddEditMemberDialogComponent, + AddExistingOrganizationDialogComponent, CreateClientDialogComponent, ManageClientNameDialogComponent, ManageClientSubscriptionDialogComponent, diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/services/provider-client-vault-privacy-banner.service.ts b/bitwarden_license/bit-web/src/app/admin-console/providers/services/provider-client-vault-privacy-banner.service.ts deleted file mode 100644 index c347f5c2aae..00000000000 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/services/provider-client-vault-privacy-banner.service.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Injectable } from "@angular/core"; - -import { - StateProvider, - AC_BANNERS_DISMISSED_DISK, - UserKeyDefinition, -} from "@bitwarden/common/platform/state"; - -export const SHOW_BANNER_KEY = new UserKeyDefinition( - AC_BANNERS_DISMISSED_DISK, - "showProviderClientVaultPrivacyBanner", - { - deserializer: (b) => b, - clearOn: [], - }, -); - -/** Displays a banner warning provider users that client organization vaults - * will soon become inaccessible directly. */ -@Injectable({ providedIn: "root" }) -export class ProviderClientVaultPrivacyBannerService { - private _showBanner = this.stateProvider.getActive(SHOW_BANNER_KEY); - - showBanner$ = this._showBanner.state$; - - constructor(private stateProvider: StateProvider) {} - - async hideBanner() { - await this._showBanner.update(() => false); - } -} diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/services/web-provider.service.ts b/bitwarden_license/bit-web/src/app/admin-console/providers/services/web-provider.service.ts index 264b43aee9d..d3482ea67a5 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/services/web-provider.service.ts +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/services/web-provider.service.ts @@ -1,15 +1,20 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore import { Injectable } from "@angular/core"; +import { firstValueFrom, map } from "rxjs"; +import { switchMap } from "rxjs/operators"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { ProviderApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/provider/provider-api.service.abstraction"; import { OrganizationKeysRequest } from "@bitwarden/common/admin-console/models/request/organization-keys.request"; import { ProviderAddOrganizationRequest } from "@bitwarden/common/admin-console/models/request/provider/provider-add-organization.request"; import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions/billing-api.service.abstraction"; import { PlanType } from "@bitwarden/common/billing/enums"; import { CreateClientOrganizationRequest } from "@bitwarden/common/billing/models/request/create-client-organization.request"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { StateProvider } from "@bitwarden/common/platform/state"; +import { OrganizationId } from "@bitwarden/common/types/guid"; import { OrgKey } from "@bitwarden/common/types/key"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { KeyService } from "@bitwarden/key-management"; @@ -23,6 +28,8 @@ export class WebProviderService { private i18nService: I18nService, private encryptService: EncryptService, private billingApiService: BillingApiServiceAbstraction, + private stateProvider: StateProvider, + private providerApiService: ProviderApiServiceAbstraction, ) {} async addOrganizationToProvider(providerId: string, organizationId: string) { @@ -40,6 +47,22 @@ export class WebProviderService { return response; } + async addOrganizationToProviderVNext(providerId: string, organizationId: string): Promise { + const orgKey = await firstValueFrom( + this.stateProvider.activeUserId$.pipe( + switchMap((userId) => this.keyService.orgKeys$(userId)), + map((organizationKeysById) => organizationKeysById[organizationId as OrganizationId]), + ), + ); + const providerKey = await this.keyService.getProviderKey(providerId); + const encryptedOrgKey = await this.encryptService.encrypt(orgKey.key, providerKey); + await this.providerApiService.addOrganizationToProvider(providerId, { + key: encryptedOrgKey.encryptedString, + organizationId, + }); + await this.syncService.fullSync(true); + } + async createClientOrganization( providerId: string, name: string, diff --git a/bitwarden_license/bit-web/src/app/app.component.ts b/bitwarden_license/bit-web/src/app/app.component.ts index 1e0f60e2cd2..dd814f5c0d2 100644 --- a/bitwarden_license/bit-web/src/app/app.component.ts +++ b/bitwarden_license/bit-web/src/app/app.component.ts @@ -20,17 +20,10 @@ export class AppComponent extends BaseAppComponent implements OnInit { this.policyListService.addPolicies([ new MaximumVaultTimeoutPolicy(), new DisablePersonalVaultExportPolicy(), + new FreeFamiliesSponsorshipPolicy(), + new ActivateAutofillPolicy(), ]); - this.configService - .getFeatureFlag(FeatureFlag.DisableFreeFamiliesSponsorship) - .then((isFreeFamilyEnabled) => { - if (isFreeFamilyEnabled) { - this.policyListService.addPolicies([new FreeFamiliesSponsorshipPolicy()]); - } - this.policyListService.addPolicies([new ActivateAutofillPolicy()]); - }); - this.configService.getFeatureFlag(FeatureFlag.IdpAutoSubmitLogin).then((enabled) => { if ( enabled && diff --git a/bitwarden_license/bit-web/src/app/billing/providers/clients/add-existing-organization-dialog.component.html b/bitwarden_license/bit-web/src/app/billing/providers/clients/add-existing-organization-dialog.component.html new file mode 100644 index 00000000000..a22484ed92d --- /dev/null +++ b/bitwarden_license/bit-web/src/app/billing/providers/clients/add-existing-organization-dialog.component.html @@ -0,0 +1,73 @@ + + + {{ "addExistingOrganization" | i18n }} + + + +

{{ "selectOrganizationProviderPortal" | i18n }}

+ + + + {{ "name" | i18n }} + {{ "assigned" | i18n }} + + + + + + + + + {{ addable.name }} +
+ {{ "assignedExceedsAvailable" | i18n }} +
+ + {{ addable.seats }} + + + + +
+
+

+ {{ "noOrganizations" | i18n }} +

+
+ +

{{ "yourProviderSubscriptionCredit" | i18n }}

+

{{ "doYouWantToAddThisOrg" | i18n: dialogParams.provider.name }}

+
+
{{ "organization" | i18n }}: {{ selectedOrganization.name }}
+
{{ "billingPlan" | i18n }}: {{ selectedOrganization.plan }}
+
{{ "assignedSeats" | i18n }}: {{ selectedOrganization.seats }}
+
+
+
+ + + + +
diff --git a/bitwarden_license/bit-web/src/app/billing/providers/clients/add-existing-organization-dialog.component.ts b/bitwarden_license/bit-web/src/app/billing/providers/clients/add-existing-organization-dialog.component.ts new file mode 100644 index 00000000000..3df0693d091 --- /dev/null +++ b/bitwarden_license/bit-web/src/app/billing/providers/clients/add-existing-organization-dialog.component.ts @@ -0,0 +1,82 @@ +import { DIALOG_DATA, DialogConfig, DialogRef } from "@angular/cdk/dialog"; +import { Component, Inject, OnInit } from "@angular/core"; + +import { ProviderApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/provider/provider-api.service.abstraction"; +import { Provider } from "@bitwarden/common/admin-console/models/domain/provider"; +import { AddableOrganizationResponse } from "@bitwarden/common/admin-console/models/response/addable-organization.response"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { DialogService, ToastService } from "@bitwarden/components"; + +import { WebProviderService } from "../../../admin-console/providers/services/web-provider.service"; + +export type AddExistingOrganizationDialogParams = { + provider: Provider; +}; + +export enum AddExistingOrganizationDialogResultType { + Closed = "closed", + Submitted = "submitted", +} + +@Component({ + templateUrl: "./add-existing-organization-dialog.component.html", +}) +export class AddExistingOrganizationDialogComponent implements OnInit { + protected loading: boolean = true; + + addableOrganizations: AddableOrganizationResponse[] = []; + selectedOrganization?: AddableOrganizationResponse; + + protected readonly ResultType = AddExistingOrganizationDialogResultType; + + constructor( + @Inject(DIALOG_DATA) protected dialogParams: AddExistingOrganizationDialogParams, + private dialogRef: DialogRef, + private i18nService: I18nService, + private providerApiService: ProviderApiServiceAbstraction, + private toastService: ToastService, + private webProviderService: WebProviderService, + ) {} + + async ngOnInit() { + this.addableOrganizations = await this.providerApiService.getProviderAddableOrganizations( + this.dialogParams.provider.id, + ); + this.loading = false; + } + + addExistingOrganization = async (): Promise => { + if (this.selectedOrganization) { + await this.webProviderService.addOrganizationToProviderVNext( + this.dialogParams.provider.id, + this.selectedOrganization.id, + ); + + this.toastService.showToast({ + variant: "success", + title: "", + message: this.i18nService.t("addedExistingOrganization"), + }); + + this.dialogRef.close(this.ResultType.Submitted); + } + }; + + selectOrganization(organizationId: string) { + this.selectedOrganization = this.addableOrganizations.find( + (organization) => organization.id === organizationId, + ); + } + + static open = ( + dialogService: DialogService, + dialogConfig: DialogConfig< + AddExistingOrganizationDialogParams, + DialogRef + >, + ) => + dialogService.open< + AddExistingOrganizationDialogResultType, + AddExistingOrganizationDialogParams + >(AddExistingOrganizationDialogComponent, dialogConfig); +} diff --git a/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-clients.component.html b/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-clients.component.html index 7c560e49579..077aeb6c124 100644 --- a/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-clients.component.html +++ b/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-clients.component.html @@ -1,9 +1,39 @@ - - - {{ "addNewOrganization" | i18n }} - + + + + + + + + + + + {{ "addNewOrganization" | i18n }} + + diff --git a/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-clients.component.ts b/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-clients.component.ts index ee2c541e72f..07434369122 100644 --- a/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-clients.component.ts +++ b/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-clients.component.ts @@ -11,6 +11,8 @@ import { Provider } from "@bitwarden/common/admin-console/models/domain/provider import { ProviderOrganizationOrganizationDetailsResponse } from "@bitwarden/common/admin-console/models/response/provider/provider-organization.response"; import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions"; import { PlanResponse } from "@bitwarden/common/billing/models/response/plan.response"; +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 { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service"; import { @@ -25,6 +27,10 @@ import { HeaderModule } from "@bitwarden/web-vault/app/layouts/header/header.mod import { WebProviderService } from "../../../admin-console/providers/services/web-provider.service"; +import { + AddExistingOrganizationDialogComponent, + AddExistingOrganizationDialogResultType, +} from "./add-existing-organization-dialog.component"; import { CreateClientDialogResultType, openCreateClientDialog, @@ -62,6 +68,9 @@ export class ManageClientsComponent { protected searchControl = new FormControl("", { nonNullable: true }); protected plans: PlanResponse[] = []; + protected addExistingOrgsFromProviderPortal$ = this.configService.getFeatureFlag$( + FeatureFlag.PM15179_AddExistingOrgsFromProviderPortal, + ); constructor( private billingApiService: BillingApiServiceAbstraction, @@ -73,6 +82,7 @@ export class ManageClientsComponent { private toastService: ToastService, private validationService: ValidationService, private webProviderService: WebProviderService, + private configService: ConfigService, ) { this.activatedRoute.queryParams.pipe(first(), takeUntilDestroyed()).subscribe((queryParams) => { this.searchControl.setValue(queryParams.search); @@ -111,19 +121,30 @@ export class ManageClientsComponent { async load() { this.provider = await firstValueFrom(this.providerService.get$(this.providerId)); - this.isProviderAdmin = this.provider?.type === ProviderUserType.ProviderAdmin; - - const clients = (await this.billingApiService.getProviderClientOrganizations(this.providerId)) - .data; - - this.dataSource.data = clients; - + this.dataSource.data = ( + await this.billingApiService.getProviderClientOrganizations(this.providerId) + ).data; this.plans = (await this.billingApiService.getPlans()).data; - this.loading = false; } + addExistingOrganization = async () => { + if (this.provider) { + const reference = AddExistingOrganizationDialogComponent.open(this.dialogService, { + data: { + provider: this.provider, + }, + }); + + const result = await lastValueFrom(reference.closed); + + if (result === AddExistingOrganizationDialogResultType.Submitted) { + await this.load(); + } + } + }; + createClient = async () => { const reference = openCreateClientDialog(this.dialogService, { data: { diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/projects/project.service.ts b/bitwarden_license/bit-web/src/app/secrets-manager/projects/project.service.ts index ee2395b3f83..8c9f894f8f6 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/projects/project.service.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/projects/project.service.ts @@ -4,8 +4,8 @@ import { Injectable } from "@angular/core"; import { Subject } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { ListResponse } from "@bitwarden/common/models/response/list.response"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { KeyService } from "@bitwarden/key-management"; diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/secrets/secret.service.spec.ts b/bitwarden_license/bit-web/src/app/secrets-manager/secrets/secret.service.spec.ts index a3d46d2ef2e..c761d73d4a1 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/secrets/secret.service.spec.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/secrets/secret.service.spec.ts @@ -1,7 +1,7 @@ import { mock } from "jest-mock-extended"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { KeyService } from "@bitwarden/key-management"; diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/secrets/secret.service.ts b/bitwarden_license/bit-web/src/app/secrets-manager/secrets/secret.service.ts index 950d3c42ccb..51c49d79f2d 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/secrets/secret.service.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/secrets/secret.service.ts @@ -4,7 +4,7 @@ import { Injectable } from "@angular/core"; import { Subject } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { KeyService } from "@bitwarden/key-management"; diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/access/access.service.ts b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/access/access.service.ts index 8eb4a5120a2..773cb83e70a 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/access/access.service.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/access/access.service.ts @@ -4,8 +4,8 @@ import { Injectable } from "@angular/core"; import { Subject } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { ListResponse } from "@bitwarden/common/models/response/list.response"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { KeyGenerationService } from "@bitwarden/common/platform/abstractions/key-generation.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/service-account.service.ts b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/service-account.service.ts index a85f5c5e09a..a56111bc655 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/service-account.service.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/service-account.service.ts @@ -4,8 +4,8 @@ import { Injectable } from "@angular/core"; import { Subject } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { ListResponse } from "@bitwarden/common/models/response/list.response"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { KeyService } from "@bitwarden/key-management"; diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/settings/services/sm-porting-api.service.spec.ts b/bitwarden_license/bit-web/src/app/secrets-manager/settings/services/sm-porting-api.service.spec.ts index fb0ab467a02..6b527d56502 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/settings/services/sm-porting-api.service.spec.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/settings/services/sm-porting-api.service.spec.ts @@ -1,7 +1,7 @@ import { mock } from "jest-mock-extended"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/settings/services/sm-porting-api.service.ts b/bitwarden_license/bit-web/src/app/secrets-manager/settings/services/sm-porting-api.service.ts index c5934067fd7..c9d63e61400 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/settings/services/sm-porting-api.service.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/settings/services/sm-porting-api.service.ts @@ -4,8 +4,8 @@ import { Injectable } from "@angular/core"; import { Subject } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { ErrorResponse } from "@bitwarden/common/models/response/error.response"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { KeyService } from "@bitwarden/key-management"; diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy.service.spec.ts b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy.service.spec.ts index 4ae80d4decc..d6bc807686a 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy.service.spec.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy.service.spec.ts @@ -3,7 +3,7 @@ import { mock } from "jest-mock-extended"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { CsprngArray } from "@bitwarden/common/types/csprng"; diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy.service.ts b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy.service.ts index 920e12ef0cf..5223135c17a 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy.service.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy.service.ts @@ -4,8 +4,8 @@ import { Injectable } from "@angular/core"; import { Subject } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { ListResponse } from "@bitwarden/common/models/response/list.response"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { KeyService } from "@bitwarden/key-management"; diff --git a/bitwarden_license/bit-web/src/app/tools/access-intelligence/access-intelligence.module.ts b/bitwarden_license/bit-web/src/app/tools/access-intelligence/access-intelligence.module.ts index 5f461ff6c49..8b78a7e8975 100644 --- a/bitwarden_license/bit-web/src/app/tools/access-intelligence/access-intelligence.module.ts +++ b/bitwarden_license/bit-web/src/app/tools/access-intelligence/access-intelligence.module.ts @@ -10,7 +10,7 @@ import { } from "@bitwarden/bit-common/tools/reports/risk-insights/services"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { AuditService } from "@bitwarden/common/abstractions/audit.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength/password-strength.service.abstraction"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { KeyService } from "@bitwarden/key-management"; diff --git a/bitwarden_license/bit-web/src/app/tools/access-intelligence/all-applications.component.html b/bitwarden_license/bit-web/src/app/tools/access-intelligence/all-applications.component.html index bcc15fbc8fc..c0eb8080070 100644 --- a/bitwarden_license/bit-web/src/app/tools/access-intelligence/all-applications.component.html +++ b/bitwarden_license/bit-web/src/app/tools/access-intelligence/all-applications.component.html @@ -27,19 +27,25 @@

{{ "allApplications" | i18n }}

@@ -75,7 +81,11 @@
- + { + showOrgAtRiskMembers = async (invokerId: string) => { const dialogData = this.reportService.generateAtRiskMemberList(this.dataSource.data); - this.dataService.setDrawerForOrgAtRiskMembers(dialogData); + this.dataService.setDrawerForOrgAtRiskMembers(dialogData, invokerId); }; - showOrgAtRiskApps = async () => { + showOrgAtRiskApps = async (invokerId: string) => { const data = this.reportService.generateAtRiskApplicationList(this.dataSource.data); - this.dataService.setDrawerForOrgAtRiskApps(data); + this.dataService.setDrawerForOrgAtRiskApps(data, invokerId); }; onCheckboxChange(applicationName: string, event: Event) { diff --git a/bitwarden_license/bit-web/src/app/tools/access-intelligence/critical-applications.component.html b/bitwarden_license/bit-web/src/app/tools/access-intelligence/critical-applications.component.html index 72e60c470b0..4dc4b7ffb1a 100644 --- a/bitwarden_license/bit-web/src/app/tools/access-intelligence/critical-applications.component.html +++ b/bitwarden_license/bit-web/src/app/tools/access-intelligence/critical-applications.component.html @@ -35,19 +35,27 @@