diff --git a/.github/workflows/auto-branch-updater.yml b/.github/workflows/auto-branch-updater.yml index e2f181680d9..372aa92eba0 100644 --- a/.github/workflows/auto-branch-updater.yml +++ b/.github/workflows/auto-branch-updater.yml @@ -29,7 +29,7 @@ jobs: run: echo "branch=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 with: ref: 'eu-web-${{ steps.setup.outputs.branch }}' fetch-depth: 0 diff --git a/.github/workflows/build-browser.yml b/.github/workflows/build-browser.yml index 562567ffe77..4b25c588090 100644 --- a/.github/workflows/build-browser.yml +++ b/.github/workflows/build-browser.yml @@ -43,7 +43,7 @@ jobs: node_version: ${{ steps.retrieve-node-version.outputs.node_version }} steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Get Package Version id: gen_vars @@ -73,7 +73,7 @@ jobs: working-directory: apps/browser steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Testing locales - extName length run: | @@ -111,7 +111,7 @@ jobs: _NODE_VERSION: ${{ needs.setup.outputs.node_version }} steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Set up Node uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 @@ -254,7 +254,7 @@ jobs: _NODE_VERSION: ${{ needs.setup.outputs.node_version }} steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Set up Node uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 @@ -367,7 +367,7 @@ jobs: - build-safari steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Login to Azure uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 diff --git a/.github/workflows/build-cli.yml b/.github/workflows/build-cli.yml index bccfc6d57ce..b5b212423ab 100644 --- a/.github/workflows/build-cli.yml +++ b/.github/workflows/build-cli.yml @@ -43,7 +43,7 @@ jobs: node_version: ${{ steps.retrieve-node-version.outputs.node_version }} steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Get Package Version id: retrieve-package-version @@ -84,7 +84,7 @@ jobs: _WIN_PKG_VERSION: 3.5 steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Setup Unix Vars run: | @@ -162,7 +162,7 @@ jobs: _WIN_PKG_VERSION: 3.5 steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Setup Windows builder run: | @@ -312,7 +312,7 @@ jobs: _PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }} steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Print environment run: | diff --git a/.github/workflows/build-desktop.yml b/.github/workflows/build-desktop.yml index 05039c3982b..17748fa6a08 100644 --- a/.github/workflows/build-desktop.yml +++ b/.github/workflows/build-desktop.yml @@ -38,7 +38,7 @@ jobs: runs-on: ubuntu-22.04 steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Verify run: | @@ -67,7 +67,7 @@ jobs: working-directory: apps/desktop steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Get Package Version id: retrieve-version @@ -140,7 +140,7 @@ jobs: working-directory: apps/desktop steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Set up Node uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 @@ -249,7 +249,7 @@ jobs: NODE_OPTIONS: --max_old_space_size=4096 steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Set up Node uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 @@ -455,7 +455,7 @@ jobs: working-directory: apps/desktop steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Set up Node uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 @@ -619,7 +619,7 @@ jobs: working-directory: apps/desktop steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Set up Node uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 @@ -836,7 +836,7 @@ jobs: working-directory: apps/desktop steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Set up Node uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 @@ -1081,7 +1081,7 @@ jobs: working-directory: apps/desktop steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Set up Node uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 @@ -1270,7 +1270,7 @@ jobs: runs-on: ubuntu-22.04 steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Login to Azure uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 diff --git a/.github/workflows/build-web.yml b/.github/workflows/build-web.yml index 54e993edb33..4551a7baac8 100644 --- a/.github/workflows/build-web.yml +++ b/.github/workflows/build-web.yml @@ -45,7 +45,7 @@ jobs: node_version: ${{ steps.retrieve-node-version.outputs.node_version }} steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Get GitHub sha as version id: version @@ -91,7 +91,7 @@ jobs: steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Set up Node uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 @@ -157,7 +157,7 @@ jobs: _VERSION: ${{ needs.setup.outputs.version }} steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Check Branch to Publish env: @@ -234,7 +234,7 @@ jobs: run: echo "name=$_AZ_REGISTRY/${PROJECT_NAME}:${IMAGE_TAG}" >> $GITHUB_OUTPUT - name: Build Docker image - uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85 # v6.7.0 + uses: docker/build-push-action@32945a339266b759abcbdc89316275140b0fc960 # v6.8.0 with: context: apps/web file: apps/web/Dockerfile @@ -255,7 +255,7 @@ jobs: runs-on: ubuntu-22.04 steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Login to Azure uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml index 272b68139ac..b52ecc1c40a 100644 --- a/.github/workflows/chromatic.yml +++ b/.github/workflows/chromatic.yml @@ -25,7 +25,7 @@ jobs: steps: - name: Check out repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 @@ -57,7 +57,7 @@ jobs: run: npm run build-storybook:ci - name: Publish to Chromatic - uses: chromaui/action@c883154c39671e194613be2f09ff4d17bb95f1e6 # v11.10.3 + uses: chromaui/action@f4e60a7072abcac4203f4ca50613f28e199a52ba # v11.10.4 with: token: ${{ secrets.GITHUB_TOKEN }} projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} diff --git a/.github/workflows/crowdin-pull.yml b/.github/workflows/crowdin-pull.yml index 527dedb5a86..b319e5365f7 100644 --- a/.github/workflows/crowdin-pull.yml +++ b/.github/workflows/crowdin-pull.yml @@ -23,7 +23,7 @@ jobs: crowdin_project_id: "308189" steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Login to Azure uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 diff --git a/.github/workflows/deploy-web.yml b/.github/workflows/deploy-web.yml index 7551538b3a1..d0f791aa000 100644 --- a/.github/workflows/deploy-web.yml +++ b/.github/workflows/deploy-web.yml @@ -71,6 +71,7 @@ jobs: retrieve-secrets-keyvault: ${{ steps.config.outputs.retrieve-secrets-keyvault }} sync-utility: ${{ steps.config.outputs.sync-utility }} sync-delete-destination-files: ${{ steps.config.outputs.sync-delete-destination-files }} + slack-channel-name: ${{ steps.config.outputs.slack-channel-name }} steps: - name: Configure id: config @@ -86,6 +87,7 @@ jobs: echo "environment-artifact=web-*-cloud-QA.zip" >> $GITHUB_OUTPUT echo "environment-name=Web Vault - US QA Cloud" >> $GITHUB_OUTPUT echo "environment-url=http://vault.$ENV_NAME_LOWER.bitwarden.pw" >> $GITHUB_OUTPUT + echo "slack-channel-name=alerts-deploy-qa" >> $GITHUB_OUTPUT ;; "EUQA") echo "azure-login-creds=AZURE_KV_EU_QA_SERVICE_PRINCIPAL" >> $GITHUB_OUTPUT @@ -93,6 +95,7 @@ jobs: echo "environment-artifact=web-*-cloud-euqa.zip" >> $GITHUB_OUTPUT echo "environment-name=Web Vault - EU QA Cloud" >> $GITHUB_OUTPUT echo "environment-url=http://vault.$ENV_NAME_LOWER.bitwarden.pw" >> $GITHUB_OUTPUT + echo "slack-channel-name=alerts-deploy-qa" >> $GITHUB_OUTPUT ;; "USPROD") echo "azure-login-creds=AZURE_KV_US_PROD_SERVICE_PRINCIPAL" >> $GITHUB_OUTPUT @@ -100,6 +103,7 @@ jobs: echo "environment-artifact=web-*-cloud-COMMERCIAL.zip" >> $GITHUB_OUTPUT echo "environment-name=Web Vault - US Production Cloud" >> $GITHUB_OUTPUT echo "environment-url=http://vault.bitwarden.com" >> $GITHUB_OUTPUT + echo "slack-channel-name=alerts-deploy-prd" >> $GITHUB_OUTPUT ;; "EUPROD") echo "azure-login-creds=AZURE_KV_EU_PRD_SERVICE_PRINCIPAL" >> $GITHUB_OUTPUT @@ -107,6 +111,7 @@ jobs: echo "environment-artifact=web-*-cloud-euprd.zip" >> $GITHUB_OUTPUT echo "environment-name=Web Vault - EU Production Cloud" >> $GITHUB_OUTPUT echo "environment-url=http://vault.bitwarden.eu" >> $GITHUB_OUTPUT + echo "slack-channel-name=alerts-deploy-prd" >> $GITHUB_OUTPUT ;; "USDEV") echo "azure-login-creds=AZURE_KV_US_DEV_SERVICE_PRINCIPAL" >> $GITHUB_OUTPUT @@ -114,6 +119,7 @@ jobs: echo "environment-artifact=web-*-cloud-usdev.zip" >> $GITHUB_OUTPUT echo "environment-name=Web Vault - US Development Cloud" >> $GITHUB_OUTPUT echo "environment-url=http://vault.$ENV_NAME_LOWER.bitwarden.pw" >> $GITHUB_OUTPUT + echo "slack-channel-name=alerts-deploy-dev" >> $GITHUB_OUTPUT ;; esac # Set the sync utility to use for deployment to the environment (az-sync or azcopy) @@ -267,7 +273,7 @@ jobs: project: Clients environment: ${{ needs.setup.outputs.environment-name }} tag: ${{ inputs.branch-or-tag }} - slack-channel: alerts-deploy-qa + slack-channel: ${{ needs.setup.outputs.slack-channel-name }} event: 'start' commit-sha: ${{ needs.artifact-check.outputs.artifact-build-commit }} url: https://github.com/bitwarden/clients/actions/runs/${{ github.run_id }} diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 3f72d62214b..ad8c5dd40dc 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-22.04 steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Lint filenames (no capital characters) run: | diff --git a/.github/workflows/publish-cli.yml b/.github/workflows/publish-cli.yml index 6581e260900..f9c4b85e8ab 100644 --- a/.github/workflows/publish-cli.yml +++ b/.github/workflows/publish-cli.yml @@ -92,7 +92,7 @@ jobs: _PKG_VERSION: ${{ needs.setup.outputs.release-version }} steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Login to Azure uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 @@ -129,7 +129,7 @@ jobs: _PKG_VERSION: ${{ needs.setup.outputs.release-version }} steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Login to Azure uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 @@ -169,7 +169,7 @@ jobs: _PKG_VERSION: ${{ needs.setup.outputs.release-version }} steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Login to Azure uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 diff --git a/.github/workflows/publish-desktop.yml b/.github/workflows/publish-desktop.yml index d12072c7e6d..0816a86b1b5 100644 --- a/.github/workflows/publish-desktop.yml +++ b/.github/workflows/publish-desktop.yml @@ -184,7 +184,7 @@ jobs: _RELEASE_TAG: ${{ needs.setup.outputs.tag-name }} steps: - name: Checkout Repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Login to Azure uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 @@ -228,7 +228,7 @@ jobs: _RELEASE_TAG: ${{ needs.setup.outputs.tag-name }} steps: - name: Checkout Repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Print Environment run: | diff --git a/.github/workflows/publish-web.yml b/.github/workflows/publish-web.yml index 4409da93560..02a60ee4222 100644 --- a/.github/workflows/publish-web.yml +++ b/.github/workflows/publish-web.yml @@ -27,7 +27,7 @@ jobs: tag_version: ${{ steps.version.outputs.tag }} steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Branch check if: ${{ inputs.publish_type != 'Dry Run' }} @@ -67,7 +67,7 @@ jobs: echo "Github Release Option: $_RELEASE_OPTION" - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 ########## ACR ########## - name: Login to Azure - PROD Subscription diff --git a/.github/workflows/release-browser.yml b/.github/workflows/release-browser.yml index 2811b23af9b..f190889414b 100644 --- a/.github/workflows/release-browser.yml +++ b/.github/workflows/release-browser.yml @@ -27,7 +27,7 @@ jobs: release-version: ${{ steps.version.outputs.version }} steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Branch check if: ${{ github.event.inputs.release_type != 'Dry Run' }} @@ -56,7 +56,7 @@ jobs: needs: setup steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Testing locales - extName length run: | diff --git a/.github/workflows/release-cli.yml b/.github/workflows/release-cli.yml index cd450b2cd79..8f5123b50b2 100644 --- a/.github/workflows/release-cli.yml +++ b/.github/workflows/release-cli.yml @@ -27,7 +27,7 @@ jobs: release-version: ${{ steps.version.outputs.version }} steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Branch check if: ${{ inputs.release_type != 'Dry Run' }} diff --git a/.github/workflows/release-desktop-beta.yml b/.github/workflows/release-desktop-beta.yml index 80b1ae092c6..23b06d71dd3 100644 --- a/.github/workflows/release-desktop-beta.yml +++ b/.github/workflows/release-desktop-beta.yml @@ -24,7 +24,7 @@ jobs: node_version: ${{ steps.retrieve-node-version.outputs.node_version }} steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Branch check run: | @@ -125,7 +125,7 @@ jobs: working-directory: apps/desktop steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 with: ref: ${{ needs.setup.outputs.branch-name }} @@ -215,7 +215,7 @@ jobs: NODE_OPTIONS: --max_old_space_size=4096 steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 with: ref: ${{ needs.setup.outputs.branch-name }} @@ -404,7 +404,7 @@ jobs: working-directory: apps/desktop steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 with: ref: ${{ needs.setup.outputs.branch-name }} @@ -538,7 +538,7 @@ jobs: working-directory: apps/desktop steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 with: ref: ${{ needs.setup.outputs.branch-name }} @@ -751,7 +751,7 @@ jobs: working-directory: apps/desktop steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 with: ref: ${{ needs.setup.outputs.branch-name }} @@ -1011,7 +1011,7 @@ jobs: - release steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Setup git config run: | diff --git a/.github/workflows/release-desktop.yml b/.github/workflows/release-desktop.yml index 5b75460ef92..d69c15559b3 100644 --- a/.github/workflows/release-desktop.yml +++ b/.github/workflows/release-desktop.yml @@ -27,7 +27,7 @@ jobs: release-channel: ${{ steps.release-channel.outputs.channel }} steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Branch check if: ${{ github.event.inputs.release_type != 'Dry Run' }} diff --git a/.github/workflows/release-web.yml b/.github/workflows/release-web.yml index 982e3867585..92f5701889b 100644 --- a/.github/workflows/release-web.yml +++ b/.github/workflows/release-web.yml @@ -24,7 +24,7 @@ jobs: tag_version: ${{ steps.version.outputs.tag }} steps: - name: Checkout repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Branch check if: ${{ github.event.inputs.release_type != 'Dry Run' }} diff --git a/.github/workflows/scan.yml b/.github/workflows/scan.yml index 2320bae72f3..f15a14dd117 100644 --- a/.github/workflows/scan.yml +++ b/.github/workflows/scan.yml @@ -27,7 +27,7 @@ jobs: steps: - name: Check out repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 with: ref: ${{ github.event.pull_request.head.sha }} @@ -47,7 +47,7 @@ jobs: --output-path . ${{ env.INCREMENTAL }} - name: Upload Checkmarx results to GitHub - uses: github/codeql-action/upload-sarif@294a9d92911152fe08befb9ec03e240add280cb3 # v3.26.8 + uses: github/codeql-action/upload-sarif@461ef6c76dfe95d5c364de2f431ddbd31a417628 # v3.26.9 with: sarif_file: cx_result.sarif @@ -61,7 +61,7 @@ jobs: steps: - name: Check out repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 with: fetch-depth: 0 ref: ${{ github.event.pull_request.head.sha }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fbe0c0a798b..fd378213c9f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -41,7 +41,7 @@ jobs: steps: - name: Check out repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Get Node Version id: retrieve-node-version @@ -121,7 +121,7 @@ jobs: sudo apt-get install -y gnome-keyring dbus-x11 - name: Check out repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Build working-directory: ./apps/desktop/desktop_native diff --git a/.github/workflows/version-bump.yml b/.github/workflows/version-bump.yml index fea68161bab..d18097ee1c2 100644 --- a/.github/workflows/version-bump.yml +++ b/.github/workflows/version-bump.yml @@ -58,7 +58,7 @@ jobs: fi - name: Checkout Branch - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 with: ref: main @@ -533,7 +533,7 @@ jobs: runs-on: ubuntu-22.04 steps: - name: Checkout Branch - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 with: ref: main diff --git a/apps/browser/src/_locales/ar/messages.json b/apps/browser/src/_locales/ar/messages.json index 1b59a7805e7..95b3922d34e 100644 --- a/apps/browser/src/_locales/ar/messages.json +++ b/apps/browser/src/_locales/ar/messages.json @@ -2374,6 +2374,10 @@ "message": "Are you sure you want to delete this Send?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send saved", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "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." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "In order to choose a file using Safari, pop out to a new window by clicking this banner." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "قبل أن تبدأ" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Add account" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/az/messages.json b/apps/browser/src/_locales/az/messages.json index 795cd371232..98bcff7e828 100644 --- a/apps/browser/src/_locales/az/messages.json +++ b/apps/browser/src/_locales/az/messages.json @@ -490,7 +490,7 @@ "description": "Label for the avoid ambiguous characters checkbox." }, "generatorPolicyInEffect": { - "message": "Enterprise policy requirements have been applied to your generator options.", + "message": "Müəssisə siyasət tələbləri, yaradıcı seçimlərinizə tətbiq edildi.", "description": "Indicates that a policy limits the credential generator screen." }, "searchVault": { @@ -2374,6 +2374,10 @@ "message": "Bu \"Send\"i silmək istədiyinizə əminsiniz?", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "deleteSendPermanentConfirmation": { + "message": "Bu Send-i həmişəlik silmək istədiyinizə əminsiniz?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "\"Send\"ə düzəliş et", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "\"Send\" saxlanıldı", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "Bir fayl seçmək üçün (mümkünsə) yan çubuqdakı uzantını açın və ya bu bannerə klikləyərək yeni bir pəncərədə açın." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "Safari istifadə edərək bir fayl seçmək üçün bu bannerə klikləyərək yeni bir pəncərədə açın." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Başlamazdan əvvəl" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Animasiyaları fəallaşdır" }, + "showAnimations": { + "message": "Animasiyaları göstər" + }, "addAccount": { "message": "Hesab əlavə et" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "Bu elementə düzəliş etmə icazəniz yoxdur" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/be/messages.json b/apps/browser/src/_locales/be/messages.json index 384036840d3..19f87b92fa9 100644 --- a/apps/browser/src/_locales/be/messages.json +++ b/apps/browser/src/_locales/be/messages.json @@ -2374,6 +2374,10 @@ "message": "Вы сапраўды хочаце выдаліць гэты Send?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Рэдагаваць Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send адрэдагаваны", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "Для выбару файла неабходна адкрыць пашырэнне на бакавой панэлі (калі ёсць такая магчымасць) або перайсці ў новае акно, націснуўшы на гэты банэр." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "Для выбару файла з выкарыстаннем Safari неабходна перайсці ў новае акно, націснуўшы на гэты банэр." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Перад тым, як пачаць" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Add account" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/bg/messages.json b/apps/browser/src/_locales/bg/messages.json index df91be9ff49..281819988a4 100644 --- a/apps/browser/src/_locales/bg/messages.json +++ b/apps/browser/src/_locales/bg/messages.json @@ -490,7 +490,7 @@ "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": { @@ -2374,6 +2374,10 @@ "message": "Сигурни ли сте, че искате да изтриете това изпращане?", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "deleteSendPermanentConfirmation": { + "message": "Наистина ли искате да изтриете завинаги това Изпращане?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Редактиране на изпращане", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Редактирано изпращане", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Отваряне на разширението в нов прозорец?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendFilePopoutDialogDesc": { + "message": "За да създадете файлово Изпращане, трябва да отворите разширението в нов прозорец.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "За да изберете файл, отворете разширението в страничната лента (ако е възможно) или в нов прозорец, като натиснете това съобщение." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "За да изберете файл в Safari, отворете разширението в нов прозорец, като натиснете това съобщение." }, + "popOut": { + "message": "Отваряне в прозорец" + }, "sendFileCalloutHeader": { "message": "Преди да почнете" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Включване на анимациите" }, + "showAnimations": { + "message": "Показване на анимации" + }, "addAccount": { "message": "Добавяне на регистрация" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "Нямате право за редактиране на този елемент" + }, + "authenticating": { + "message": "Удостоверяване" } } diff --git a/apps/browser/src/_locales/bn/messages.json b/apps/browser/src/_locales/bn/messages.json index 5d8ea4ee404..a56b791e32e 100644 --- a/apps/browser/src/_locales/bn/messages.json +++ b/apps/browser/src/_locales/bn/messages.json @@ -2374,6 +2374,10 @@ "message": "Are you sure you want to delete this Send?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send saved", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "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." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "In order to choose a file using Safari, pop out to a new window by clicking this banner." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Before you start" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Add account" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/bs/messages.json b/apps/browser/src/_locales/bs/messages.json index 6f2a9be6185..7293b697ee8 100644 --- a/apps/browser/src/_locales/bs/messages.json +++ b/apps/browser/src/_locales/bs/messages.json @@ -2374,6 +2374,10 @@ "message": "Are you sure you want to delete this Send?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send saved", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "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." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "In order to choose a file using Safari, pop out to a new window by clicking this banner." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Before you start" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Add account" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/ca/messages.json b/apps/browser/src/_locales/ca/messages.json index 7c1cc4b3367..94fd992a01f 100644 --- a/apps/browser/src/_locales/ca/messages.json +++ b/apps/browser/src/_locales/ca/messages.json @@ -2374,6 +2374,10 @@ "message": "Esteu segur que voleu suprimir aquest Send?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Edita Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send guardat", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "Per triar un fitxer, obriu l'extensió a la barra lateral (si és possible) o eixiu a una finestra nova fent clic a aquest bàner." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "Per triar un fitxer mitjançant Safari, eixiu a una finestra nova fent clic en aquest bàner." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Abans de començar" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Afig compte" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/cs/messages.json b/apps/browser/src/_locales/cs/messages.json index cee00a55ffe..1ddb21122e2 100644 --- a/apps/browser/src/_locales/cs/messages.json +++ b/apps/browser/src/_locales/cs/messages.json @@ -490,7 +490,7 @@ "description": "Label for the avoid ambiguous characters checkbox." }, "generatorPolicyInEffect": { - "message": "Enterprise policy requirements have been applied to your generator options.", + "message": "Na volby generátoru byly uplatněny požadavky podnikových zásad.", "description": "Indicates that a policy limits the credential generator screen." }, "searchVault": { @@ -2374,6 +2374,10 @@ "message": "Opravdu chcete smazat tento Send?", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "deleteSendPermanentConfirmation": { + "message": "Opravdu chcete tento Send trvale smazat?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Upravit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send upraven", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Zobrazit rozšíření v novém okně?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendFilePopoutDialogDesc": { + "message": "Chcete-li vytvořit Send souboru, musí se zobrazit rozšíření v novém okně.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "Chcete-li vybrat soubor, otevřete rozšíření v postranním panelu (pokud je to možné) nebo jej otevřete v novém okně klepnutím na tento banner." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "Chcete-li vybrat soubor pomocí prohlížeče Safari, otevřete nové okno klepnutím na tento banner." }, + "popOut": { + "message": "Nové okno" + }, "sendFileCalloutHeader": { "message": "Než začnete" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Povolit animace" }, + "showAnimations": { + "message": "Zobrazit animaci" + }, "addAccount": { "message": "Přidat účet" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "Nemáte oprávnění upravit tuto položku" + }, + "authenticating": { + "message": "Ověřování" } } diff --git a/apps/browser/src/_locales/cy/messages.json b/apps/browser/src/_locales/cy/messages.json index 476319b3709..b9cb28d4b88 100644 --- a/apps/browser/src/_locales/cy/messages.json +++ b/apps/browser/src/_locales/cy/messages.json @@ -2374,6 +2374,10 @@ "message": "Are you sure you want to delete this Send?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send saved", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "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." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "In order to choose a file using Safari, pop out to a new window by clicking this banner." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Cyn i chi ddechrau" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Ychwanegu cyfrif" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/da/messages.json b/apps/browser/src/_locales/da/messages.json index e5c2c38c078..1fec98793d3 100644 --- a/apps/browser/src/_locales/da/messages.json +++ b/apps/browser/src/_locales/da/messages.json @@ -490,7 +490,7 @@ "description": "Label for the avoid ambiguous characters checkbox." }, "generatorPolicyInEffect": { - "message": "Enterprise policy requirements have been applied to your generator options.", + "message": "Virksomhedspolitikkrav gør sig gældende på generatorvalgmulighder.", "description": "Indicates that a policy limits the credential generator screen." }, "searchVault": { @@ -2374,6 +2374,10 @@ "message": "Er du sikker på, at du vil slette denne Send?", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "deleteSendPermanentConfirmation": { + "message": "Sikker på, at denne Send skal slettes permanent?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Redigér Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send gemt", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop udvidelsen ud?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendFilePopoutDialogDesc": { + "message": "For at oprette en fil-Send, skal udvidelsen poppes ud til et nyt vindue.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "For at vælge en fil, åben udvidelsen i sidepanelet (om muligt) eller pop ud til et nyt vindue ved at klikke på dette banner." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "For at vælge en fil i Safari skal du åbne i et nyt vindue ved at klikke på dette banner." }, + "popOut": { + "message": "Pop ud" + }, "sendFileCalloutHeader": { "message": "Før du starter" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Aktivér animationer" }, + "showAnimations": { + "message": "Vis animationer" + }, "addAccount": { "message": "Tilføj konto" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "Ingen tilladelse til at redigere dette emne" + }, + "authenticating": { + "message": "Godkender" } } diff --git a/apps/browser/src/_locales/de/messages.json b/apps/browser/src/_locales/de/messages.json index dc027fd44a5..cf634a14bfb 100644 --- a/apps/browser/src/_locales/de/messages.json +++ b/apps/browser/src/_locales/de/messages.json @@ -490,7 +490,7 @@ "description": "Label for the avoid ambiguous characters checkbox." }, "generatorPolicyInEffect": { - "message": "Enterprise policy requirements have been applied to your generator options.", + "message": "Die Unternehmensrichtlinien-Anforderungen wurden auf deine Generator-Optionen angewendet.", "description": "Indicates that a policy limits the credential generator screen." }, "searchVault": { @@ -2374,6 +2374,10 @@ "message": "Bist du sicher, dass du dieses Send löschen möchtest?", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "deleteSendPermanentConfirmation": { + "message": "Bist du sicher, dass du dieses Send dauerhaft löschen möchtest?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Send bearbeiten", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send gespeichert", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "Um eine Datei auszuwählen, öffne die Erweiterung in der Sidebar (falls möglich) oder öffne sie in einem neuem Fenster, indem du auf dieses Banner klickst." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "Um eine Datei mit Safari auszuwählen, öffne ein neues Fenster, indem du auf dieses Banner klickst." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Bevor du beginnst" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Animationen aktivieren" }, + "showAnimations": { + "message": "Animationen anzeigen" + }, "addAccount": { "message": "Konto hinzufügen" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "Du bist nicht berechtigt, diesen Eintrag zu bearbeiten" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/el/messages.json b/apps/browser/src/_locales/el/messages.json index 7d0054267b6..ece0a8badff 100644 --- a/apps/browser/src/_locales/el/messages.json +++ b/apps/browser/src/_locales/el/messages.json @@ -3,7 +3,7 @@ "message": "Bitwarden" }, "extName": { - "message": "Bitwarden Διαχειριστής Κωδικών Πρόσβασης", + "message": "Bitwarden: Διαχείριση κωδικών πρόσβασης", "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { @@ -198,13 +198,13 @@ "message": "Email λογαριασμού" }, "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": "Εισαγάγετε τη διεύθυνση email του λογαριασμού σας και θα σας αποσταλεί η υπόδειξη για τον κωδικό πρόσβασης" }, "passwordHint": { "message": "Υπόδειξη κωδικού πρόσβασης" @@ -490,7 +490,7 @@ "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": { @@ -584,7 +584,7 @@ "message": "Χρονικό όριο λήξης συνεδρίας" }, "vaultTimeoutHeader": { - "message": "Vault timeout" + "message": "Χρονικό όριο κρύπτης" }, "otherOptions": { "message": "Άλλες επιλογές" @@ -627,7 +627,7 @@ "message": "Χρόνος Λήξης Vault" }, "vaultTimeout1": { - "message": "Timeout" + "message": "Λήξη χρονικού ορίου" }, "lockNow": { "message": "Κλείδωμα Τώρα" @@ -830,7 +830,7 @@ "message": "Η σύνδεση δύο βημάτων καθιστά πιο ασφαλή τον λογαριασμό σας, απαιτώντας να επαληθεύσετε τη συνδεσή σας με μια άλλη συσκευή, όπως ένα κλειδί ασφαλείας, μία εφαρμογή επαλήθευσης, ένα μήνυμα SMS, μία τηλεφωνική κλήση ή ένα μήνυμα ηλ. ταχυδρομείου. Μπορείτε να ενεργοποιήσετε τη σύνδεση δύο βημάτων στο διαδικτυακό θυσαυ/κιο bitwarden.com. Θέλετε να επισκεφθείτε την ιστοσελίδα τώρα;" }, "twoStepLoginConfirmationContent": { - "message": "Make your account more secure by setting up two-step login in the Bitwarden web app." + "message": "Κάντε τον λογαριασμό σας πιο ασφαλή με τη ρύθμιση της σύνδεσης δύο βημάτων στη διαδικτυακή εφαρμογή του Bitwarden." }, "twoStepLoginConfirmationTitle": { "message": "Συνέχεια στη διαδικτυακή εφαρμογή;" @@ -1849,10 +1849,10 @@ "message": "Διαγραφή ιστορικού" }, "noPasswordsToShow": { - "message": "No passwords to show" + "message": "Δεν υπάρχουν κωδικοί πρόσβασης για εμφάνιση" }, "noRecentlyGeneratedPassword": { - "message": "You haven't generated a password recently" + "message": "Δεν έχετε δημιουργήσει πρόσφατα έναν κωδικό πρόσβασης" }, "remove": { "message": "Αφαίρεση" @@ -1922,7 +1922,7 @@ "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 αντί του κύριου κωδικού πρόσβασης. Αν αποσυνδεθείτε εντελώς από το Bitwarden, θα γίνει επαναφορά του PIN σας." }, "pinRequired": { "message": "Απαιτείται κωδικός PIN." @@ -1946,7 +1946,7 @@ "message": "Κλείδωμα με κύριο κωδικό πρόσβασης στην επανεκκίνηση του προγράμματος περιήγησης" }, "lockWithMasterPassOnRestart1": { - "message": "Require master password on browser restart" + "message": "Απαίτηση κύριου κωδικού πρόσβασης κατά την επανεκκίνηση του προγράμματος περιήγησης" }, "selectOneCollection": { "message": "Πρέπει να επιλέξετε τουλάχιστον μία συλλογή." @@ -1987,7 +1987,7 @@ "message": "Ενέργεια Χρόνου Λήξης Vault" }, "vaultTimeoutAction1": { - "message": "Timeout action" + "message": "Ενέργεια κατά τη λήξη χρονικού ορίου" }, "lock": { "message": "Κλείδωμα", @@ -2278,7 +2278,7 @@ "message": "Περιορισμός προβολών" }, "limitSendViewsHint": { - "message": "No one can view this Send after the limit is reached.", + "message": "Κανένας δεν μπορεί να προβάλει αυτό το Send μετά το πέρας του ορίου.", "description": "Displayed under the limit views field on Send" }, "limitSendViewsCount": { @@ -2296,7 +2296,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", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "searchSends": { @@ -2311,7 +2311,7 @@ "message": "Κείμενο" }, "sendTypeTextToShare": { - "message": "Text to share" + "message": "Κείμενο προς κοινοποίηση" }, "sendTypeFile": { "message": "Αρχείο" @@ -2321,7 +2321,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": "Απόκρυψη κειμένου από προεπιλογή" }, "maxAccessCountReached": { "message": "Φτάσατε στον μέγιστο αριθμό πρόσβασης", @@ -2374,6 +2374,10 @@ "message": "Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτό το Send;", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "deleteSendPermanentConfirmation": { + "message": "Θέλετε σίγουρα να διαγράψετε οριστικά αυτό το Send;", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Επεξεργασία Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2397,7 +2401,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "deletionDateDescV2": { - "message": "The Send will be permanently deleted on this date.", + "message": "Το Send θα διαγραφεί οριστικά σε αυτήν την ημερομηνία.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "expirationDate": { @@ -2434,7 +2438,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendPasswordDescV2": { - "message": "Require this password to view the Send.", + "message": "Να απαιτείται αυτός ο κωδικός πρόσβασης για την προβολή του Send.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendNotesDesc": { @@ -2500,6 +2504,14 @@ "message": "Το Send αποθηκεύτηκε", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "Για να επιλέξετε ένα αρχείο, ανοίξτε την επέκταση στην πλαϊνή μπάρα (αν είναι δυνατόν) ή βγείτε σε ένα νέο παράθυρο κάνοντας κλικ σε αυτή τη διαφήμιση." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "Για να επιλέξετε ένα αρχείο χρησιμοποιώντας το Safari, βγαίνετε σε ένα νέο παράθυρο κάνοντας κλικ σε αυτή τη διαφήμιση." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Πριν ξεκινήσετε" }, @@ -2543,7 +2558,7 @@ "message": "Απόκρυψη της διεύθυνσης email μου από τους παραλήπτες." }, "hideYourEmail": { - "message": "Hide your email address from viewers." + "message": "Απόκρυψη της διεύθυνσης email σας από τους θεατές." }, "sendOptionsPolicyInEffect": { "message": "Μία ή περισσότερες οργανωτικές πολιτικές επηρεάζουν τις επιλογές send σας." @@ -2613,7 +2628,7 @@ "message": "Λεπτά" }, "vaultTimeoutPolicyAffectingOptions": { - "message": "Enterprise policy requirements have been applied to your timeout options" + "message": "Οι απαιτήσεις της εταιρικής πολιτικής έχουν εφαρμοστεί στις επιλογές χρονικού ορίου σας" }, "vaultTimeoutPolicyInEffect": { "message": "Οι πολιτικές του οργανισμού σας επηρεάζουν το χρονικό όριο vault σας. Το μέγιστο επιτρεπόμενο Χρονικό όριο Vault είναι $HOURS$ ώρα(ες) και $MINUTES$ λεπτό(ά)", @@ -2629,7 +2644,7 @@ } }, "vaultTimeoutPolicyInEffect1": { - "message": "$HOURS$ hour(s) and $MINUTES$ minute(s) maximum.", + "message": "$HOURS$ ώρα(ες) και $MINUTES$ λεπτό(ά) το πολύ.", "placeholders": { "hours": { "content": "$1", @@ -2642,7 +2657,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", @@ -3630,7 +3645,7 @@ "message": "Δεν έχετε στοιχεία σύνδεσης που να συνδυάζονται με αυτόν τον ιστότοπο." }, "noMatchingLoginsForSite": { - "message": "No matching logins for this site" + "message": "Δεν υπάρχουν αντίστοιχες συνδέσεις για αυτόν τον ιστότοπο" }, "confirm": { "message": "Επιβεβαίωση" @@ -3642,10 +3657,10 @@ "message": "Αποθήκευση κλειδιού πρόσβασης ως νέα σύνδεση" }, "chooseCipherForPasskeySave": { - "message": "Choose a login to save this passkey to" + "message": "Επιλέξτε μια σύνδεση για την αποθήκευση αυτού του κλειδιού πρόσβασης" }, "chooseCipherForPasskeyAuth": { - "message": "Choose a passkey to log in with" + "message": "Επιλέξτε ένα κλειδί πρόσβασης για σύνδεση" }, "passkeyItem": { "message": "Αντικείμενο κλειδιού πρόσβασης" @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Ενεργοποίηση κινούμενων εικόνων" }, + "showAnimations": { + "message": "Εμφάνιση εφέ κίνησης" + }, "addAccount": { "message": "Προσθήκη λογαριασμού" }, @@ -4444,13 +4462,13 @@ "message": "Επανάληψη" }, "vaultCustomTimeoutMinimum": { - "message": "Minimum custom timeout is 1 minute." + "message": "Το ελάχιστο προσαρμοσμένο χρονικό όριο λήξης είναι 1 λεπτό." }, "additionalContentAvailable": { "message": "Διατίθεται πρόσθετο περιεχόμενο" }, "fileSavedToDevice": { - "message": "File saved to device. Manage from your device downloads." + "message": "Το αρχείο αποθηκεύτηκε στη συσκευή. Διαχειριστείτε το από τις λήψεις της συσκευής σας." }, "showCharacterCount": { "message": "Εμφάνιση αριθμού χαρακτήρων" @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "Δεν έχετε δικαίωμα να επεξεργαστείτε αυτό το αντικείμενο" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index 8c08caec353..5203edf0a44 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -2504,6 +2504,14 @@ "message": "Send saved", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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.", + "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." }, @@ -2513,6 +2521,9 @@ "sendSafariFileWarning": { "message": "In order to choose a file using Safari, pop out to a new window by clicking this banner." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Before you start" }, @@ -4485,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/en_GB/messages.json b/apps/browser/src/_locales/en_GB/messages.json index e8fcd3de2c9..cf37e70fb89 100644 --- a/apps/browser/src/_locales/en_GB/messages.json +++ b/apps/browser/src/_locales/en_GB/messages.json @@ -2374,6 +2374,10 @@ "message": "Are you sure you want to delete this Send?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send saved", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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.", + "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." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "In order to choose a file using Safari, pop out to a new window by clicking this banner." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Before you start" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Add account" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/en_IN/messages.json b/apps/browser/src/_locales/en_IN/messages.json index c4d7128eafa..e87d5a83e8c 100644 --- a/apps/browser/src/_locales/en_IN/messages.json +++ b/apps/browser/src/_locales/en_IN/messages.json @@ -2374,6 +2374,10 @@ "message": "Are you sure you want to delete this Send?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Edited Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "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." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "In order to choose a file using Safari, pop out to a new window by clicking this banner." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Before you start" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Add account" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/es/messages.json b/apps/browser/src/_locales/es/messages.json index 800f7baab0d..bc9ed5547db 100644 --- a/apps/browser/src/_locales/es/messages.json +++ b/apps/browser/src/_locales/es/messages.json @@ -2374,6 +2374,10 @@ "message": "¿Está seguro de que desea eliminar este Send?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Editar Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Envío editado", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "Para elegir un archivo, abra la extensión en la barra lateral (si es posible) o salga a una nueva ventana haciendo clic en este anouncio." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "Para elegir un archivo usando Safari, salga a una nueva ventana haciendo clic en este anouncio." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Antes de empezar" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Activar animaciones" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Añadir cuenta" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "No tiene permiso de editar este elemento" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/et/messages.json b/apps/browser/src/_locales/et/messages.json index d9f64ecc041..0b87fbdd4ac 100644 --- a/apps/browser/src/_locales/et/messages.json +++ b/apps/browser/src/_locales/et/messages.json @@ -2374,6 +2374,10 @@ "message": "Soovid tõesti selle Sendi kustutada?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Muuda Sendi", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Muudetud", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "Faili valimiseks ava rakendus külgribal (kui see on võimalik) või kasuta hüpikakent, klikkides sellel bänneril." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "Faili valimiseks läbi Safari kasuta Bitwardeni hüpikakent (klikkides sellel bänneril)." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Enne alustamist" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Add account" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/eu/messages.json b/apps/browser/src/_locales/eu/messages.json index 88f2348d5ff..7591a4b5d32 100644 --- a/apps/browser/src/_locales/eu/messages.json +++ b/apps/browser/src/_locales/eu/messages.json @@ -2374,6 +2374,10 @@ "message": "Ziur al zaude Send hau ezabatu nahi duzula?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Editatu Send-a", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send-a editatua", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "Fitxategi bat aukeratzeko, ireki gehigarria alboko barran (ahal bada) edo atera leiho berri batera banner honetan klik eginez." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "Safari erabiliz fitxategi bat aukeratzeko, ireki beste leiho bat banner hau sakatuz." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Hasi aurretik" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Add account" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/fa/messages.json b/apps/browser/src/_locales/fa/messages.json index a152c8edd53..fa0c9ff0c1a 100644 --- a/apps/browser/src/_locales/fa/messages.json +++ b/apps/browser/src/_locales/fa/messages.json @@ -2374,6 +2374,10 @@ "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "ویرایش ارسال", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "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?", + "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 te extension to a new window.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "برای انتخاب پرونده، پسوند را در نوار کناری باز کنید (در صورت امکان) یا با کلیک بر روی این بنر پنجره جدیدی باز کنید." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "برای انتخاب پرونده ای با استفاده از Safari، با کلیک روی این بنر پنجره جدیدی باز کنید." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "قبل از اینکه شروع کنی" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Add account" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/fi/messages.json b/apps/browser/src/_locales/fi/messages.json index 9d152bc53a3..aca9c6738aa 100644 --- a/apps/browser/src/_locales/fi/messages.json +++ b/apps/browser/src/_locales/fi/messages.json @@ -2374,6 +2374,10 @@ "message": "Haluatko varmasti poistaa Sendin?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Muokkaa Sendiä", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send tallennettiin", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "Jotta voit valita tiedoston, avaa laajennus sivupalkkiin (jos mahdollista) tai erilliseen ikkunaan klikkaamalla tätä banneria." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "Jotta voit valita tiedoston käyttäen Safaria, avaa laajennus erilliseen ikkunaan klikkaamalla tätä banneria." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Ennen kuin aloitat" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Käytä animaatioita" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Lisää tili" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "Sinulla ei ole oikeutta muokata tätä kohdetta" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/fil/messages.json b/apps/browser/src/_locales/fil/messages.json index f69cbf71977..04a30a0d0e4 100644 --- a/apps/browser/src/_locales/fil/messages.json +++ b/apps/browser/src/_locales/fil/messages.json @@ -2374,6 +2374,10 @@ "message": "Sigurado ka bang gusto mo na i-delete ang Ipadala na ito?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "I-edit ang Ipadala", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Ipadala na nai-save", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "Upang pumili ng isang file, buksan ang extension sa sidebar (kung posible) o bumalik sa isang bagong window sa pamamagitan ng pag-click sa banner na ito." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "Upang pumili ng isang file gamit ang Safari, bumalik sa isang bagong window sa pamamagitan ng pag-click sa banner na ito." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Bago ka magsimula" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Add account" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/fr/messages.json b/apps/browser/src/_locales/fr/messages.json index 42b60a5f43a..8eb51c6eaf3 100644 --- a/apps/browser/src/_locales/fr/messages.json +++ b/apps/browser/src/_locales/fr/messages.json @@ -490,7 +490,7 @@ "description": "Label for the avoid ambiguous characters checkbox." }, "generatorPolicyInEffect": { - "message": "Enterprise policy requirements have been applied to your generator options.", + "message": "Les exigences de la politique d'entreprise ont été appliquées à vos options de générateur.", "description": "Indicates that a policy limits the credential generator screen." }, "searchVault": { @@ -2374,6 +2374,10 @@ "message": "Êtes-vous sûr de vouloir supprimer ce Send ?", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "deleteSendPermanentConfirmation": { + "message": "Êtes-vous sûr de vouloir supprimer définitivement ce Send ?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Modifier le Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send sauvegardé", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Détacher l'extension ?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendFilePopoutDialogDesc": { + "message": "Pour créer un envoi de fichier Send, vous devez détacher l'extension dans une nouvelle fenêtre.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "Pour choisir un fichier, ouvrez l'extension dans la barre latérale (si possible) ou ouvrez une nouvelle fenêtre en cliquant sur cette bannière." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "Pour choisir un fichier avec Safari, ouvrez une nouvelle fenêtre en cliquant sur cette bannière." }, + "popOut": { + "message": "Détacher" + }, "sendFileCalloutHeader": { "message": "Avant de commencer" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Activer les animations" }, + "showAnimations": { + "message": "Afficher les animations" + }, "addAccount": { "message": "Ajouter un compte" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "Vous n'êtes pas autorisé à modifier cet élément" + }, + "authenticating": { + "message": "Authentification" } } diff --git a/apps/browser/src/_locales/gl/messages.json b/apps/browser/src/_locales/gl/messages.json index 93b63919311..f51068e8229 100644 --- a/apps/browser/src/_locales/gl/messages.json +++ b/apps/browser/src/_locales/gl/messages.json @@ -2374,6 +2374,10 @@ "message": "Are you sure you want to delete this Send?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Editar Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send gardado", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "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." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "In order to choose a file using Safari, pop out to a new window by clicking this banner." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Before you start" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Add account" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/he/messages.json b/apps/browser/src/_locales/he/messages.json index 9b5ce585e41..5643edfc3c0 100644 --- a/apps/browser/src/_locales/he/messages.json +++ b/apps/browser/src/_locales/he/messages.json @@ -2374,6 +2374,10 @@ "message": "Are you sure you want to delete this Send?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send saved", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "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." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "In order to choose a file using Safari, pop out to a new window by clicking this banner." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Before you start" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Add account" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/hi/messages.json b/apps/browser/src/_locales/hi/messages.json index 3e00e16273e..df53d65a00d 100644 --- a/apps/browser/src/_locales/hi/messages.json +++ b/apps/browser/src/_locales/hi/messages.json @@ -490,7 +490,7 @@ "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": { @@ -2374,6 +2374,10 @@ "message": "क्या आप वाकई इस Send को मिटाना चाहते हैं?", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "deleteSendPermanentConfirmation": { + "message": "क्या आप इस प्रेषित संदेश को स्थायी रूप से हटाना चाहते हैं?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "एडिट Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "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?", + "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 te extension to a new window.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "फ़ाइल चुनने के लिए, साइडबार (यदि संभव हो) में एक्सटेंशन खोलें या इस बैनर पर क्लिक करके एक नई विंडो को पॉप आउट करें।" }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "सफारी का उपयोग करके फ़ाइल चुनने के लिए, इस बैनर पर क्लिक करके एक नई विंडो को पॉप आउट करें।" }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "शुरू करने से पहले" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "एनिमेशन दिखाएं" + }, "addAccount": { "message": "Add account" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/hr/messages.json b/apps/browser/src/_locales/hr/messages.json index 1d999a0f9b2..1dcc4861b72 100644 --- a/apps/browser/src/_locales/hr/messages.json +++ b/apps/browser/src/_locales/hr/messages.json @@ -2374,6 +2374,10 @@ "message": "Sigurno želiš izbrisati ovaj Send?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Uredi Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send spremljen", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "Za odabir datoteke, otvori proširenje u bočnoj traci (ako je moguće) ili u iskočnom prozoru klikom na ovu poruku." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "Za odabir datoteke u Safariju, otvori iskočni prozor klikom na ovu poruku." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Prije početka" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Omogući animacije" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Dodaj račun" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "Nemaš prava za uređivanje ove stavke" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/hu/messages.json b/apps/browser/src/_locales/hu/messages.json index 41da93a06cf..742938e154d 100644 --- a/apps/browser/src/_locales/hu/messages.json +++ b/apps/browser/src/_locales/hu/messages.json @@ -490,7 +490,7 @@ "description": "Label for the avoid ambiguous characters checkbox." }, "generatorPolicyInEffect": { - "message": "Enterprise policy requirements have been applied to your generator options.", + "message": "A vállalati házirend követelményei kerülnek alkalmazásra a generátor beállításaira.", "description": "Indicates that a policy limits the credential generator screen." }, "searchVault": { @@ -2374,6 +2374,10 @@ "message": "Biztosan törlésre kerüljön ez a Send?", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "deleteSendPermanentConfirmation": { + "message": "Biztosan véglegesen törlésre kerüljön ez a Send elem?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Send szerkesztése", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "A Send mentésre került.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Bővítmény átthelyezése?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendFilePopoutDialogDesc": { + "message": "A Send fájl létrehozásához át kell helyezni a bővítményt egy új ablakba.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "A fájl kiválasztásához nyissuk meg a kiterjesztést az oldalsávon (ha lehetséges) vagy kattintsunk erre a sávra új ablak felbukkanásához." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "A fájl kiválasztásához Safariban kattintsunk erre a hirdetőtáblára kattintva új ablak nyílik meg." }, + "popOut": { + "message": "Áthelyezés" + }, "sendFileCalloutHeader": { "message": "Mielőtt belevágnánk" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Animációk engedélyezése" }, + "showAnimations": { + "message": "Animációk megjelenítése" + }, "addAccount": { "message": "Fiók hozzáadása" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "Nincs jogosulltság ezen elem szerkesztéséheu." + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/id/messages.json b/apps/browser/src/_locales/id/messages.json index a5aa720c0b5..e05fb18d861 100644 --- a/apps/browser/src/_locales/id/messages.json +++ b/apps/browser/src/_locales/id/messages.json @@ -2374,6 +2374,10 @@ "message": "Anda yakin ingin menghapus Send ini?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send diedit", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "Untuk memilih file ini, buka Extension di sidebar (jika memungkinkan) atau keluarkan menjadi window baru dengan menekan gambar ini." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "Untuk memilih file menggunakan Safari, keluar ke jendela baru dengan mengklik spanduk ini." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Sebelum kamu memulai" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Add account" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/it/messages.json b/apps/browser/src/_locales/it/messages.json index 46bf1fe6c9b..83abf961c27 100644 --- a/apps/browser/src/_locales/it/messages.json +++ b/apps/browser/src/_locales/it/messages.json @@ -2374,6 +2374,10 @@ "message": "Sei sicuro di voler eliminare questo Send?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Modifica Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send salvato", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "Per scegliere un file, apri l'estensione nella barra laterale (se possibile) o apri una nuova finestra cliccando questo banner." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "Per scegliere un file usando Safari, apri una nuova finestra cliccando questo banner." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Prima di iniziare" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Abilita animazioni" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Aggiungi account" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "Non hai i permessi per modificare questo elemento" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/ja/messages.json b/apps/browser/src/_locales/ja/messages.json index adc9242050e..708b2d039a4 100644 --- a/apps/browser/src/_locales/ja/messages.json +++ b/apps/browser/src/_locales/ja/messages.json @@ -490,7 +490,7 @@ "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": { @@ -2374,6 +2374,10 @@ "message": "この Send を削除してもよろしいですか?", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "deleteSendPermanentConfirmation": { + "message": "この Send を完全に削除してもよろしいですか?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Send を編集", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "編集済みの Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "拡張機能をポップアウトしますか?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendFilePopoutDialogDesc": { + "message": "ファイル Send を作成するには、拡張機能を新しいウィンドウでポップアウト表示する必要があります。", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "ファイルを選択するには、可能な場合サイドバーで拡張子を開くか、このバナーをクリックして新しいウィンドウにポップアップしてください。" }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "Safari を使用してファイルを選択するには、このバナーをクリックして新しいウィンドウで開いてください。" }, + "popOut": { + "message": "ポップアウト" + }, "sendFileCalloutHeader": { "message": "はじめる前に" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "アニメーションを有効化" }, + "showAnimations": { + "message": "アニメーションを表示" + }, "addAccount": { "message": "アカウントを追加" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "このアイテムを編集する権限がありません" + }, + "authenticating": { + "message": "認証中" } } diff --git a/apps/browser/src/_locales/ka/messages.json b/apps/browser/src/_locales/ka/messages.json index 6525dcc9c06..c1225487483 100644 --- a/apps/browser/src/_locales/ka/messages.json +++ b/apps/browser/src/_locales/ka/messages.json @@ -2374,6 +2374,10 @@ "message": "Are you sure you want to delete this Send?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send saved", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "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." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "In order to choose a file using Safari, pop out to a new window by clicking this banner." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Before you start" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Add account" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/km/messages.json b/apps/browser/src/_locales/km/messages.json index 8eae45e6b38..f7db6d78f21 100644 --- a/apps/browser/src/_locales/km/messages.json +++ b/apps/browser/src/_locales/km/messages.json @@ -2374,6 +2374,10 @@ "message": "Are you sure you want to delete this Send?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send saved", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "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." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "In order to choose a file using Safari, pop out to a new window by clicking this banner." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Before you start" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Add account" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/kn/messages.json b/apps/browser/src/_locales/kn/messages.json index c022c77288d..3ec5ff04f93 100644 --- a/apps/browser/src/_locales/kn/messages.json +++ b/apps/browser/src/_locales/kn/messages.json @@ -2374,6 +2374,10 @@ "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "ಕಳುಹಿಸು ಸಂಪಾದಿಸಿ", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "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?", + "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 te extension to a new window.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "ಫೈಲ್ ಅನ್ನು ಆಯ್ಕೆ ಮಾಡಲು, ಸೈಡ್‌ಬಾರ್‌ನಲ್ಲಿ ವಿಸ್ತರಣೆಯನ್ನು ತೆರೆಯಿರಿ (ಸಾಧ್ಯವಾದರೆ) ಅಥವಾ ಈ ಬ್ಯಾನರ್ ಕ್ಲಿಕ್ ಮಾಡುವ ಮೂಲಕ ಹೊಸ ವಿಂಡೋಗೆ ಪಾಪ್ಔಟ್ ಮಾಡಿ." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "ಸಫಾರಿ ಬಳಸಿ ಫೈಲ್ ಆಯ್ಕೆ ಮಾಡಲು, ಈ ಬ್ಯಾನರ್ ಕ್ಲಿಕ್ ಮಾಡುವ ಮೂಲಕ ಹೊಸ ವಿಂಡೋಗೆ ಪಾಪ್ಔಟ್ ಮಾಡಿ." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "ನೀವು ಪ್ರಾರಂಭಿಸುವ ಮೊದಲು" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Add account" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/ko/messages.json b/apps/browser/src/_locales/ko/messages.json index 138a4548f88..3844548e24f 100644 --- a/apps/browser/src/_locales/ko/messages.json +++ b/apps/browser/src/_locales/ko/messages.json @@ -2374,6 +2374,10 @@ "message": "정말 이 Send를 삭제하시겠습니까?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Send 편집", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send 수정함", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "파일을 선택하려면 이 배너를 클릭하여 확장 프로그램을 사이드바에서 열거나, 불가능한 경우 새 창에서 여세요." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "Safari에서 파일을 선택할 경우, 이 배너를 클릭하여 확장 프로그램을 새 창에서 여세요." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "시작하기 전에" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Add account" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/lt/messages.json b/apps/browser/src/_locales/lt/messages.json index 6e583c88c13..21eabe2adec 100644 --- a/apps/browser/src/_locales/lt/messages.json +++ b/apps/browser/src/_locales/lt/messages.json @@ -1144,7 +1144,7 @@ "message": "Failas" }, "fileToShare": { - "message": "File to share" + "message": "Failas, kuri bendrinti" }, "selectFile": { "message": "Pasirinkite failą." @@ -2374,6 +2374,10 @@ "message": "Ar tikrai norite ištrinti šį „Send“?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Redaguoti „Send“", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Siuntinys išsaugotas", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "Norėdami pasirinkti failą, atidarykite plėtinį šoninėje juostoje (jei įmanoma) arba iššokkite į naują langą spustelėdami šią reklamjuostę." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "Norėdami pasirinkti failą naudodami „Safari“, iššokkite į naują langą spustelėdami šią reklamjuostę." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Prieš pradedant" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Pridėti paskyrą" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/lv/messages.json b/apps/browser/src/_locales/lv/messages.json index 8382fdcdc73..ae2a9bf6797 100644 --- a/apps/browser/src/_locales/lv/messages.json +++ b/apps/browser/src/_locales/lv/messages.json @@ -490,7 +490,7 @@ "description": "Label for the avoid ambiguous characters checkbox." }, "generatorPolicyInEffect": { - "message": "Enterprise policy requirements have been applied to your generator options.", + "message": "Veidotāja iespējām tika piemērotas uzņēmējdarbības nosacījumu prasības.", "description": "Indicates that a policy limits the credential generator screen." }, "searchVault": { @@ -2374,6 +2374,10 @@ "message": "Vai tiešām izdzēst šo Send?", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "deleteSendPermanentConfirmation": { + "message": "Vai tiešām neatgriezeniski izdzēst šo Send?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Labot Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send saglabāts", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Atvērt paplašinājumu atsevišķi?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendFilePopoutDialogDesc": { + "message": "Lai izveidotu datņu Send, nepieciešams atvērt paplašinājumu atsevišķā logā.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "Lai izvēlētos datni, paplašinājums ir jāatver sānjoslā (ja iespējams) vai atsevišķā logā, klikšķinot uz šī paziņojuma." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "Lai izvēlētos datni, ja tiek izmantots Safari, paplašinājums ir jāatver jaunā logā, klikšķinot uz šī paziņojuma." }, + "popOut": { + "message": "Atvērt atsevišķi" + }, "sendFileCalloutHeader": { "message": "Pirms sākšanas" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Iespējot animācijas" }, + "showAnimations": { + "message": "Rādīt animācijas" + }, "addAccount": { "message": "Pievienot kontu" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "Nav nepieciešamo atļauju, lai labotu šo vienumu" + }, + "authenticating": { + "message": "Autentificē" } } diff --git a/apps/browser/src/_locales/ml/messages.json b/apps/browser/src/_locales/ml/messages.json index e78edf841ea..38d86e2f776 100644 --- a/apps/browser/src/_locales/ml/messages.json +++ b/apps/browser/src/_locales/ml/messages.json @@ -2374,6 +2374,10 @@ "message": "Are you sure you want to delete this Send?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send saved", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "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." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "In order to choose a file using Safari, pop out to a new window by clicking this banner." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Before you start" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Add account" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/mr/messages.json b/apps/browser/src/_locales/mr/messages.json index 36010477889..35e55a1cf0c 100644 --- a/apps/browser/src/_locales/mr/messages.json +++ b/apps/browser/src/_locales/mr/messages.json @@ -2374,6 +2374,10 @@ "message": "Are you sure you want to delete this Send?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send saved", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "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." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "In order to choose a file using Safari, pop out to a new window by clicking this banner." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Before you start" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Add account" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/my/messages.json b/apps/browser/src/_locales/my/messages.json index 8eae45e6b38..f7db6d78f21 100644 --- a/apps/browser/src/_locales/my/messages.json +++ b/apps/browser/src/_locales/my/messages.json @@ -2374,6 +2374,10 @@ "message": "Are you sure you want to delete this Send?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send saved", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "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." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "In order to choose a file using Safari, pop out to a new window by clicking this banner." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Before you start" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Add account" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/nb/messages.json b/apps/browser/src/_locales/nb/messages.json index 75188875b59..987ef6e8119 100644 --- a/apps/browser/src/_locales/nb/messages.json +++ b/apps/browser/src/_locales/nb/messages.json @@ -2374,6 +2374,10 @@ "message": "Er du sikker på at du vil slette denne Send-en?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Rediger Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Redigerte Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "For å velge en fil, åpne utvidelsen i sidepanelet (hvis mulig) eller poppe ut til et nytt vindu ved å klikke på dette banneret." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "For å velge en fil med Safari, popp ut i et nytt vindu ved å klikke på dette banneret." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Før du starter" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Add account" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/ne/messages.json b/apps/browser/src/_locales/ne/messages.json index 8eae45e6b38..f7db6d78f21 100644 --- a/apps/browser/src/_locales/ne/messages.json +++ b/apps/browser/src/_locales/ne/messages.json @@ -2374,6 +2374,10 @@ "message": "Are you sure you want to delete this Send?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send saved", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "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." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "In order to choose a file using Safari, pop out to a new window by clicking this banner." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Before you start" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Add account" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/nl/messages.json b/apps/browser/src/_locales/nl/messages.json index 3426fa1c62d..0f4787eb9ce 100644 --- a/apps/browser/src/_locales/nl/messages.json +++ b/apps/browser/src/_locales/nl/messages.json @@ -490,7 +490,7 @@ "description": "Label for the avoid ambiguous characters checkbox." }, "generatorPolicyInEffect": { - "message": "Enterprise policy requirements have been applied to your generator options.", + "message": "Bedrijfsbeleidseisen zijn toegepast op je generator-instellingen.", "description": "Indicates that a policy limits the credential generator screen." }, "searchVault": { @@ -2374,6 +2374,10 @@ "message": "Weet je zeker dat je deze Send wilt verwijderen?", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "deleteSendPermanentConfirmation": { + "message": "Weet je zeker dat je deze Send permanent wil verwijderen?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Send bewerken", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send bewerkt", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Extensie uitklappen?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendFilePopoutDialogDesc": { + "message": "Om een bestand te versturen via Send, moet je de extensie naar een nieuw venster uitklappen.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "Om een bestand te kiezen open je de extensie in de zijbalk (indien mogelijk) of pop-out naar een nieuw venster door op deze banner te klikken." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "Om een bestand te kiezen met Safari, open je een nieuw pop-up-venster door op deze banner te klikken." }, + "popOut": { + "message": "Uitklappen" + }, "sendFileCalloutHeader": { "message": "Voor je begint" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Animaties inschakelen" }, + "showAnimations": { + "message": "Animaties weergeven" + }, "addAccount": { "message": "Account toevoegen" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "Je hebt geen toestemming om dit item te bewerken" + }, + "authenticating": { + "message": "Aan het inloggen" } } diff --git a/apps/browser/src/_locales/nn/messages.json b/apps/browser/src/_locales/nn/messages.json index 8eae45e6b38..f7db6d78f21 100644 --- a/apps/browser/src/_locales/nn/messages.json +++ b/apps/browser/src/_locales/nn/messages.json @@ -2374,6 +2374,10 @@ "message": "Are you sure you want to delete this Send?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send saved", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "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." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "In order to choose a file using Safari, pop out to a new window by clicking this banner." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Before you start" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Add account" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/or/messages.json b/apps/browser/src/_locales/or/messages.json index 8eae45e6b38..f7db6d78f21 100644 --- a/apps/browser/src/_locales/or/messages.json +++ b/apps/browser/src/_locales/or/messages.json @@ -2374,6 +2374,10 @@ "message": "Are you sure you want to delete this Send?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send saved", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "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." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "In order to choose a file using Safari, pop out to a new window by clicking this banner." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Before you start" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Add account" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/pl/messages.json b/apps/browser/src/_locales/pl/messages.json index 0452d2d5db3..f667d71b917 100644 --- a/apps/browser/src/_locales/pl/messages.json +++ b/apps/browser/src/_locales/pl/messages.json @@ -129,7 +129,7 @@ "message": "Kopiuj numer licencji" }, "copyCustomField": { - "message": "Copy $FIELD$", + "message": "Kopiuj $FIELD$", "placeholders": { "field": { "content": "$1", @@ -138,10 +138,10 @@ } }, "copyWebsite": { - "message": "Copy website" + "message": "Kopiuj stronę internetową" }, "copyNotes": { - "message": "Copy notes" + "message": "Kopiuj notatki" }, "autoFill": { "message": "Autouzupełnianie" @@ -195,16 +195,16 @@ "message": "Dodaj element" }, "accountEmail": { - "message": "Account email" + "message": "Adres e-mail konta" }, "requestHint": { - "message": "Request hint" + "message": "Poproś o podpowiedź" }, "requestPasswordHint": { - "message": "Request password hint" + "message": "Poproś o podpowiedź do hasła" }, "enterYourAccountEmailAddressAndYourPasswordHintWillBeSentToYou": { - "message": "Enter your account email address and your password hint will be sent to you" + "message": "Wprowadź adres e-mail swojego konta, a podpowiedź hasła zostanie wysłana do Ciebie" }, "passwordHint": { "message": "Podpowiedź do hasła" @@ -329,22 +329,22 @@ "message": "Edytuj folder" }, "newFolder": { - "message": "New folder" + "message": "Nowy folder" }, "folderName": { - "message": "Folder name" + "message": "Nazwa folderu" }, "folderHintText": { - "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + "message": "Zagnieżdżaj foldery dodając nazwę folderu nadrzędnego, a następnie “/”. Przykład: Społeczne/Fora" }, "noFoldersAdded": { - "message": "No folders added" + "message": "Nie dodano folderów" }, "createFoldersToOrganize": { - "message": "Create folders to organize your vault items" + "message": "Twórz foldery, aby zorganizować elementy swojego sejfu" }, "deleteFolderPermanently": { - "message": "Are you sure you want to permanently delete this folder?" + "message": "Czy na pewno chcesz trwale usunąć ten folder?" }, "deleteFolder": { "message": "Usuń folder" @@ -427,11 +427,11 @@ "description": "deprecated. Use specialCharactersLabel instead." }, "include": { - "message": "Include", + "message": "Uwzględnij", "description": "Card header for password generator include block" }, "uppercaseDescription": { - "message": "Include uppercase characters", + "message": "Uwzględnij wielkie litery", "description": "Tooltip for the password generator uppercase character checkbox" }, "uppercaseLabel": { @@ -439,7 +439,7 @@ "description": "Label for the password generator uppercase character checkbox" }, "lowercaseDescription": { - "message": "Include lowercase characters", + "message": "Uwzględnij małe litery", "description": "Full description for the password generator lowercase character checkbox" }, "lowercaseLabel": { @@ -447,7 +447,7 @@ "description": "Label for the password generator lowercase character checkbox" }, "numbersDescription": { - "message": "Include numbers", + "message": "Uwzględnij cyfry", "description": "Full description for the password generator numbers checkbox" }, "numbersLabel": { @@ -455,7 +455,7 @@ "description": "Label for the password generator numbers checkbox" }, "specialCharactersDescription": { - "message": "Include special characters", + "message": "Uwzględnij znaki specjalne", "description": "Full description for the password generator special characters checkbox" }, "specialCharactersLabel": { @@ -486,11 +486,11 @@ "description": "deprecated. Use avoidAmbiguous instead." }, "avoidAmbiguous": { - "message": "Avoid ambiguous characters", + "message": "Unikaj niejednoznacznych znaków", "description": "Label for the avoid ambiguous characters checkbox." }, "generatorPolicyInEffect": { - "message": "Enterprise policy requirements have been applied to your generator options.", + "message": "Wymagania polityki przedsiębiorstwa zostały użyte do ustawienia opcji generatora.", "description": "Indicates that a policy limits the credential generator screen." }, "searchVault": { @@ -536,7 +536,7 @@ "message": "Notatki" }, "privateNote": { - "message": "Private note" + "message": "Prywatna notatka" }, "note": { "message": "Notatka" @@ -584,7 +584,7 @@ "message": "Limit czasu sesji" }, "vaultTimeoutHeader": { - "message": "Vault timeout" + "message": "Blokowanie sejfu" }, "otherOptions": { "message": "Pozostałe opcje" @@ -627,7 +627,7 @@ "message": "Blokowanie sejfu" }, "vaultTimeout1": { - "message": "Timeout" + "message": "Limit czasu" }, "lockNow": { "message": "Zablokuj" @@ -724,10 +724,10 @@ "message": "Konto zostało utworzone! Teraz możesz się zalogować." }, "newAccountCreated2": { - "message": "Your new account has been created!" + "message": "Twoje nowe konto zostało utworzone!" }, "youHaveBeenLoggedIn": { - "message": "You have been logged in!" + "message": "Zalogowano Cię!" }, "youSuccessfullyLoggedIn": { "message": "Zalogowałeś się pomyślnie" @@ -779,7 +779,7 @@ "message": "Bitwarden może przechowywać i wypełniać kody weryfikacyjne. Wybierz ikonę aparatu, aby zrobić zrzut ekranu z kodem QR lub skopiuj i wklej klucz do tego pola." }, "learnMoreAboutAuthenticators": { - "message": "Learn more about authenticators" + "message": "Dowiedz się więcej o uwierzytelniaczach" }, "copyTOTP": { "message": "Kopiuj klucz uwierzytelniający (TOTP)" @@ -830,10 +830,10 @@ "message": "Logowanie dwustopniowe sprawia, że konto jest bardziej bezpieczne poprzez wymuszenie potwierdzenia logowania z innego urządzenia, takiego jak z klucza bezpieczeństwa, aplikacji uwierzytelniającej, wiadomości SMS, telefonu lub adresu e-mail. Logowanie dwustopniowe możesz włączyć w sejfie internetowym bitwarden.com. Czy chcesz przejść do tej strony?" }, "twoStepLoginConfirmationContent": { - "message": "Make your account more secure by setting up two-step login in the Bitwarden web app." + "message": "Spraw, aby Twoje konto było bezpieczniejsze poprzez skonfigurowanie dwustopniowego logowania w aplikacji internetowej Bitwarden." }, "twoStepLoginConfirmationTitle": { - "message": "Continue to web app?" + "message": "Kontynuować do aplikacji internetowej?" }, "editedFolder": { "message": "Folder został zapisany" @@ -938,7 +938,7 @@ "message": "Pokaż elementy karty na stronie głównej, aby ułatwić autouzupełnianie." }, "showIdentitiesInVaultView": { - "message": "Show identities as Autofill suggestions on Vault view" + "message": "Pokaż tożsamośći jako sugestie autouzupełniania w widoku sejfu" }, "showIdentitiesCurrentTab": { "message": "Pokaż tożsamości na stronie głównej" @@ -1144,7 +1144,7 @@ "message": "Plik" }, "fileToShare": { - "message": "File to share" + "message": "Plik do udostępnienia" }, "selectFile": { "message": "Wybierz plik" @@ -1180,7 +1180,7 @@ "message": "1 GB miejsca na zaszyfrowane załączniki." }, "premiumSignUpEmergency": { - "message": "Emergency access." + "message": "Dostęp awaryjny." }, "premiumSignUpTwoStepOptions": { "message": "Własnościowe opcje logowania dwuetapowego, takie jak YubiKey i Duo." @@ -1204,7 +1204,7 @@ "message": "Konto Premium możesz zakupić na stronie sejfu bitwarden.com. Czy chcesz otworzyć tę stronę?" }, "premiumPurchaseAlertV2": { - "message": "You can purchase Premium from your account settings on the Bitwarden web app." + "message": "Możesz kupić Premium w ustawieniach konta w aplikacji internetowej Bitwarden." }, "premiumCurrentMember": { "message": "Posiadasz konto Premium!" @@ -1213,7 +1213,7 @@ "message": "Dziękujemy za wspieranie Bitwarden." }, "premiumFeatures": { - "message": "Upgrade to Premium and receive:" + "message": "Uaktualnij do wersji Premium i otrzymaj:" }, "premiumPrice": { "message": "Wszystko to jedynie za $PRICE$ /rok!", @@ -1225,7 +1225,7 @@ } }, "premiumPriceV2": { - "message": "All for just $PRICE$ per year!", + "message": "Wszystko tylko za $PRICE$ rocznie!", "placeholders": { "price": { "content": "$1", @@ -1846,13 +1846,13 @@ "message": "Brak haseł." }, "clearHistory": { - "message": "Clear history" + "message": "Wyczyść historię" }, "noPasswordsToShow": { - "message": "No passwords to show" + "message": "Brak haseł do wyświetlenia" }, "noRecentlyGeneratedPassword": { - "message": "You haven't generated a password recently" + "message": "W ostatnim czasie nie wygenerowano hasła" }, "remove": { "message": "Usuń" @@ -1913,16 +1913,16 @@ "message": "Odblokuj kodem PIN" }, "setYourPinTitle": { - "message": "Set PIN" + "message": "Ustaw kod PIN" }, "setYourPinButton": { - "message": "Set PIN" + "message": "Ustaw kod PIN" }, "setYourPinCode": { "message": "Ustaw kod PIN do odblokowywania aplikacji Bitwarden. Ustawienia odblokowywania kodem PIN zostaną zresetowane po wylogowaniu." }, "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": "Twój PIN będzie używany do odblokowania Bitwardena zamiast hasła głównego. Twój kod PIN zostanie zresetowany jeśli kiedykolwiek wylogujesz się z Bitwarden." }, "pinRequired": { "message": "Kod PIN jest wymagany." @@ -1946,7 +1946,7 @@ "message": "Zablokuj hasłem głównym po uruchomieniu przeglądarki" }, "lockWithMasterPassOnRestart1": { - "message": "Require master password on browser restart" + "message": "Wymagaj hasła głównego przy ponownym uruchomieniu przeglądarki" }, "selectOneCollection": { "message": "Musisz wybrać co najmniej jedną kolekcję." @@ -1961,33 +1961,33 @@ "message": "Co najmniej jedna zasada organizacji wpływa na ustawienia generatora." }, "passwordGenerator": { - "message": "Password generator" + "message": "Generator hasła" }, "usernameGenerator": { - "message": "Username generator" + "message": "Generator nazw użytkownika" }, "useThisPassword": { - "message": "Use this password" + "message": "Użyj tego hasła" }, "useThisUsername": { - "message": "Use this username" + "message": "Użyj tej nazwy użytkownika" }, "securePasswordGenerated": { - "message": "Secure password generated! Don't forget to also update your password on the website." + "message": "Wygenerowane bezpieczne hasło! Nie zapomnij również zaktualizować hasła na stronie." }, "useGeneratorHelpTextPartOne": { - "message": "Use the generator", + "message": "Użyj generatora", "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": ", aby utworzyć mocne unikalne hasło", "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": "Sposób blokowania sejfu" }, "vaultTimeoutAction1": { - "message": "Timeout action" + "message": "Akcja po przekroczeniu limitu czasu" }, "lock": { "message": "Zablokuj", @@ -2208,10 +2208,10 @@ "message": "Odblokuj tego użytkownika w aplikacji desktopowej i spróbuj ponownie." }, "biometricsNotAvailableTitle": { - "message": "Biometric unlock unavailable" + "message": "Odblokowanie biometryczne jest niedostępne" }, "biometricsNotAvailableDesc": { - "message": "Biometric unlock is currently unavailable. Please try again later." + "message": "Odblokowanie biometryczne jest obecnie niedostępne. Spróbuj ponownie później." }, "biometricsFailedTitle": { "message": "Dane biometryczne są błędne" @@ -2275,14 +2275,14 @@ "message": "Zmiany w wykluczonych domenach zapisane" }, "limitSendViews": { - "message": "Limit views" + "message": "Limit wyświetleń" }, "limitSendViewsHint": { - "message": "No one can view this Send after the limit is reached.", + "message": "Nikt nie może wyświetlić Send po osiągnieciu limitu.", "description": "Displayed under the limit views field on Send" }, "limitSendViewsCount": { - "message": "$ACCESSCOUNT$ views left", + "message": "Zostało wyświetleń: $ACCESSCOUNT$", "description": "Displayed under the limit views field on Send", "placeholders": { "accessCount": { @@ -2296,7 +2296,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": "Szczegóły Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "searchSends": { @@ -2311,7 +2311,7 @@ "message": "Tekst" }, "sendTypeTextToShare": { - "message": "Text to share" + "message": "Tekst do udostępnienia" }, "sendTypeFile": { "message": "Plik" @@ -2321,7 +2321,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": "Domyślnie ukryj tekst" }, "maxAccessCountReached": { "message": "Maksymalna liczba dostępów została osiągnięta", @@ -2374,6 +2374,10 @@ "message": "Czy na pewno chcesz usunąć tę wysyłkę?", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "deleteSendPermanentConfirmation": { + "message": "Czy na pewno chcesz trwale usunąć to Send?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Edytuj wysyłkę", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2397,7 +2401,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "deletionDateDescV2": { - "message": "The Send will be permanently deleted on this date.", + "message": "Send zostanie trwale usunięte w tej dacie.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "expirationDate": { @@ -2434,7 +2438,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendPasswordDescV2": { - "message": "Require this password to view the Send.", + "message": "Wymagaj tego hasła aby wyświetlić Send.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendNotesDesc": { @@ -2479,11 +2483,11 @@ "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": "Send został stworzony!", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendAvailability": { - "message": "The Send will be available to anyone with the link for the next $DAYS$ days.", + "message": "Send będzie dostępny dla każdego kto ma link przez następującą liczbę dni: $DAYS$.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.", "placeholders": { "days": { @@ -2493,13 +2497,21 @@ } }, "sendLinkCopied": { - "message": "Send link copied", + "message": "Link Send został skopiowany", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "editedSend": { "message": "Wysyłka została zapisana", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "Aby wybrać plik, otwórz rozszerzenie na pasku bocznym (jeśli to możliwe) lub w nowym oknie." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "Aby wybrać plik za pomocą przeglądarki Safari, otwórz rozszerzenie w nowym oknie." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Zanim zaczniesz" }, @@ -2543,7 +2558,7 @@ "message": "Ukryj mój adres e-mail przed odbiorcami." }, "hideYourEmail": { - "message": "Hide your email address from viewers." + "message": "Ukryj mój adres e-mail przed oglądającymi." }, "sendOptionsPolicyInEffect": { "message": "Co najmniej jedna zasada organizacji wpływa na ustawienia wysyłek." @@ -2579,7 +2594,7 @@ "message": "Twoje hasło główne nie spełnia jednej lub kilku zasad organizacji. Aby uzyskać dostęp do sejfu, musisz teraz zaktualizować swoje hasło główne. Kontynuacja wyloguje Cię z bieżącej sesji, wymagając zalogowania się ponownie. Aktywne sesje na innych urządzeniach mogą pozostać aktywne przez maksymalnie jedną godzinę." }, "tdeDisabledMasterPasswordRequired": { - "message": "Your organization has disabled trusted device encryption. Please set a master password to access your vault." + "message": "Twoja organizacja wyłączyła szyfrowanie zaufanego urządzenia. Ustaw hasło główne, aby uzyskać dostęp do sejfu." }, "resetPasswordPolicyAutoEnroll": { "message": "Automatyczne rejestrowanie użytkowników" @@ -2613,7 +2628,7 @@ "message": "Minuty" }, "vaultTimeoutPolicyAffectingOptions": { - "message": "Enterprise policy requirements have been applied to your timeout options" + "message": "Wymagania polityki przedsiębiorstwa zostały zastosowane do twoich opcji przekrocznia limitu czasu" }, "vaultTimeoutPolicyInEffect": { "message": "Zasady organizacji mają wpływ czas blokowania sejfu. Maksymalny dozwolony czas wynosi $HOURS$ godz. i $MINUTES$ min.", @@ -2629,7 +2644,7 @@ } }, "vaultTimeoutPolicyInEffect1": { - "message": "$HOURS$ hour(s) and $MINUTES$ minute(s) maximum.", + "message": "$HOURS$ godzin(y) i $MINUTES$ minut(y) maksymalnie.", "placeholders": { "hours": { "content": "$1", @@ -2642,7 +2657,7 @@ } }, "vaultTimeoutPolicyMaximumError": { - "message": "Timeout exceeds the restriction set by your organization: $HOURS$ hour(s) and $MINUTES$ minute(s) maximum", + "message": "Limit czasu przekracza ograniczenie ustawione przez Twoją organizację: $HOURS$ godzin(y) i $MINUTES$ minut(y) maksymalnie", "placeholders": { "hours": { "content": "$1", @@ -3618,7 +3633,7 @@ "message": "Weryfikacja jest wymagana przez stronę inicjującą. Ta funkcja nie jest jeszcze zaimplementowana dla kont bez hasła głównego." }, "logInWithPasskeyQuestion": { - "message": "Log in with passkey?" + "message": "Zaloguj się za pomocą passkey?" }, "passkeyAlreadyExists": { "message": "Passkey już istnieje dla tej aplikacji." @@ -3630,7 +3645,7 @@ "message": "Nie masz pasujących danych logowania do tej witryny." }, "noMatchingLoginsForSite": { - "message": "No matching logins for this site" + "message": "Brak pasujących loginów dla tej witryny" }, "confirm": { "message": "Potwierdź" @@ -3642,10 +3657,10 @@ "message": "Zapisz passkey jako nowe dane logowania" }, "chooseCipherForPasskeySave": { - "message": "Choose a login to save this passkey to" + "message": "Wybierz dane logowania do których przypisać passkey" }, "chooseCipherForPasskeyAuth": { - "message": "Choose a passkey to log in with" + "message": "Wybierz passkey żeby się zalogować" }, "passkeyItem": { "message": "Element Passkey" @@ -3843,7 +3858,7 @@ "description": "Notification message for when saving credentials has succeeded." }, "passwordSaved": { - "message": "Password saved!", + "message": "Hasło zostało zapisane!", "description": "Notification message for when saving credentials has succeeded." }, "updateCipherAttemptSuccess": { @@ -3851,7 +3866,7 @@ "description": "Notification message for when updating credentials has succeeded." }, "passwordUpdated": { - "message": "Password updated!", + "message": "Hasło zostało zaktualizowane!", "description": "Notification message for when updating credentials has succeeded." }, "saveCipherAttemptFailed": { @@ -4131,7 +4146,7 @@ "message": "Strona internetowa (URI)" }, "websiteUriCount": { - "message": "Website (URI) $COUNT$", + "message": "Strona internetowa (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": { @@ -4160,7 +4175,7 @@ } }, "showMatchDetection": { - "message": "Show match detection $WEBSITE$", + "message": "Pokaż wykrywanie dopasowań $WEBSITE$", "placeholders": { "website": { "content": "$1", @@ -4169,7 +4184,7 @@ } }, "hideMatchDetection": { - "message": "Hide match detection $WEBSITE$", + "message": "Ukryj wykrywanie dopasowań $WEBSITE$", "placeholders": { "website": { "content": "$1", @@ -4181,10 +4196,10 @@ "message": "Włącz autouzupełnianie po załadowaniu strony?" }, "cardExpiredTitle": { - "message": "Expired card" + "message": "Karta wygasła" }, "cardExpiredMessage": { - "message": "If you've renewed it, update the card's information" + "message": "Jeśli ją wznowiłeś, zaktualizuj informacje o karcie" }, "cardDetails": { "message": "Szczegóły karty" @@ -4199,7 +4214,10 @@ } }, "enableAnimations": { - "message": "Enable animations" + "message": "Włącz animacje" + }, + "showAnimations": { + "message": "Pokaż animacje" }, "addAccount": { "message": "Dodaj konto" @@ -4215,11 +4233,11 @@ "description": "A section header for a list of passkeys." }, "passwords": { - "message": "Passwords", + "message": "Hasła", "description": "A section header for a list of passwords." }, "logInWithPasskeyAriaLabel": { - "message": "Log in with passkey", + "message": "Zaloguj się za pomocą passkey", "description": "ARIA label for the inline menu button that logs in with a passkey." }, "assign": { @@ -4429,54 +4447,57 @@ "message": "Auto wypełnianie i szukanie na zakładce sejfu jest teraz prostsze i bardziej intuicyjne. Rozejrzyj się tam!" }, "accountActions": { - "message": "Account actions" + "message": "Akcje konta" }, "showNumberOfAutofillSuggestions": { - "message": "Show number of login autofill suggestions on extension icon" + "message": "Pokaż liczbę sugestii autouzupełniania logowania na ikonie rozszerzenia" }, "systemDefault": { - "message": "System default" + "message": "Domyślny systemu" }, "enterprisePolicyRequirementsApplied": { - "message": "Enterprise policy requirements have been applied to this setting" + "message": "Do tego ustalenia zastosowano wymogi polityki przedsiębiorstw" }, "retry": { - "message": "Retry" + "message": "Powtórz" }, "vaultCustomTimeoutMinimum": { - "message": "Minimum custom timeout is 1 minute." + "message": "Minimalny limit czasu niestandardowego wynosi 1 minutę." }, "additionalContentAvailable": { - "message": "Additional content is available" + "message": "Dostępna jest dodatkowa zawartość" }, "fileSavedToDevice": { - "message": "File saved to device. Manage from your device downloads." + "message": "Plik zapisany na urządzeniu. Zarządzaj plikiem na swoim urządzeniu." }, "showCharacterCount": { - "message": "Show character count" + "message": "Pokaż liczbę znaków" }, "hideCharacterCount": { - "message": "Hide character count" + "message": "Ukryj liczbę znaków" }, "itemsInTrash": { - "message": "Items in trash" + "message": "Elementy w koszu" }, "noItemsInTrash": { - "message": "No items in trash" + "message": "Brak elementów w koszu" }, "noItemsInTrashDesc": { - "message": "Items you delete will appear here and be permanently deleted after 30 days" + "message": "Usunięte elementy pojawią się tutaj i zostaną trwale usunięte po 30 dniach" }, "trashWarning": { - "message": "Items that have been in trash more than 30 days will automatically be deleted" + "message": "Elementy znajdujące się w koszu ponad 30 dni zostaną automatycznie usunięte" }, "restore": { - "message": "Restore" + "message": "Przywróć" }, "deleteForever": { - "message": "Delete forever" + "message": "Usuń na zawsze" }, "noEditPermissions": { - "message": "You don't have permission to edit this item" + "message": "Nie masz uprawnień do edycji tego elementu" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/pt_BR/messages.json b/apps/browser/src/_locales/pt_BR/messages.json index 27f41c9ef29..110bd1556f3 100644 --- a/apps/browser/src/_locales/pt_BR/messages.json +++ b/apps/browser/src/_locales/pt_BR/messages.json @@ -2374,6 +2374,10 @@ "message": "Você tem certeza que deseja excluir este Send?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Editar Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send Editado", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "Para escolher um arquivo, abra a extensão na barra lateral (se possível), ou abra uma nova janela clicando neste banner." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "Para escolher um arquivo usando o Safari, abra uma nova janela clicando neste banner." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Antes de começar" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Habilita animações" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Adicionar conta" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "Você não tem permissão para editar este arquivo" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/pt_PT/messages.json b/apps/browser/src/_locales/pt_PT/messages.json index 4c5c63a343c..9162937f2c3 100644 --- a/apps/browser/src/_locales/pt_PT/messages.json +++ b/apps/browser/src/_locales/pt_PT/messages.json @@ -490,7 +490,7 @@ "description": "Label for the avoid ambiguous characters checkbox." }, "generatorPolicyInEffect": { - "message": "Enterprise policy requirements have been applied to your generator options.", + "message": "Os requisitos da política empresarial foram aplicados às suas opções de gerador.", "description": "Indicates that a policy limits the credential generator screen." }, "searchVault": { @@ -2374,6 +2374,10 @@ "message": "Tem a certeza de que pretende eliminar este Send?", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "deleteSendPermanentConfirmation": { + "message": "Tem a certeza de que pretende eliminar permanentemente este Send?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Editar Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send editado", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Abrir a extensão numa nova janela?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendFilePopoutDialogDesc": { + "message": "Para criar um ficheiro Send, precisa de abrir a extensão para uma nova janela.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "Para escolher um ficheiro, abra a extensão na barra lateral (se possível) ou abra uma nova janela clicando neste banner." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "Para escolher um ficheiro utilizando o Safari, abra uma nova janela clicando neste banner." }, + "popOut": { + "message": "Abrir numa nova janela" + }, "sendFileCalloutHeader": { "message": "Antes de começar" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Ativar animações" }, + "showAnimations": { + "message": "Mostrar animações" + }, "addAccount": { "message": "Adicionar conta" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "Não tem permissão para editar este item" + }, + "authenticating": { + "message": "A autenticar" } } diff --git a/apps/browser/src/_locales/ro/messages.json b/apps/browser/src/_locales/ro/messages.json index 6d5dfa9e24c..e3498726146 100644 --- a/apps/browser/src/_locales/ro/messages.json +++ b/apps/browser/src/_locales/ro/messages.json @@ -2374,6 +2374,10 @@ "message": "Sigur doriți să ștergeți acest Send?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Editare Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send salvat", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "Pentru a alege un fișier, deschideți extensia în bara laterală (dacă este posibil) sau deschideți-o într-o fereastră nouă, făcând clic pe acest banner." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "Pentru a alege un fișier folosind Safari, deschideți o fereastră nouă făcând clic pe acest banner." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Înainte de a începe" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Add account" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/ru/messages.json b/apps/browser/src/_locales/ru/messages.json index 829cd56b6f5..b65860e3972 100644 --- a/apps/browser/src/_locales/ru/messages.json +++ b/apps/browser/src/_locales/ru/messages.json @@ -490,7 +490,7 @@ "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": { @@ -2374,6 +2374,10 @@ "message": "Вы действительно хотите удалить эту Send?", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "deleteSendPermanentConfirmation": { + "message": "Вы уверены, что хотите безвозвратно удалить эту Send?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Изменить Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send сохранена", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Открепить расширение?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendFilePopoutDialogDesc": { + "message": "Чтобы создать файл Send, необходимо открыть расширение в новом окне.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "Для выбора файла откройте расширение в боковой панели (если возможно) или перейдите в новое окно, нажав на этот баннер." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "Для выбора файла с помощью Safari, перейдите в новое окно, нажав на этот баннер." }, + "popOut": { + "message": "Открепить" + }, "sendFileCalloutHeader": { "message": "Перед тем, как начать" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Включить анимацию" }, + "showAnimations": { + "message": "Показать анимацию" + }, "addAccount": { "message": "Добавить аккаунт" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "У вас нет разрешения на редактирование этого элемента" + }, + "authenticating": { + "message": "Аутентификация" } } diff --git a/apps/browser/src/_locales/si/messages.json b/apps/browser/src/_locales/si/messages.json index 36094f55103..a20bdf1ce02 100644 --- a/apps/browser/src/_locales/si/messages.json +++ b/apps/browser/src/_locales/si/messages.json @@ -2374,6 +2374,10 @@ "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "යැවීම සංස්කරණය", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "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?", + "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 te extension to a new window.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "ගොනුවක් තෝරා ගැනීම සඳහා, පැති තීරුවේ දිගුව විවෘත කරන්න (හැකි නම්) හෝ මෙම බැනරය ක්ලික් කිරීමෙන් නව කවුළුවකට පොප් කරන්න." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "සෆාරි භාවිතා ගොනුවක් තෝරා ගැනීම සඳහා, මෙම බැනරය ක්ලික් කිරීමෙන් නව කවුළුවකට දිස්වේ." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "ඔබ ආරම්භ කිරීමට පෙර" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Add account" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/sk/messages.json b/apps/browser/src/_locales/sk/messages.json index 3faaa066934..b7ac5aa748e 100644 --- a/apps/browser/src/_locales/sk/messages.json +++ b/apps/browser/src/_locales/sk/messages.json @@ -490,7 +490,7 @@ "description": "Label for the avoid ambiguous characters checkbox." }, "generatorPolicyInEffect": { - "message": "Enterprise policy requirements have been applied to your generator options.", + "message": "Na nastavenie generátora boli uplatnené požiadavky pravidiel spoločnosti.", "description": "Indicates that a policy limits the credential generator screen." }, "searchVault": { @@ -2374,6 +2374,10 @@ "message": "Ste si istý, že chcete odstrániť Send?", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "deleteSendPermanentConfirmation": { + "message": "Naozaj chcete natrvalo odstrániť tento Send?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Upraviť Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send upravený", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Zobraziť rozšírenie v novom okne?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendFilePopoutDialogDesc": { + "message": "Na vytvorenie Sendu so súborom musíte zobraziť rozšírenie v novom okne.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "Ak chcete zvoliť súbor, otvorte rozšírenie v bočnom paneli (ak je to možné) alebo kliknite do tohto okna kliknutím na tento banner." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "Ak chcete zvoliť súbor pomocou Safari, kliknite na tento banner a otvorte nové okno." }, + "popOut": { + "message": "Zobraziť v novom okne" + }, "sendFileCalloutHeader": { "message": "Skôr než začnete" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Povoliť animácie" }, + "showAnimations": { + "message": "Zobraziť animácie" + }, "addAccount": { "message": "Pridať účet" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "Na úpravu tejto položky nemáte oprávnenie" + }, + "authenticating": { + "message": "Overuje sa" } } diff --git a/apps/browser/src/_locales/sl/messages.json b/apps/browser/src/_locales/sl/messages.json index 11205385d2b..4f3a5b4f0d0 100644 --- a/apps/browser/src/_locales/sl/messages.json +++ b/apps/browser/src/_locales/sl/messages.json @@ -2374,6 +2374,10 @@ "message": "Ste prepričani, da želite izbrisati to pošiljko?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Uredi pošiljko", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Pošiljka shranjena", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "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." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "In order to choose a file using Safari, pop out to a new window by clicking this banner." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Preden pričnete" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Add account" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/sr/messages.json b/apps/browser/src/_locales/sr/messages.json index f36038e0518..394eff867db 100644 --- a/apps/browser/src/_locales/sr/messages.json +++ b/apps/browser/src/_locales/sr/messages.json @@ -490,7 +490,7 @@ "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": { @@ -2374,6 +2374,10 @@ "message": "Сигурно избрисати овај „Send“?", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "deleteSendPermanentConfirmation": { + "message": "Да ли сте сигурни да желите да трајно избришете овај Send?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Уреди „Send“", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Измењено слање", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Искачући додатак?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendFilePopoutDialogDesc": { + "message": "Да бисте креирали датотеку Send, потребно је да искочите екстензију у нови прозор.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "Да бисте изабрали датотеку, отворите екстензију на бочној траци (ако је могуће) или отворите у нови прозор кликом на овај банер." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "Да бисте изабрали датотеку са Safari-ом, отворите у нови прозор кликом на овај банер." }, + "popOut": { + "message": "Искочити" + }, "sendFileCalloutHeader": { "message": "Пре него што почнеш" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Омогући анимације" }, + "showAnimations": { + "message": "Прикажи анимације" + }, "addAccount": { "message": "Додај налог" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "Немате дозволу да уређујете ову ставку" + }, + "authenticating": { + "message": "Аутентификација" } } diff --git a/apps/browser/src/_locales/sv/messages.json b/apps/browser/src/_locales/sv/messages.json index 4f0a1cb1ffb..c021a34c833 100644 --- a/apps/browser/src/_locales/sv/messages.json +++ b/apps/browser/src/_locales/sv/messages.json @@ -2374,6 +2374,10 @@ "message": "Är du säker på att du vill radera denna Send?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Redigera Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send har sparats", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "För att välja en fil, öppna tillägget i sidofältet (om möjligt) eller skapa ett nytt fönster genom att klicka på denna banner." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "För att välja en fil med Safari, öppna ett nytt fönster genom att klicka på denna banner." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Innan du börjar" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Aktivera animationer" }, + "showAnimations": { + "message": "Visa animationer" + }, "addAccount": { "message": "Lägg till konto" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/te/messages.json b/apps/browser/src/_locales/te/messages.json index 8eae45e6b38..f7db6d78f21 100644 --- a/apps/browser/src/_locales/te/messages.json +++ b/apps/browser/src/_locales/te/messages.json @@ -2374,6 +2374,10 @@ "message": "Are you sure you want to delete this Send?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send saved", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "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." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "In order to choose a file using Safari, pop out to a new window by clicking this banner." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Before you start" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Add account" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/th/messages.json b/apps/browser/src/_locales/th/messages.json index baa8babb5ef..fef75116169 100644 --- a/apps/browser/src/_locales/th/messages.json +++ b/apps/browser/src/_locales/th/messages.json @@ -2374,6 +2374,10 @@ "message": "คุณต้องการลบ Send นี้ใช่หรือไม่?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "แก้ไข Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send saved", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "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." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "In order to choose a file using Safari, pop out to a new window by clicking this banner." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Before you start" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Add account" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/tr/messages.json b/apps/browser/src/_locales/tr/messages.json index 55286fccc93..0bfa7b56a5f 100644 --- a/apps/browser/src/_locales/tr/messages.json +++ b/apps/browser/src/_locales/tr/messages.json @@ -490,7 +490,7 @@ "description": "Label for the avoid ambiguous characters checkbox." }, "generatorPolicyInEffect": { - "message": "Enterprise policy requirements have been applied to your generator options.", + "message": "Üreteç seçeneklerinize kurumsal ilke gereksinimleri uygulandı.", "description": "Indicates that a policy limits the credential generator screen." }, "searchVault": { @@ -2374,6 +2374,10 @@ "message": "Bu Send'i silmek istediğinizden emin misiniz?", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "deleteSendPermanentConfirmation": { + "message": "Bu Send'i kalıcı olarak silmek istediğinizden emin misiniz?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Send'i düzenle", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send kaydedildi", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Uzantı dışarı alınsın mı?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendFilePopoutDialogDesc": { + "message": "Dosya Send'i oluşturmak için uzantıyı yeni bir pencere halinde dışarı almalısınız.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "Dosya seçmek için eklentiyi kenar çubuğunda açın (mümkünse) veya bu banner'a tıklayarak yeni bir pencerede açın." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "Safari ile dosya seçmek için bu banner'a tıklayarak eklentiyi yeni bir pencerede açın." }, + "popOut": { + "message": "Dışarı al" + }, "sendFileCalloutHeader": { "message": "Başlamadan önce" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Animasyonları etkinleştir" }, + "showAnimations": { + "message": "Animasyonları göster" + }, "addAccount": { "message": "Hesap ekle" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "Bu kaydı düzenleme yetkisine sahip değilsiniz" + }, + "authenticating": { + "message": "Kimlik doğrulanıyor" } } diff --git a/apps/browser/src/_locales/uk/messages.json b/apps/browser/src/_locales/uk/messages.json index e063af8c7fa..a9090f5140c 100644 --- a/apps/browser/src/_locales/uk/messages.json +++ b/apps/browser/src/_locales/uk/messages.json @@ -490,7 +490,7 @@ "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": { @@ -2374,6 +2374,10 @@ "message": "Ви дійсно хочете видалити це відправлення?", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "deleteSendPermanentConfirmation": { + "message": "Ви дійсно хочете остаточно видалити це відправлення?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Редагування", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Відправлення збережено", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Відкріпити розширення?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendFilePopoutDialogDesc": { + "message": "Щоб створити відправлення файлу, необхідно відкріпити розширення в окреме вікно.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "Щоб вибрати файл, відкрийте розширення в бічній панелі (якщо можливо) або в новому вікні, натиснувши цей банер." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "Щоб вибрати файл з використанням Safari, відкрийте розширення в новому вікні, натиснувши на цей банер." }, + "popOut": { + "message": "Відкріпити" + }, "sendFileCalloutHeader": { "message": "Перед початком" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Увімкнути анімацію" }, + "showAnimations": { + "message": "Показати анімації" + }, "addAccount": { "message": "Додати обліковий запис" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "Вам не дозволено редагувати цей запис" + }, + "authenticating": { + "message": "Аутентифікація" } } diff --git a/apps/browser/src/_locales/vi/messages.json b/apps/browser/src/_locales/vi/messages.json index 363065e4429..a3e4adbc7e9 100644 --- a/apps/browser/src/_locales/vi/messages.json +++ b/apps/browser/src/_locales/vi/messages.json @@ -2374,6 +2374,10 @@ "message": "Bạn có chắc muốn mục Gửi này?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "Sửa mục Gửi", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Đã lưu mục Gửi", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "Để chọn tập tin, mở tiện ích mở rộng trong thanh bên (nếu có thể) hoặc mở ra cửa sổ mới bằng cách nhấp vào biểu ngữ này." }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "Để chọn tập tin bằng Safari, mở ra cửa sổ mới bằng cách nhấp vào biểu ngữ này." }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "Trước khi bạn bắt đầu" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Thêm tài khoản" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/_locales/zh_CN/messages.json b/apps/browser/src/_locales/zh_CN/messages.json index e86e14c1a6a..baf21d30a2b 100644 --- a/apps/browser/src/_locales/zh_CN/messages.json +++ b/apps/browser/src/_locales/zh_CN/messages.json @@ -490,7 +490,7 @@ "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": { @@ -2374,6 +2374,10 @@ "message": "确定要删除此 Send 吗?", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "deleteSendPermanentConfirmation": { + "message": "您确定要永久删除这个 Send 吗?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "编辑 Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send 已保存", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "弹出扩展?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, + "sendFilePopoutDialogDesc": { + "message": "要创建文件 Send,您需要弹出扩展到一个新窗口。", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "要选择文件,请在侧边栏中打开扩展(如果可以),或者点击此横幅来弹出一个新窗口。" }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "要在 Safari 中选择文件,请点击此横幅来弹出一个新窗口。" }, + "popOut": { + "message": "弹出" + }, "sendFileCalloutHeader": { "message": "在开始之前" }, @@ -2613,7 +2628,7 @@ "message": "分钟" }, "vaultTimeoutPolicyAffectingOptions": { - "message": "企业策略要求已应用到您的超时选项" + "message": "企业策略要求已应用到您的超时选项中" }, "vaultTimeoutPolicyInEffect": { "message": "您的组织策略已将您最大允许的密码库超时时间设置为 $HOURS$ 小时 $MINUTES$ 分钟。", @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "启用动画" }, + "showAnimations": { + "message": "显示动画" + }, "addAccount": { "message": "添加账户" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "您没有编辑此项目的权限" + }, + "authenticating": { + "message": "正在验证" } } diff --git a/apps/browser/src/_locales/zh_TW/messages.json b/apps/browser/src/_locales/zh_TW/messages.json index 49a407d51d5..d973910c66b 100644 --- a/apps/browser/src/_locales/zh_TW/messages.json +++ b/apps/browser/src/_locales/zh_TW/messages.json @@ -14,16 +14,16 @@ "message": "登入或建立帳戶以存取您的安全密碼庫。" }, "inviteAccepted": { - "message": "Invitation accepted" + "message": "邀請已接受" }, "createAccount": { "message": "建立帳戶" }, "setAStrongPassword": { - "message": "Set a strong password" + "message": "設定一個強密碼" }, "finishCreatingYourAccountBySettingAPassword": { - "message": "Finish creating your account by setting a password" + "message": "設定密碼以完成創建您的帳戶。" }, "enterpriseSingleSignOn": { "message": "企業單一登入" @@ -69,7 +69,7 @@ "message": "主密碼提示(選用)" }, "joinOrganization": { - "message": "Join organization" + "message": "加入組織" }, "finishJoiningThisOrganizationBySettingAMasterPassword": { "message": "Finish joining this organization by setting a master password." @@ -114,16 +114,16 @@ "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" @@ -2374,6 +2374,10 @@ "message": "您確定要刪除此 Send 嗎?", "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?", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "editSend": { "message": "編輯 Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2500,6 +2504,14 @@ "message": "Send 已儲存", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "sendFilePopoutDialogText": { + "message": "Pop out extension?", + "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 te extension to a new window.", + "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + }, "sendLinuxChromiumFileWarning": { "message": "要選擇檔案,請在側邊欄中開啟擴充套件(若可以),或點選此橫幅彈出至新視窗。" }, @@ -2509,6 +2521,9 @@ "sendSafariFileWarning": { "message": "要使用 Safari 來選擇檔案,請點選此橫幅彈出至新視窗。" }, + "popOut": { + "message": "Pop out" + }, "sendFileCalloutHeader": { "message": "在開始之前" }, @@ -4201,6 +4216,9 @@ "enableAnimations": { "message": "Enable animations" }, + "showAnimations": { + "message": "Show animations" + }, "addAccount": { "message": "Add account" }, @@ -4478,5 +4496,8 @@ }, "noEditPermissions": { "message": "You don't have permission to edit this item" + }, + "authenticating": { + "message": "Authenticating" } } diff --git a/apps/browser/src/autofill/background/overlay-notifications.background.ts b/apps/browser/src/autofill/background/overlay-notifications.background.ts index e252bdcc4af..ca8f05b77dc 100644 --- a/apps/browser/src/autofill/background/overlay-notifications.background.ts +++ b/apps/browser/src/autofill/background/overlay-notifications.background.ts @@ -6,6 +6,7 @@ import { ConfigService } from "@bitwarden/common/platform/abstractions/config/co import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { BrowserApi } from "../../platform/browser/browser-api"; +import { generateDomainMatchPatterns, isInvalidResponseStatusCode } from "../utils"; import { ActiveFormSubmissionRequests, @@ -109,35 +110,11 @@ export class OverlayNotificationsBackground implements OverlayNotificationsBackg */ private getSenderUrlMatchPatterns(sender: chrome.runtime.MessageSender) { return new Set([ - ...this.generateMatchPatterns(sender.url), - ...this.generateMatchPatterns(sender.tab.url), + ...generateDomainMatchPatterns(sender.url), + ...generateDomainMatchPatterns(sender.tab.url), ]); } - /** - * Generates the origin and subdomain match patterns for the URL. - * - * @param url - The URL of the tab - */ - private generateMatchPatterns(url: string): string[] { - try { - if (!url.startsWith("http")) { - url = `https://${url}`; - } - - const originMatchPattern = `${new URL(url).origin}/*`; - - const parsedUrl = new URL(url); - const splitHost = parsedUrl.hostname.split("."); - const domain = splitHost.slice(-2).join("."); - const subDomainMatchPattern = `${parsedUrl.protocol}//*.${domain}/*`; - - return [originMatchPattern, subDomainMatchPattern]; - } catch { - return []; - } - } - /** * Stores the login form data that was modified by the user in the content script. This data is * used to trigger the add login or change password notification when the form is submitted. @@ -329,7 +306,7 @@ export class OverlayNotificationsBackground implements OverlayNotificationsBackg private handleOnCompletedRequestEvent = async (details: chrome.webRequest.WebResponseDetails) => { if ( this.requestHostIsInvalid(details) || - this.isInvalidStatusCode(details.statusCode) || + isInvalidResponseStatusCode(details.statusCode) || !this.activeFormSubmissionRequests.has(details.requestId) ) { return; @@ -472,16 +449,6 @@ export class OverlayNotificationsBackground implements OverlayNotificationsBackg this.setupWebRequestsListeners(); }; - /** - * Determines if the status code of the web response is invalid. An invalid status code is - * any status code that is not in the 200-299 range. - * - * @param statusCode - The status code of the web response - */ - private isInvalidStatusCode = (statusCode: number) => { - return statusCode < 200 || statusCode >= 300; - }; - /** * Determines if the host of the web request is invalid. An invalid host is any host that does not * start with "http" or a tab id that is less than 0. diff --git a/apps/browser/src/autofill/background/overlay.background.spec.ts b/apps/browser/src/autofill/background/overlay.background.spec.ts index 30f19e7260a..b6a04f63d54 100644 --- a/apps/browser/src/autofill/background/overlay.background.spec.ts +++ b/apps/browser/src/autofill/background/overlay.background.spec.ts @@ -61,6 +61,7 @@ import { triggerPortOnDisconnectEvent, triggerPortOnMessageEvent, triggerWebNavigationOnCommittedEvent, + triggerWebRequestOnCompletedEvent, } from "../spec/testing-utils"; import { @@ -3003,37 +3004,95 @@ describe("OverlayBackground", () => { expect(copyToClipboardSpy).toHaveBeenCalledWith("totp-code"); }); - it("triggers passkey authentication through mediated conditional UI", async () => { - const fido2Credential = mock({ credentialId: "credential-id" }); - const cipher1 = mock({ - id: "inline-menu-cipher-1", - login: { - username: "username1", - password: "password1", - fido2Credentials: [fido2Credential], - }, - }); - overlayBackground["inlineMenuCiphers"] = new Map([["inline-menu-cipher-1", cipher1]]); - const pageDetailsForTab = { - frameId: sender.frameId, - tab: sender.tab, - details: pageDetails, - }; - overlayBackground["pageDetailsForTab"][sender.tab.id] = new Map([ - [sender.frameId, pageDetailsForTab], - ]); - autofillService.isPasswordRepromptRequired.mockResolvedValue(false); - jest.spyOn(fido2ActiveRequestManager, "getActiveRequest"); + describe("triggering passkey authentication", () => { + let cipher1: CipherView; - sendPortMessage(listMessageConnectorSpy, { - command: "fillAutofillInlineMenuCipher", - inlineMenuCipherId: "inline-menu-cipher-1", - usePasskey: true, - portKey, + beforeEach(() => { + const fido2Credential = mock({ credentialId: "credential-id" }); + cipher1 = mock({ + id: "inline-menu-cipher-1", + login: { + username: "username1", + password: "password1", + fido2Credentials: [fido2Credential], + }, + }); + const pageDetailsForTab = { + frameId: sender.frameId, + tab: sender.tab, + details: pageDetails, + }; + overlayBackground["inlineMenuCiphers"] = new Map([["inline-menu-cipher-1", cipher1]]); + overlayBackground["pageDetailsForTab"][sender.tab.id] = new Map([ + [sender.frameId, pageDetailsForTab], + ]); + autofillService.isPasswordRepromptRequired.mockResolvedValue(false); }); - await flushPromises(); - expect(fido2ActiveRequestManager.getActiveRequest).toHaveBeenCalledWith(sender.tab.id); + it("logs an error if the authentication could not complete due to a missing FIDO2 request", async () => { + jest.spyOn(logService, "error"); + + sendPortMessage(listMessageConnectorSpy, { + command: "fillAutofillInlineMenuCipher", + inlineMenuCipherId: "inline-menu-cipher-1", + usePasskey: true, + portKey, + }); + await flushPromises(); + + expect(logService.error).toHaveBeenCalled(); + }); + + describe("when the FIDO2 request is present", () => { + beforeEach(async () => { + void fido2ActiveRequestManager.newActiveRequest( + sender.tab.id, + cipher1.login.fido2Credentials, + new AbortController(), + ); + }); + + it("aborts all active FIDO2 requests if the subsequent request after the authentication is invalid", async () => { + jest.spyOn(fido2ActiveRequestManager, "removeActiveRequest"); + + sendPortMessage(listMessageConnectorSpy, { + command: "fillAutofillInlineMenuCipher", + inlineMenuCipherId: "inline-menu-cipher-1", + usePasskey: true, + portKey, + }); + await flushPromises(); + triggerWebRequestOnCompletedEvent( + mock({ + statusCode: 401, + }), + ); + + expect(fido2ActiveRequestManager.removeActiveRequest).toHaveBeenCalled(); + }); + + it("triggers a closure of the inline menu if the subsequent request after the authentication is valid", async () => { + jest.useFakeTimers(); + + await initOverlayElementPorts(); + sendPortMessage(listMessageConnectorSpy, { + command: "fillAutofillInlineMenuCipher", + inlineMenuCipherId: "inline-menu-cipher-1", + usePasskey: true, + portKey, + }); + triggerWebRequestOnCompletedEvent( + mock({ + statusCode: 200, + }), + ); + jest.advanceTimersByTime(3100); + + expect(listPortSpy.postMessage).toHaveBeenCalledWith({ + command: "triggerDelayedAutofillInlineMenuClosure", + }); + }); + }); }); }); diff --git a/apps/browser/src/autofill/background/overlay.background.ts b/apps/browser/src/autofill/background/overlay.background.ts index c8d250df509..653d31ca52c 100644 --- a/apps/browser/src/autofill/background/overlay.background.ts +++ b/apps/browser/src/autofill/background/overlay.background.ts @@ -55,7 +55,11 @@ import { MAX_SUB_FRAME_DEPTH, } from "../enums/autofill-overlay.enum"; import { AutofillService } from "../services/abstractions/autofill.service"; -import { generateRandomChars } from "../utils"; +import { + generateDomainMatchPatterns, + generateRandomChars, + isInvalidResponseStatusCode, +} from "../utils"; import { LockedVaultPendingNotificationsData } from "./abstractions/notification.background"; import { @@ -151,7 +155,7 @@ export class OverlayBackground implements OverlayBackgroundInterface { addEditCipherSubmitted: () => this.updateOverlayCiphers(), editedCipher: () => this.updateOverlayCiphers(), deletedCipher: () => this.updateOverlayCiphers(), - fido2AbortRequest: ({ sender }) => this.abortFido2ActiveRequest(sender), + fido2AbortRequest: ({ sender }) => this.abortFido2ActiveRequest(sender.tab.id), }; private readonly inlineMenuButtonPortMessageHandlers: InlineMenuButtonPortMessageHandlers = { triggerDelayedAutofillInlineMenuClosure: () => this.triggerDelayedInlineMenuClosure(), @@ -672,10 +676,10 @@ export class OverlayBackground implements OverlayBackgroundInterface { /** * Aborts an active FIDO2 request for a given tab and updates the inline menu ciphers. * - * @param sender - The sender of the message + * @param tabId - The id of the tab to abort the request for */ - private async abortFido2ActiveRequest(sender: chrome.runtime.MessageSender) { - this.fido2ActiveRequestManager.removeActiveRequest(sender.tab.id); + private async abortFido2ActiveRequest(tabId: number) { + this.fido2ActiveRequestManager.removeActiveRequest(tabId); await this.updateOverlayCiphers(false); } @@ -939,11 +943,10 @@ export class OverlayBackground implements OverlayBackgroundInterface { if (usePasskey && cipher.login?.hasFido2Credentials) { await this.authenticatePasskeyCredential( - sender.tab.id, + sender, cipher.login.fido2Credentials[0].credentialId, ); this.updateLastUsedInlineMenuCipher(inlineMenuCipherId, cipher); - this.closeInlineMenu(sender, { forceCloseInlineMenu: true }); return; } @@ -969,11 +972,11 @@ export class OverlayBackground implements OverlayBackgroundInterface { /** * Triggers a FIDO2 authentication from the inline menu using the passed credential ID. * - * @param tabId - The tab ID to trigger the authentication for + * @param sender - The sender of the port message * @param credentialId - The credential ID to authenticate */ - async authenticatePasskeyCredential(tabId: number, credentialId: string) { - const request = this.fido2ActiveRequestManager.getActiveRequest(tabId); + async authenticatePasskeyCredential(sender: chrome.runtime.MessageSender, credentialId: string) { + const request = this.fido2ActiveRequestManager.getActiveRequest(sender.tab.id); if (!request) { this.logService.error( "Could not complete passkey autofill due to missing active Fido2 request", @@ -981,9 +984,35 @@ export class OverlayBackground implements OverlayBackgroundInterface { return; } + chrome.webRequest.onCompleted.addListener(this.handlePasskeyAuthenticationOnCompleted, { + urls: generateDomainMatchPatterns(sender.tab.url), + }); request.subject.next({ type: Fido2ActiveRequestEvents.Continue, credentialId }); } + /** + * Handles the next web request that occurs after a passkey authentication has been completed. + * Ensures that the inline menu closes after the request, and that the FIDO2 request is aborted + * if the request is not successful. + * + * @param details - The web request details + */ + private handlePasskeyAuthenticationOnCompleted = ( + details: chrome.webRequest.WebResponseCacheDetails, + ) => { + chrome.webRequest.onCompleted.removeListener(this.handlePasskeyAuthenticationOnCompleted); + + if (isInvalidResponseStatusCode(details.statusCode)) { + this.closeInlineMenu({ tab: { id: details.tabId } } as chrome.runtime.MessageSender, { + forceCloseInlineMenu: true, + }); + this.abortFido2ActiveRequest(details.tabId).catch((error) => this.logService.error(error)); + return; + } + + globalThis.setTimeout(() => this.triggerDelayedInlineMenuClosure(), 3000); + }; + /** * Sets the most recently used cipher at the top of the list of ciphers. * @@ -1587,6 +1616,7 @@ export class OverlayBackground implements OverlayBackgroundInterface { passkeys: this.i18nService.translate("passkeys"), passwords: this.i18nService.translate("passwords"), logInWithPasskey: this.i18nService.translate("logInWithPasskeyAriaLabel"), + authenticating: this.i18nService.translate("authenticating"), }; } diff --git a/apps/browser/src/autofill/overlay/inline-menu/pages/list/__snapshots__/autofill-inline-menu-list.spec.ts.snap b/apps/browser/src/autofill/overlay/inline-menu/pages/list/__snapshots__/autofill-inline-menu-list.spec.ts.snap index 3339781fabf..0a4ae8d795f 100644 --- a/apps/browser/src/autofill/overlay/inline-menu/pages/list/__snapshots__/autofill-inline-menu-list.spec.ts.snap +++ b/apps/browser/src/autofill/overlay/inline-menu/pages/list/__snapshots__/autofill-inline-menu-list.spec.ts.snap @@ -2131,6 +2131,44 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers f `; +exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers for an authenticated user fill cipher button event listeners filling a cipher displays an \`Authenticating\` loader when a passkey cipher is filled 1`] = ` +
+
+ +
+
+`; + exports[`AutofillInlineMenuList initAutofillInlineMenuList the locked inline menu for an unauthenticated user creates the views for the locked inline menu 1`] = `
{ postWindowMessage(createInitAutofillInlineMenuListMessageMock({ portKey })); }); - it("allows the user to fill a cipher on click", () => { - const fillCipherButton = - autofillInlineMenuList["inlineMenuListContainer"].querySelector(".fill-cipher-button"); + describe("filling a cipher", () => { + it("allows the user to fill a cipher on click", () => { + const fillCipherButton = + autofillInlineMenuList["inlineMenuListContainer"].querySelector( + ".fill-cipher-button", + ); - fillCipherButton.dispatchEvent(new Event("click")); + fillCipherButton.dispatchEvent(new Event("click")); - expect(globalThis.parent.postMessage).toHaveBeenCalledWith( - { - command: "fillAutofillInlineMenuCipher", - inlineMenuCipherId: "1", - usePasskey: false, - portKey, - }, - "*", - ); + expect(globalThis.parent.postMessage).toHaveBeenCalledWith( + { + command: "fillAutofillInlineMenuCipher", + inlineMenuCipherId: "1", + usePasskey: false, + portKey, + }, + "*", + ); + }); + + it("displays an `Authenticating` loader when a passkey cipher is filled", async () => { + postWindowMessage( + createInitAutofillInlineMenuListMessageMock({ + ciphers: [ + createAutofillOverlayCipherDataMock(1, { + name: "https://example.com", + login: { + username: "username1", + passkey: { + rpName: "https://example.com", + userName: "username1", + }, + }, + }), + ], + showPasskeysLabels: true, + portKey, + }), + ); + await flushPromises(); + + const fillCipherButton = + autofillInlineMenuList["inlineMenuListContainer"].querySelector( + ".fill-cipher-button", + ); + + fillCipherButton.dispatchEvent(new Event("click")); + + expect(autofillInlineMenuList["inlineMenuListContainer"]).toMatchSnapshot(); + }); }); it("allows the user to move keyboard focus to the next cipher element on ArrowDown", () => { diff --git a/apps/browser/src/autofill/overlay/inline-menu/pages/list/autofill-inline-menu-list.ts b/apps/browser/src/autofill/overlay/inline-menu/pages/list/autofill-inline-menu-list.ts index da8cbdd200f..27a9c68d995 100644 --- a/apps/browser/src/autofill/overlay/inline-menu/pages/list/autofill-inline-menu-list.ts +++ b/apps/browser/src/autofill/overlay/inline-menu/pages/list/autofill-inline-menu-list.ts @@ -14,6 +14,7 @@ import { plusIcon, viewCipherIcon, passkeyIcon, + spinnerIcon, } from "../../../../utils/svg-icons"; import { AutofillInlineMenuListWindowMessageHandlers, @@ -40,6 +41,7 @@ export class AutofillInlineMenuList extends AutofillInlineMenuPageElement { private passkeysHeadingHeight: number; private lastPasskeysListItemHeight: number; private ciphersListHeight: number; + private isPasskeyAuthInProgress = false; private readonly showCiphersPerPage = 6; private readonly headingBorderClass = "inline-menu-list-heading--bordered"; private readonly inlineMenuListWindowMessageHandlers: AutofillInlineMenuListWindowMessageHandlers = @@ -156,15 +158,14 @@ export class AutofillInlineMenuList extends AutofillInlineMenuPageElement { ciphers: InlineMenuCipherData[], showInlineMenuAccountCreation?: boolean, ) { + if (this.isPasskeyAuthInProgress) { + return; + } + this.ciphers = ciphers; this.currentCipherIndex = 0; this.showInlineMenuAccountCreation = showInlineMenuAccountCreation; - if (this.inlineMenuListContainer) { - this.inlineMenuListContainer.innerHTML = ""; - this.inlineMenuListContainer.classList.remove( - "inline-menu-list-container--with-new-item-button", - ); - } + this.resetInlineMenuContainer(); if (!ciphers?.length) { this.buildNoResultsInlineMenuList(); @@ -191,6 +192,18 @@ export class AutofillInlineMenuList extends AutofillInlineMenuPageElement { this.newItemButtonElement.addEventListener(EVENTS.KEYUP, this.handleNewItemButtonKeyUpEvent); } + /** + * Clears and resets the inline menu list container. + */ + private resetInlineMenuContainer() { + if (this.inlineMenuListContainer) { + this.inlineMenuListContainer.innerHTML = ""; + this.inlineMenuListContainer.classList.remove( + "inline-menu-list-container--with-new-item-button", + ); + } + } + /** * Inline menu view that is presented when no ciphers are found for a given page. * Facilitates the ability to add a new vault item from the inline menu. @@ -330,7 +343,7 @@ export class AutofillInlineMenuList extends AutofillInlineMenuPageElement { this.ciphersList.addEventListener( EVENTS.SCROLL, this.useEventHandlersMemo( - throttle(() => this.updatePasskeysHeadingsOnScroll(this.ciphersList.scrollTop), 50), + throttle(this.handleThrottledOnScrollEvent, 50), UPDATE_PASSKEYS_HEADINGS_ON_SCROLL, ), options, @@ -342,7 +355,10 @@ export class AutofillInlineMenuList extends AutofillInlineMenuPageElement { * Handles updating the list of ciphers when the * user scrolls to the bottom of the list. */ - private updateCiphersListOnScroll = () => { + private updateCiphersListOnScroll = (event: MouseEvent) => { + event.preventDefault(); + event.stopPropagation(); + if (this.cipherListScrollIsDebounced) { return; } @@ -382,6 +398,18 @@ export class AutofillInlineMenuList extends AutofillInlineMenuPageElement { } }; + /** + * Throttled handler for updating the passkeys and login headings when the user scrolls the ciphers list. + * + * @param event - The scroll event. + */ + private handleThrottledOnScrollEvent = (event: MouseEvent) => { + event.preventDefault(); + event.stopPropagation(); + + this.updatePasskeysHeadingsOnScroll(this.ciphersList.scrollTop); + }; + /** * Updates the passkeys and login headings when the user scrolls the ciphers list. * @@ -596,16 +624,29 @@ export class AutofillInlineMenuList extends AutofillInlineMenuPageElement { private handleFillCipherClickEvent = (cipher: InlineMenuCipherData) => { const usePasskey = !!cipher.login?.passkey; return this.useEventHandlersMemo( - () => - this.postMessageToParent({ - command: "fillAutofillInlineMenuCipher", - inlineMenuCipherId: cipher.id, - usePasskey, - }), + () => this.triggerFillCipherClickEvent(cipher, usePasskey), `${cipher.id}-fill-cipher-button-click-handler-${usePasskey ? "passkey" : ""}`, ); }; + /** + * Triggers a fill of the currently selected cipher. + * + * @param cipher - The cipher to fill. + * @param usePasskey - Whether the cipher uses a passkey. + */ + private triggerFillCipherClickEvent = (cipher: InlineMenuCipherData, usePasskey: boolean) => { + if (usePasskey) { + this.createPasskeyAuthenticatingLoader(); + } + + this.postMessageToParent({ + command: "fillAutofillInlineMenuCipher", + inlineMenuCipherId: cipher.id, + usePasskey, + }); + }; + /** * Handles the keyup event for the fill cipher button. Facilitates * selecting the next/previous cipher item on ArrowDown/ArrowUp. Also @@ -889,6 +930,26 @@ export class AutofillInlineMenuList extends AutofillInlineMenuPageElement { return cipherDetailsElement; } + /** + * Creates an indicator for the user that the passkey is being authenticated. + */ + private createPasskeyAuthenticatingLoader() { + this.isPasskeyAuthInProgress = true; + this.resetInlineMenuContainer(); + + const passkeyAuthenticatingLoader = globalThis.document.createElement("div"); + passkeyAuthenticatingLoader.classList.add("passkey-authenticating-loader"); + passkeyAuthenticatingLoader.textContent = this.getTranslation("authenticating"); + passkeyAuthenticatingLoader.appendChild(buildSvgDomElement(spinnerIcon)); + + this.inlineMenuListContainer.appendChild(passkeyAuthenticatingLoader); + + globalThis.setTimeout(() => { + this.isPasskeyAuthInProgress = false; + this.postMessageToParent({ command: "checkAutofillInlineMenuButtonFocused" }); + }, 4000); + } + /** * Gets the subtitle text for a given cipher. * diff --git a/apps/browser/src/autofill/overlay/inline-menu/pages/list/list.scss b/apps/browser/src/autofill/overlay/inline-menu/pages/list/list.scss index 9cd8ae1a73c..fb12da78f48 100644 --- a/apps/browser/src/autofill/overlay/inline-menu/pages/list/list.scss +++ b/apps/browser/src/autofill/overlay/inline-menu/pages/list/list.scss @@ -15,6 +15,8 @@ body { width: 100%; padding: 0; margin: 0; + font-family: $font-family-sans-serif; + font-weight: 400; @include themify($themes) { color: themed("textColor"); @@ -23,8 +25,6 @@ body { } .inline-menu-list-message { - font-family: $font-family-sans-serif; - font-weight: 400; font-size: 1.4rem; line-height: 1.5; width: 100%; @@ -393,3 +393,38 @@ body { } } } + +@keyframes bwi-spin { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(359deg); + } +} + +.passkey-authenticating-loader { + display: flex; + align-content: center; + align-items: center; + justify-content: center; + text-align: center; + padding: 1rem 0.8rem; + font-size: 1.4rem; + font-weight: 400; + + @include themify($themes) { + color: themed("passkeysAuthenticating"); + } + + svg { + animation: bwi-spin 2s infinite linear; + margin-left: 1rem; + + path { + @include themify($themes) { + fill: themed("passkeysAuthenticating") !important; + } + } + } +} diff --git a/apps/browser/src/autofill/services/autofill.service.ts b/apps/browser/src/autofill/services/autofill.service.ts index 5d9bfa9f9d4..de79fd974ef 100644 --- a/apps/browser/src/autofill/services/autofill.service.ts +++ b/apps/browser/src/autofill/services/autofill.service.ts @@ -237,7 +237,9 @@ export default class AutofillService implements AutofillServiceInterface { FeatureFlag.InlineMenuPositioningImprovements, ); if (!inlineMenuPositioningImprovements) { - return "bootstrap-legacy-autofill-overlay.js"; + return !inlineMenuVisibility + ? "bootstrap-autofill.js" + : "bootstrap-legacy-autofill-overlay.js"; } const enableChangedPasswordPrompt = await firstValueFrom( @@ -3017,9 +3019,11 @@ export default class AutofillService implements AutofillServiceInterface { const tabs = await BrowserApi.tabsQuery({}); for (let index = 0; index < tabs.length; index++) { const tab = tabs[index]; - if (tab.url?.startsWith("http")) { + if (tab?.id && tab.url?.startsWith("http")) { const frames = await BrowserApi.getAllFrameDetails(tab.id); - frames.forEach((frame) => this.injectAutofillScripts(tab, frame.frameId, false)); + if (frames) { + frames.forEach((frame) => this.injectAutofillScripts(tab, frame.frameId, false)); + } } } } diff --git a/apps/browser/src/autofill/shared/styles/variables.scss b/apps/browser/src/autofill/shared/styles/variables.scss index 40b0080bb02..bd75415a198 100644 --- a/apps/browser/src/autofill/shared/styles/variables.scss +++ b/apps/browser/src/autofill/shared/styles/variables.scss @@ -10,6 +10,7 @@ $border-color: #ced4dc; $border-color-dark: #ddd; $border-radius: 3px; $focus-outline-color: #1252a3; +$muted-blue: #5a6d91; $brand-primary: #175ddc; @@ -45,6 +46,7 @@ $themes: ( focusOutlineColor: $focus-outline-color, successColor: $success-color-light, errorColor: $error-color-light, + passkeysAuthenticating: $muted-blue, ), dark: ( textColor: #ffffff, @@ -60,6 +62,7 @@ $themes: ( focusOutlineColor: lighten($focus-outline-color, 25%), successColor: $success-color-dark, errorColor: $error-color-dark, + passkeysAuthenticating: #bac0ce, ), nord: ( textColor: $nord5, @@ -74,6 +77,7 @@ $themes: ( borderColor: $nord0, focusOutlineColor: lighten($focus-outline-color, 25%), successColor: $success-color-dark, + passkeysAuthenticating: $nord4, ), solarizedDark: ( textColor: $solarizedDarkBase2, @@ -89,6 +93,7 @@ $themes: ( borderColor: $solarizedDarkBase2, focusOutlineColor: lighten($focus-outline-color, 15%), successColor: $success-color-dark, + passkeysAuthenticating: $solarizedDarkBase2, ), ); diff --git a/apps/browser/src/autofill/utils/index.ts b/apps/browser/src/autofill/utils/index.ts index 98c0a97ac56..f2fafac3d8c 100644 --- a/apps/browser/src/autofill/utils/index.ts +++ b/apps/browser/src/autofill/utils/index.ts @@ -426,3 +426,50 @@ export function getSubmitButtonKeywordsSet(element: HTMLElement): Set { return keywordsSet; } + +/** + * Generates the origin and subdomain match patterns for the URL. + * + * @param url - The URL of the tab + */ +export function generateDomainMatchPatterns(url: string): string[] { + try { + const extensionUrlPattern = + /^(chrome|chrome-extension|moz-extension|safari-web-extension):\/\/\/?/; + if (extensionUrlPattern.test(url)) { + return []; + } + + // Add protocol to URL if it is missing to allow for parsing the hostname correctly + const urlPattern = /^(https?|file):\/\/\/?/; + if (!urlPattern.test(url)) { + url = `https://${url}`; + } + + let protocolGlob = "*://"; + if (url.startsWith("file:///")) { + protocolGlob = "*:///"; // File URLs require three slashes to be a valid match pattern + } + + const parsedUrl = new URL(url); + const originMatchPattern = `${protocolGlob}${parsedUrl.hostname}/*`; + + const splitHost = parsedUrl.hostname.split("."); + const domain = splitHost.slice(-2).join("."); + const subDomainMatchPattern = `${protocolGlob}*.${domain}/*`; + + return [originMatchPattern, subDomainMatchPattern]; + } catch { + return []; + } +} + +/** + * Determines if the status code of the web response is invalid. An invalid status code is + * any status code that is not in the 200-299 range. + * + * @param statusCode - The status code of the web response + */ +export function isInvalidResponseStatusCode(statusCode: number) { + return statusCode < 200 || statusCode >= 300; +} diff --git a/apps/browser/src/autofill/utils/svg-icons.ts b/apps/browser/src/autofill/utils/svg-icons.ts index df2cfa189f9..908e57f2cba 100644 --- a/apps/browser/src/autofill/utils/svg-icons.ts +++ b/apps/browser/src/autofill/utils/svg-icons.ts @@ -27,3 +27,6 @@ export const passkeyIcon = export const circleCheckIcon = ''; + +export const spinnerIcon = + ''; diff --git a/apps/browser/src/tools/popup/generator/credential-generator.component.html b/apps/browser/src/tools/popup/generator/credential-generator.component.html index 45a6c67f78b..932816ba7a6 100644 --- a/apps/browser/src/tools/popup/generator/credential-generator.component.html +++ b/apps/browser/src/tools/popup/generator/credential-generator.component.html @@ -1 +1,2 @@ - + + diff --git a/apps/browser/src/tools/popup/generator/credential-generator.component.ts b/apps/browser/src/tools/popup/generator/credential-generator.component.ts index 16938fbe79f..760f0627abd 100644 --- a/apps/browser/src/tools/popup/generator/credential-generator.component.ts +++ b/apps/browser/src/tools/popup/generator/credential-generator.component.ts @@ -1,11 +1,12 @@ import { Component } from "@angular/core"; -import { PasswordGeneratorComponent } from "@bitwarden/generator-components"; +import { SectionComponent } from "@bitwarden/components"; +import { UsernameGeneratorComponent } from "@bitwarden/generator-components"; @Component({ standalone: true, selector: "credential-generator", templateUrl: "credential-generator.component.html", - imports: [PasswordGeneratorComponent], + imports: [UsernameGeneratorComponent, SectionComponent], }) export class CredentialGeneratorComponent {} diff --git a/apps/browser/src/tools/popup/send-v2/add-edit/send-add-edit.component.html b/apps/browser/src/tools/popup/send-v2/add-edit/send-add-edit.component.html index 7f723cc7364..b3783bfed3a 100644 --- a/apps/browser/src/tools/popup/send-v2/add-edit/send-add-edit.component.html +++ b/apps/browser/src/tools/popup/send-v2/add-edit/send-add-edit.component.html @@ -9,6 +9,8 @@ > + + + + + diff --git a/apps/browser/src/tools/popup/send-v2/send-file-popout-dialog/send-file-popout-dialog.component.ts b/apps/browser/src/tools/popup/send-v2/send-file-popout-dialog/send-file-popout-dialog.component.ts new file mode 100644 index 00000000000..fb21b5bb026 --- /dev/null +++ b/apps/browser/src/tools/popup/send-v2/send-file-popout-dialog/send-file-popout-dialog.component.ts @@ -0,0 +1,25 @@ +import { CommonModule } from "@angular/common"; +import { Component } from "@angular/core"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { ButtonModule, DialogModule, DialogService, TypographyModule } from "@bitwarden/components"; + +import BrowserPopupUtils from "../../../../platform/popup/browser-popup-utils"; + +@Component({ + selector: "send-file-popout-dialog", + templateUrl: "./send-file-popout-dialog.component.html", + standalone: true, + imports: [JslibModule, CommonModule, DialogModule, ButtonModule, TypographyModule], +}) +export class SendFilePopoutDialogComponent { + constructor(private dialogService: DialogService) {} + + async popOutWindow() { + await BrowserPopupUtils.openCurrentPagePopout(window); + } + + close() { + this.dialogService.closeAll(); + } +} diff --git a/apps/browser/src/tools/popup/send-v2/send-v2.component.html b/apps/browser/src/tools/popup/send-v2/send-v2.component.html index 698901d8460..23582f19115 100644 --- a/apps/browser/src/tools/popup/send-v2/send-v2.component.html +++ b/apps/browser/src/tools/popup/send-v2/send-v2.component.html @@ -1,4 +1,4 @@ - + diff --git a/apps/browser/src/tools/popup/send-v2/send-v2.component.spec.ts b/apps/browser/src/tools/popup/send-v2/send-v2.component.spec.ts index 63e3c2d2fc6..506d7146dd6 100644 --- a/apps/browser/src/tools/popup/send-v2/send-v2.component.spec.ts +++ b/apps/browser/src/tools/popup/send-v2/send-v2.component.spec.ts @@ -59,6 +59,7 @@ describe("SendV2Component", () => { { id: "1", name: "Send A" }, { id: "2", name: "Send B" }, ] as SendView[]), + loading$: of(false), latestSearchText$: of(""), }); diff --git a/apps/browser/src/tools/popup/send-v2/send-v2.component.ts b/apps/browser/src/tools/popup/send-v2/send-v2.component.ts index 19fff402e2e..2766ba56c95 100644 --- a/apps/browser/src/tools/popup/send-v2/send-v2.component.ts +++ b/apps/browser/src/tools/popup/send-v2/send-v2.component.ts @@ -51,17 +51,13 @@ export enum SendState { }) export class SendV2Component implements OnInit, OnDestroy { sendType = SendType; - sendState = SendState; protected listState: SendState | null = null; - protected sends$ = this.sendItemsService.filteredAndSortedSends$; - + protected sendsLoading$ = this.sendItemsService.loading$; protected title: string = "allSends"; - protected noItemIcon = NoSendsIcon; - protected noResultsIcon = Icons.NoResults; protected sendsDisabled = false; diff --git a/apps/browser/store/locales/zh_TW/copy.resx b/apps/browser/store/locales/zh_TW/copy.resx index 27080965cb3..3005d6bdcba 100644 --- a/apps/browser/store/locales/zh_TW/copy.resx +++ b/apps/browser/store/locales/zh_TW/copy.resx @@ -118,7 +118,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Bitwarden 密碼管理器 + Bitwarden - 免費密碼管理工具 無論在家、在辦公或在途中,Bitwarden 都能輕易的保護你的密碼、登入金鑰和敏感資訊。 diff --git a/apps/desktop/desktop_native/Cargo.lock b/apps/desktop/desktop_native/Cargo.lock index 603feabe136..347f8dd3f4f 100644 --- a/apps/desktop/desktop_native/Cargo.lock +++ b/apps/desktop/desktop_native/Cargo.lock @@ -85,9 +85,9 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7ebdfa2ebdab6b1760375fa7d6f382b9f486eac35fc994625a00e89280bdbb7" +checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" dependencies = [ "async-task", "concurrent-queue", @@ -139,9 +139,9 @@ dependencies = [ [[package]] name = "async-process" -version = "2.2.4" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8a07789659a4d385b79b18b9127fc27e1a59e1e89117c78c5ea3b806f016374" +checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb" dependencies = [ "async-channel", "async-io", @@ -154,7 +154,6 @@ dependencies = [ "futures-lite", "rustix", "tracing", - "windows-sys 0.59.0", ] [[package]] @@ -194,9 +193,9 @@ checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.81" +version = "0.1.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", @@ -290,9 +289,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.1" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" [[package]] name = "cbc" @@ -305,9 +304,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.15" +version = "1.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57b6a275aa2903740dc87da01c62040406b8812552e97129a63ea8850a17c6e6" +checksum = "07b1695e2c7e8fc85310cde85aeaab7e3097f593c91d209d3f9df76c928100f0" dependencies = [ "shlex", ] @@ -405,9 +404,9 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] @@ -603,9 +602,9 @@ dependencies = [ [[package]] name = "error-code" -version = "3.2.0" +version = "3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0474425d51df81997e2f90a21591180b38eccf27292d755f3e30750225c175b" +checksum = "a5d9305ccc6942a704f4335694ecd3de2ea531b114ac2d51f5f843750787a92f" [[package]] name = "event-listener" @@ -1074,9 +1073,9 @@ dependencies = [ [[package]] name = "napi-derive-backend" -version = "1.0.73" +version = "1.0.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cd81b794fc1d6051acf8c4f3cb4f82833b0621272a232b4ff0cf3df1dbddb61" +checksum = "967c485e00f0bf3b1bdbe510a38a4606919cf1d34d9a37ad41f25a81aa077abe" dependencies = [ "convert_case", "once_cell", @@ -1277,9 +1276,9 @@ dependencies = [ [[package]] name = "parking" -version = "2.2.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" @@ -1339,9 +1338,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "polling" @@ -1387,9 +1386,9 @@ dependencies = [ [[package]] name = "quick-xml" -version = "0.34.0" +version = "0.36.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f24d770aeca0eacb81ac29dfbc55ebcc09312fdd1f8bbecdc7e4a84e000e3b4" +checksum = "f7649a7b4df05aed9ea7ec6f628c67c9953a43869b8bc50929569b2999d443fe" dependencies = [ "memchr", ] @@ -1435,9 +1434,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.3" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +checksum = "62871f2d65009c0256aed1b9cfeeb8ac272833c404e13d53d400cd0dad7a2ac0" dependencies = [ "bitflags", ] @@ -1548,18 +1547,18 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.209" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.209" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", @@ -1763,9 +1762,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.20" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ "indexmap", "serde", @@ -1838,21 +1837,21 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-segmentation" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "version-compare" @@ -1874,9 +1873,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wayland-backend" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90e11ce2ca99c97b940ee83edbae9da2d56a08f9ea8158550fd77fa31722993" +checksum = "056535ced7a150d45159d3a8dc30f91a2e2d588ca0b23f70e56033622b8016f6" dependencies = [ "cc", "downcast-rs", @@ -1888,9 +1887,9 @@ dependencies = [ [[package]] name = "wayland-client" -version = "0.31.5" +version = "0.31.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e321577a0a165911bdcfb39cf029302479d7527b517ee58ab0f6ad09edf0943" +checksum = "e3f45d1222915ef1fd2057220c1d9d9624b7654443ea35c3877f7a52bd0a5a2d" dependencies = [ "bitflags", "rustix", @@ -1925,9 +1924,9 @@ dependencies = [ [[package]] name = "wayland-scanner" -version = "0.31.4" +version = "0.31.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7b56f89937f1cf2ee1f1259cf2936a17a1f45d8f0aa1019fae6d470d304cfa6" +checksum = "597f2001b2e5fc1121e3d5b9791d3e78f05ba6bfa4641053846248e3a13661c3" dependencies = [ "proc-macro2", "quick-xml", @@ -1936,9 +1935,9 @@ dependencies = [ [[package]] name = "wayland-sys" -version = "0.31.4" +version = "0.31.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43676fe2daf68754ecf1d72026e4e6c15483198b5d24e888b74d3f22f887a148" +checksum = "efa8ac0d8e8ed3e3b5c9fc92c7881406a268e11555abe36493efabe649a29e09" dependencies = [ "dlib", "log", @@ -2176,9 +2175,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.18" +version = "0.6.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" +checksum = "c52ac009d615e79296318c1bcce2d422aaca15ad08515e344feeda07df67a587" dependencies = [ "memchr", ] diff --git a/apps/desktop/native-messaging-test-runner/package-lock.json b/apps/desktop/native-messaging-test-runner/package-lock.json index c9bc710b537..48dfbfd6fcb 100644 --- a/apps/desktop/native-messaging-test-runner/package-lock.json +++ b/apps/desktop/native-messaging-test-runner/package-lock.json @@ -46,8 +46,6 @@ }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" @@ -58,23 +56,17 @@ }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "version": "1.4.15", "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", @@ -82,27 +74,19 @@ } }, "node_modules/@tsconfig/node10": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "version": "1.0.10", "license": "MIT" }, "node_modules/@tsconfig/node12": { "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", "license": "MIT" }, "node_modules/@tsconfig/node14": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", "license": "MIT" }, "node_modules/@tsconfig/node16": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "license": "MIT" }, "node_modules/@types/node": { @@ -116,8 +100,6 @@ }, "node_modules/@types/node-ipc": { "version": "9.2.3", - "resolved": "https://registry.npmjs.org/@types/node-ipc/-/node-ipc-9.2.3.tgz", - "integrity": "sha512-/MvSiF71fYf3+zwqkh/zkVkZj1hl1Uobre9EMFy08mqfJNAmpR0vmPgOUdEIDVgifxHj6G1vYMPLSBLLxoDACQ==", "dev": true, "license": "MIT", "dependencies": { @@ -125,9 +107,7 @@ } }, "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "version": "8.11.3", "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -137,21 +117,14 @@ } }, "node_modules/acorn-walk": { - "version": "8.3.3", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", - "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "version": "8.3.2", "license": "MIT", - "dependencies": { - "acorn": "^8.11.0" - }, "engines": { "node": ">=0.4.0" } }, "node_modules/ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "license": "MIT", "engines": { "node": ">=8" @@ -159,8 +132,6 @@ }, "node_modules/ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -174,14 +145,10 @@ }, "node_modules/arg": { "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "license": "MIT" }, "node_modules/cliui": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "license": "ISC", "dependencies": { "string-width": "^4.2.0", @@ -194,8 +161,6 @@ }, "node_modules/color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -206,20 +171,14 @@ }, "node_modules/color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/create-require": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "license": "MIT" }, "node_modules/diff": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" @@ -227,8 +186,6 @@ }, "node_modules/easy-stack": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/easy-stack/-/easy-stack-1.0.1.tgz", - "integrity": "sha512-wK2sCs4feiiJeFXn3zvY0p41mdU5VUgbgs1rNsc/y5ngFUijdWd+iIN8eoyuZHKB8xN6BL4PdWmzqFmxNg6V2w==", "license": "MIT", "engines": { "node": ">=6.0.0" @@ -236,14 +193,10 @@ }, "node_modules/emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "license": "MIT" }, "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "version": "3.1.2", "license": "MIT", "engines": { "node": ">=6" @@ -251,8 +204,6 @@ }, "node_modules/event-pubsub": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/event-pubsub/-/event-pubsub-4.3.0.tgz", - "integrity": "sha512-z7IyloorXvKbFx9Bpie2+vMJKKx1fH1EN5yiTfp8CiLOTptSYy1g8H4yDpGlEdshL1PBiFtBHepF2cNsqeEeFQ==", "license": "Unlicense", "engines": { "node": ">=4.0.0" @@ -260,8 +211,6 @@ }, "node_modules/get-caller-file": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" @@ -269,8 +218,6 @@ }, "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", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "license": "MIT", "engines": { "node": ">=8" @@ -278,8 +225,6 @@ }, "node_modules/js-message": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/js-message/-/js-message-1.0.7.tgz", - "integrity": "sha512-efJLHhLjIyKRewNS9EGZ4UpI8NguuL6fKkhRxVuMmrGV2xN/0APGdQYwLFky5w9naebSZ0OwAGp0G6/2Cg90rA==", "license": "MIT", "engines": { "node": ">=0.6.0" @@ -287,8 +232,6 @@ }, "node_modules/js-queue": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/js-queue/-/js-queue-2.0.2.tgz", - "integrity": "sha512-pbKLsbCfi7kriM3s1J4DDCo7jQkI58zPLHi0heXPzPlj0hjUsm+FesPUbE0DSbIVIK503A36aUBoCN7eMFedkA==", "license": "MIT", "dependencies": { "easy-stack": "^1.0.1" @@ -299,20 +242,14 @@ }, "node_modules/make-error": { "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "license": "ISC" }, "node_modules/module-alias": { "version": "2.2.3", - "resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.2.3.tgz", - "integrity": "sha512-23g5BFj4zdQL/b6tor7Ji+QY4pEfNH784BMslY9Qb0UnJWRAt+lQGLYmRaM0KDBwIG23ffEBELhZDP2rhi9f/Q==", "license": "MIT" }, "node_modules/node-ipc": { "version": "9.2.1", - "resolved": "https://registry.npmjs.org/node-ipc/-/node-ipc-9.2.1.tgz", - "integrity": "sha512-mJzaM6O3xHf9VT8BULvJSbdVbmHUKRNOH7zDDkCrA1/T+CVjq2WVIDfLt0azZRXpgArJtl3rtmEozrbXPZ9GaQ==", "license": "MIT", "dependencies": { "event-pubsub": "4.3.0", @@ -325,8 +262,6 @@ }, "node_modules/require-directory": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -334,8 +269,6 @@ }, "node_modules/string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -348,8 +281,6 @@ }, "node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -403,8 +334,6 @@ }, "node_modules/typescript": { "version": "4.7.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", - "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -435,14 +364,10 @@ }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "license": "MIT" }, "node_modules/wrap-ansi": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -458,8 +383,6 @@ }, "node_modules/y18n": { "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "license": "ISC", "engines": { "node": ">=10" @@ -467,8 +390,6 @@ }, "node_modules/yargs": { "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "license": "MIT", "dependencies": { "cliui": "^8.0.1", @@ -485,8 +406,6 @@ }, "node_modules/yargs-parser": { "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "license": "ISC", "engines": { "node": ">=12" @@ -494,8 +413,6 @@ }, "node_modules/yn": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "license": "MIT", "engines": { "node": ">=6" diff --git a/apps/desktop/src/app/accounts/settings.component.html b/apps/desktop/src/app/accounts/settings.component.html index 891314aa568..02b64a757a7 100644 --- a/apps/desktop/src/app/accounts/settings.component.html +++ b/apps/desktop/src/app/accounts/settings.component.html @@ -382,7 +382,7 @@
{{ - "enableBrowserIntegrationDesc" | i18n + "enableBrowserIntegrationDesc1" | i18n }}
diff --git a/apps/desktop/src/locales/af/messages.json b/apps/desktop/src/locales/af/messages.json index 8e004383e3c..87b39f14c3d 100644 --- a/apps/desktop/src/locales/af/messages.json +++ b/apps/desktop/src/locales/af/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Vermy dubbelsinnige karakters" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Deursoek versameling" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Aktiveer blaaierintegrasie" }, - "enableBrowserIntegrationDesc": { - "message": "Blaaierintegrasie word gebruik vir biometrie in blaaier." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Staan DuckDuckGo-blaaierintegrasie toe" diff --git a/apps/desktop/src/locales/ar/messages.json b/apps/desktop/src/locales/ar/messages.json index e92c7b104bd..51e74e5cd20 100644 --- a/apps/desktop/src/locales/ar/messages.json +++ b/apps/desktop/src/locales/ar/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "تجنب الأحرف الغامضة" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "بحث عن مجموعة" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "السماح بتكامل المتصفح" }, - "enableBrowserIntegrationDesc": { - "message": "يتم استخدام تكامل المتصفح للقياسات الحيوية في المتصفح." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "السماح بدمج متصفح DuckDuckGo" diff --git a/apps/desktop/src/locales/az/messages.json b/apps/desktop/src/locales/az/messages.json index 68000b3bf48..692604f26f0 100644 --- a/apps/desktop/src/locales/az/messages.json +++ b/apps/desktop/src/locales/az/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Anlaşılmaz simvollardan çəkinin" }, + "generatorPolicyInEffect": { + "message": "Müəssisə siyasət tələbləri, yaradıcı seçimlərinizə tətbiq edildi.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Kolleksiya axtar" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Brauzer inteqrasiyasını fəallaşdır" }, - "enableBrowserIntegrationDesc": { - "message": "Brauzerdə biometriklər üçün istifadə olunur." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "DuckDuckGo brauzer inteqrasiyasına icazə ver" diff --git a/apps/desktop/src/locales/be/messages.json b/apps/desktop/src/locales/be/messages.json index 8d8d5ad3773..ea66f782edb 100644 --- a/apps/desktop/src/locales/be/messages.json +++ b/apps/desktop/src/locales/be/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Пазбягаць неадназначных сімвалаў" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Пошук у калекцыі" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Дазволіць інтэграцыю з браўзерам" }, - "enableBrowserIntegrationDesc": { - "message": "Выкарыстоўваецца для біяметрыі ў браўзеры." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Дазволіць інтэграцыю браўзера з DuckDuckGo" diff --git a/apps/desktop/src/locales/bg/messages.json b/apps/desktop/src/locales/bg/messages.json index dde9a23d3a3..228be0bf875 100644 --- a/apps/desktop/src/locales/bg/messages.json +++ b/apps/desktop/src/locales/bg/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Без нееднозначни знаци" }, + "generatorPolicyInEffect": { + "message": "Изискванията на политиката за големи компании бяха приложени към настройките на генератора.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Търсене в колекцията" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Включване на интеграцията с браузър" }, - "enableBrowserIntegrationDesc": { - "message": "За потвърждаване с биометрични данни е необходима интеграция с браузъра." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Разрешаване на интеграцията на DuckDuckGo в браузъра" diff --git a/apps/desktop/src/locales/bn/messages.json b/apps/desktop/src/locales/bn/messages.json index 12c6d10501a..8601e2e1a72 100644 --- a/apps/desktop/src/locales/bn/messages.json +++ b/apps/desktop/src/locales/bn/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "অস্পষ্ট বর্ণগুলি এড়িয়ে চলুন" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "সংগ্রহ অনুসন্ধান" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Allow browser integration" }, - "enableBrowserIntegrationDesc": { - "message": "Used for biometrics in browser." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Allow DuckDuckGo browser integration" diff --git a/apps/desktop/src/locales/bs/messages.json b/apps/desktop/src/locales/bs/messages.json index 4da0dbee9ee..de9710e60ec 100644 --- a/apps/desktop/src/locales/bs/messages.json +++ b/apps/desktop/src/locales/bs/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Izbjegavaj dvosmislene znakove" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Pretraži kolekciju" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Allow browser integration" }, - "enableBrowserIntegrationDesc": { - "message": "Used for biometrics in browser." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Allow DuckDuckGo browser integration" diff --git a/apps/desktop/src/locales/ca/messages.json b/apps/desktop/src/locales/ca/messages.json index 6ca0aac1845..87c51542292 100644 --- a/apps/desktop/src/locales/ca/messages.json +++ b/apps/desktop/src/locales/ca/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Eviteu caràcters ambigus" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Cerca en la col·lecció" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Habilita la integració amb el navegador" }, - "enableBrowserIntegrationDesc": { - "message": "S'utilitza per a la biometria al navegador." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Permet la integració del navegador DuckDuckGo" diff --git a/apps/desktop/src/locales/cs/messages.json b/apps/desktop/src/locales/cs/messages.json index f40ba19f169..1f316f5c051 100644 --- a/apps/desktop/src/locales/cs/messages.json +++ b/apps/desktop/src/locales/cs/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Nepoužívat zaměnitelné znaky" }, + "generatorPolicyInEffect": { + "message": "Na volby generátoru byly uplatněny požadavky podnikových zásad.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Prohledat kolekci" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Povolit integraci prohlížeče" }, - "enableBrowserIntegrationDesc": { - "message": "Integrace prohlížeče se používá pro biometriku v prohlížeči." + "enableBrowserIntegrationDesc1": { + "message": "Použito k povolení biometrického odemknutí v prohlížečích, které nejsou Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Povolit integraci prohlížeče DuckDuckGo" diff --git a/apps/desktop/src/locales/cy/messages.json b/apps/desktop/src/locales/cy/messages.json index 3ac19a2ada8..6de2dc0a898 100644 --- a/apps/desktop/src/locales/cy/messages.json +++ b/apps/desktop/src/locales/cy/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Avoid ambiguous characters" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Search collection" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Allow browser integration" }, - "enableBrowserIntegrationDesc": { - "message": "Used for biometrics in browser." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Allow DuckDuckGo browser integration" diff --git a/apps/desktop/src/locales/da/messages.json b/apps/desktop/src/locales/da/messages.json index c4f5a081040..e6725a1d901 100644 --- a/apps/desktop/src/locales/da/messages.json +++ b/apps/desktop/src/locales/da/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Undgå tvetydige tegn" }, + "generatorPolicyInEffect": { + "message": "Virksomhedspolitikkrav gør sig gældende på generatorvalgmulighder.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Søg i samling" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Tillad browserintegration" }, - "enableBrowserIntegrationDesc": { - "message": "Bruges til biometri i browser." + "enableBrowserIntegrationDesc1": { + "message": "Bruges til at tillade biometrisk oplåsning i ikke-Safari webbrowsere." }, "enableDuckDuckGoBrowserIntegration": { "message": "Tillad DuckDuckGo-browserintegration" diff --git a/apps/desktop/src/locales/de/messages.json b/apps/desktop/src/locales/de/messages.json index 6f64e8cfcf6..a6209e823bc 100644 --- a/apps/desktop/src/locales/de/messages.json +++ b/apps/desktop/src/locales/de/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Mehrdeutige Zeichen vermeiden" }, + "generatorPolicyInEffect": { + "message": "Die Unternehmensrichtlinien-Anforderungen wurden auf deine Generator-Optionen angewendet.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Sammlung durchsuchen" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Browser-Integration erlauben" }, - "enableBrowserIntegrationDesc": { - "message": "Die Browser-Integration wird für Biometrie im Browser verwendet." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "DuckDuckGo Browser-Integration erlauben" diff --git a/apps/desktop/src/locales/el/messages.json b/apps/desktop/src/locales/el/messages.json index f9093d904b8..d9fdc62d654 100644 --- a/apps/desktop/src/locales/el/messages.json +++ b/apps/desktop/src/locales/el/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Αποφυγή αμφιλεγόμενων χαρακτήρων" }, + "generatorPolicyInEffect": { + "message": "Οι απαιτήσεις της εταιρικής πολιτικής έχουν εφαρμοστεί στις επιλογές γεννήτριάς σας.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Αναζήτηση στη συλλογή" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Να επιτρέπεται η ενσωμάτωση περιηγητή" }, - "enableBrowserIntegrationDesc": { - "message": "Χρησιμοποιείται για βιομετρικά στοιχεία στον περιηγητή." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Επίτρεψε ενσωμάτωση περιηγητή DuckDuckGo" diff --git a/apps/desktop/src/locales/en/messages.json b/apps/desktop/src/locales/en/messages.json index 7f8ddb3aad3..9504ecb1fa3 100644 --- a/apps/desktop/src/locales/en/messages.json +++ b/apps/desktop/src/locales/en/messages.json @@ -1775,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Allow browser integration" }, - "enableBrowserIntegrationDesc": { - "message": "Used for biometrics in browser." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Allow DuckDuckGo browser integration" diff --git a/apps/desktop/src/locales/en_GB/messages.json b/apps/desktop/src/locales/en_GB/messages.json index 5718f6a4d6f..0df77c9607b 100644 --- a/apps/desktop/src/locales/en_GB/messages.json +++ b/apps/desktop/src/locales/en_GB/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Avoid ambiguous characters" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Search collection" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Allow browser integration" }, - "enableBrowserIntegrationDesc": { - "message": "Used for biometrics in browser." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Allow DuckDuckGo browser integration" diff --git a/apps/desktop/src/locales/en_IN/messages.json b/apps/desktop/src/locales/en_IN/messages.json index cefbda1c65c..34a47f47f5d 100644 --- a/apps/desktop/src/locales/en_IN/messages.json +++ b/apps/desktop/src/locales/en_IN/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Avoid ambiguous characters" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Search collection" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Enable browser integration" }, - "enableBrowserIntegrationDesc": { - "message": "Browser integration is used for biometrics in browser." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Allow DuckDuckGo browser integration" diff --git a/apps/desktop/src/locales/eo/messages.json b/apps/desktop/src/locales/eo/messages.json index 4d7fdbefa1e..3ccaeca20e6 100644 --- a/apps/desktop/src/locales/eo/messages.json +++ b/apps/desktop/src/locales/eo/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Avoid ambiguous characters" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Search collection" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Allow browser integration" }, - "enableBrowserIntegrationDesc": { - "message": "Used for biometrics in browser." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Allow DuckDuckGo browser integration" diff --git a/apps/desktop/src/locales/es/messages.json b/apps/desktop/src/locales/es/messages.json index 937c60ba0c8..e2c0f2e629f 100644 --- a/apps/desktop/src/locales/es/messages.json +++ b/apps/desktop/src/locales/es/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Evitar caracteres ambiguos" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Buscar en colección" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Habilitar integración con el navegador" }, - "enableBrowserIntegrationDesc": { - "message": "La integración del navegador se usa para la biometría en el mismo." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Permitir integración con el navegador DuckDuckGo" diff --git a/apps/desktop/src/locales/et/messages.json b/apps/desktop/src/locales/et/messages.json index 51790cd9a08..3d9ad0d68bd 100644 --- a/apps/desktop/src/locales/et/messages.json +++ b/apps/desktop/src/locales/et/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Väldi ebamääraseid kirjamärke" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Otsi kogumikku" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Lülita sisse brauseri integratsioon" }, - "enableBrowserIntegrationDesc": { - "message": "Brauseri integratsioon on vajalik biomeetria kasutamiseks brauseris." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Lubage DuckDuckGo brauseri integreerimine" diff --git a/apps/desktop/src/locales/eu/messages.json b/apps/desktop/src/locales/eu/messages.json index b3b09045df0..07928116d55 100644 --- a/apps/desktop/src/locales/eu/messages.json +++ b/apps/desktop/src/locales/eu/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Saihestu karaktere anbiguoak" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Bilatu bilduma" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Baimendu nabigatzailearekin integratzea" }, - "enableBrowserIntegrationDesc": { - "message": "Nabigatzailean biometria erabiltzen da." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Baimendu DuckDuckGo nabigatzailearekin integratzea" diff --git a/apps/desktop/src/locales/fa/messages.json b/apps/desktop/src/locales/fa/messages.json index def7de712cd..b2fdf4cae24 100644 --- a/apps/desktop/src/locales/fa/messages.json +++ b/apps/desktop/src/locales/fa/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "از کاراکترهای مبهم اجتناب کن" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "جستجوی مجموعه" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "فعال کردن ادغام مرورگر" }, - "enableBrowserIntegrationDesc": { - "message": "یکپارچه سازی مرورگر برای بیومتریک در مرورگر استفاده می‌شود." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "اجازه ادغام مرورگر DuckDuckGo را بدهید" diff --git a/apps/desktop/src/locales/fi/messages.json b/apps/desktop/src/locales/fi/messages.json index 76941909112..4e7791f78d1 100644 --- a/apps/desktop/src/locales/fi/messages.json +++ b/apps/desktop/src/locales/fi/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Vältä epäselviä merkkejä" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Etsi kokoelmasta" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Salli selainintegraatio" }, - "enableBrowserIntegrationDesc": { - "message": "Käytetään verkkoselainten biometriatukeen." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Salli integraatio DuckDuckGo-selaimeen" diff --git a/apps/desktop/src/locales/fil/messages.json b/apps/desktop/src/locales/fil/messages.json index 9ffce18230c..19241a24d3f 100644 --- a/apps/desktop/src/locales/fil/messages.json +++ b/apps/desktop/src/locales/fil/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Iwasan ang mga hindi malinaw na character" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Maghanap ng koleksyon" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Payagan ang pagsasama ng browser" }, - "enableBrowserIntegrationDesc": { - "message": "Ginagamit para sa biometrics sa browser." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Payagan ang pagsasama ng browser ng DuckDuckGo" diff --git a/apps/desktop/src/locales/fr/messages.json b/apps/desktop/src/locales/fr/messages.json index 7913b80723a..a28e877fd9c 100644 --- a/apps/desktop/src/locales/fr/messages.json +++ b/apps/desktop/src/locales/fr/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Éviter les caractères ambigus" }, + "generatorPolicyInEffect": { + "message": "Les exigences de la politique d'entreprise ont été appliquées à vos options de générateur.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Rechercher dans la collection" }, @@ -1196,7 +1200,7 @@ "message": "Vous pouvez acheter une adhésion Premium sur le coffre web de bitwarden.com. Voulez-vous visiter le site web maintenant ?" }, "premiumPurchaseAlertV2": { - "message": "You can purchase Premium from your account settings on the Bitwarden web app." + "message": "Vous pouvez faire des achats Prenium à partir des paramètres de votre compte sur l'application web Bitwarden." }, "premiumCurrentMember": { "message": "Vous êtes un membre Premium !" @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Activer l'intégration avec le navigateur" }, - "enableBrowserIntegrationDesc": { - "message": "L'intégration avec le navigateur est utilisée pour le déverrouillage biométrique dans le navigateur." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Autoriser l'intégration DuckDuckGo au navigateur" diff --git a/apps/desktop/src/locales/gl/messages.json b/apps/desktop/src/locales/gl/messages.json index 46c89b933c5..9504ecb1fa3 100644 --- a/apps/desktop/src/locales/gl/messages.json +++ b/apps/desktop/src/locales/gl/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Avoid ambiguous characters" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Search collection" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Allow browser integration" }, - "enableBrowserIntegrationDesc": { - "message": "Used for biometrics in browser." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Allow DuckDuckGo browser integration" diff --git a/apps/desktop/src/locales/he/messages.json b/apps/desktop/src/locales/he/messages.json index 77c0e2390f3..dd3e3f52304 100644 --- a/apps/desktop/src/locales/he/messages.json +++ b/apps/desktop/src/locales/he/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "המנע מאותיות ותווים דומים" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "חפש אוסף" }, @@ -500,7 +504,7 @@ "message": "צור חשבון" }, "setAStrongPassword": { - "message": "Set a strong password" + "message": "הגדרת סיסמה חזקה" }, "finishCreatingYourAccountBySettingAPassword": { "message": "Finish creating your account by setting a password" @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "אפשר אינטגרציה עם הדפדפן" }, - "enableBrowserIntegrationDesc": { - "message": "אינטגרצייה עם הדפדפן מאפשרת שימוש באמצעיים ביומטריים בדפדפן." + "enableBrowserIntegrationDesc1": { + "message": "משמש כדי לאפשר שחרור עם אמצעים ביומטריים בדפדפנים שאינם Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "אפשר שילוב דפדפן DuckDuckGo" diff --git a/apps/desktop/src/locales/hi/messages.json b/apps/desktop/src/locales/hi/messages.json index 22d898222a0..eccd6911c33 100644 --- a/apps/desktop/src/locales/hi/messages.json +++ b/apps/desktop/src/locales/hi/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Avoid ambiguous characters" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Search collection" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Allow browser integration" }, - "enableBrowserIntegrationDesc": { - "message": "Used for biometrics in browser." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Allow DuckDuckGo browser integration" diff --git a/apps/desktop/src/locales/hr/messages.json b/apps/desktop/src/locales/hr/messages.json index f5bb74f14c6..19857e4f40a 100644 --- a/apps/desktop/src/locales/hr/messages.json +++ b/apps/desktop/src/locales/hr/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Izbjegavaj dvosmislene znakove" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Pretraživanje zbirke" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Uključi integraciju s web preglednikom" }, - "enableBrowserIntegrationDesc": { - "message": "Integracija s preglednikom koristi se za biometriju u pregledniku." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Dozvoli integraciju s DuckDuckGo preglednikom" diff --git a/apps/desktop/src/locales/hu/messages.json b/apps/desktop/src/locales/hu/messages.json index 9080c66232d..a01d448984f 100644 --- a/apps/desktop/src/locales/hu/messages.json +++ b/apps/desktop/src/locales/hu/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Félreérthető karakterek mellőzése" }, + "generatorPolicyInEffect": { + "message": "A vállalati házirend követelményei kerülnek alkalmazásra a generátor beállításaira.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Gyűjtemény keresése" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Böngésző integráció engedélyezése" }, - "enableBrowserIntegrationDesc": { - "message": "A böngésző integrációt a biometrikus adatokhoz használják a böngészőben." + "enableBrowserIntegrationDesc1": { + "message": "A biometrikus feloldás engedélyezésére szolgál olyan böngészőkben, amelyek nem Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "DuckDuckGo böngésző integráció engedélyezése" diff --git a/apps/desktop/src/locales/id/messages.json b/apps/desktop/src/locales/id/messages.json index 3013a4dc8da..2442ff680ee 100644 --- a/apps/desktop/src/locales/id/messages.json +++ b/apps/desktop/src/locales/id/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Hindari Karakter Ambigu" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Cari koleksi" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Aktifkan integrasi browser" }, - "enableBrowserIntegrationDesc": { - "message": "Integrasi browser digunakan untuk biometrik di browser." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Izinkan integrasi browser DuckDuckGo" diff --git a/apps/desktop/src/locales/it/messages.json b/apps/desktop/src/locales/it/messages.json index d701076da89..2d037c9e10c 100644 --- a/apps/desktop/src/locales/it/messages.json +++ b/apps/desktop/src/locales/it/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Evita caratteri ambigui" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Cerca nella raccolta" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Consenti l'integrazione del browser" }, - "enableBrowserIntegrationDesc": { - "message": "Usata per i dati biometrici nel browser." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Consenti l'integrazione del browser DuckDuckGo" diff --git a/apps/desktop/src/locales/ja/messages.json b/apps/desktop/src/locales/ja/messages.json index 694810550e3..7926b90702e 100644 --- a/apps/desktop/src/locales/ja/messages.json +++ b/apps/desktop/src/locales/ja/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "あいまいな文字を省く" }, + "generatorPolicyInEffect": { + "message": "生成オプションにエンタープライズポリシー要件を適用しました", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "コレクションの検索" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "ブラウザ統合を有効にする" }, - "enableBrowserIntegrationDesc": { - "message": "ブラウザでの生体認証のためにブラウザ統合を使用します。" + "enableBrowserIntegrationDesc1": { + "message": "Safari 以外のブラウザで生体認証によるロック解除を許可するために使用されます。" }, "enableDuckDuckGoBrowserIntegration": { "message": "DuckDuckGo ブラウザの統合を許可する" diff --git a/apps/desktop/src/locales/ka/messages.json b/apps/desktop/src/locales/ka/messages.json index 46c89b933c5..9504ecb1fa3 100644 --- a/apps/desktop/src/locales/ka/messages.json +++ b/apps/desktop/src/locales/ka/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Avoid ambiguous characters" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Search collection" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Allow browser integration" }, - "enableBrowserIntegrationDesc": { - "message": "Used for biometrics in browser." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Allow DuckDuckGo browser integration" diff --git a/apps/desktop/src/locales/km/messages.json b/apps/desktop/src/locales/km/messages.json index 46c89b933c5..9504ecb1fa3 100644 --- a/apps/desktop/src/locales/km/messages.json +++ b/apps/desktop/src/locales/km/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Avoid ambiguous characters" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Search collection" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Allow browser integration" }, - "enableBrowserIntegrationDesc": { - "message": "Used for biometrics in browser." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Allow DuckDuckGo browser integration" diff --git a/apps/desktop/src/locales/kn/messages.json b/apps/desktop/src/locales/kn/messages.json index eaac20a3edf..54a282fe1fe 100644 --- a/apps/desktop/src/locales/kn/messages.json +++ b/apps/desktop/src/locales/kn/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "ಅಸ್ಪಷ್ಟ ಅಕ್ಷರಗಳನ್ನು ತಪ್ಪಿಸಿ" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "ಸಂಗ್ರಹಣೆ ಹುಡುಕಿ" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "ಬ್ರೌಸರ್ ಏಕೀಕರಣವನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ" }, - "enableBrowserIntegrationDesc": { - "message": "ಬ್ರೌಸರ್ನಲ್ಲಿ ಬಯೋಮೆಟ್ರಿಕ್ಸ್ಗಾಗಿ ಬ್ರೌಸರ್ ಏಕೀಕರಣವನ್ನು ಬಳಸಲಾಗುತ್ತದೆ." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Allow DuckDuckGo browser integration" diff --git a/apps/desktop/src/locales/ko/messages.json b/apps/desktop/src/locales/ko/messages.json index 18b215447ba..7d570021579 100644 --- a/apps/desktop/src/locales/ko/messages.json +++ b/apps/desktop/src/locales/ko/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "모호한 문자 사용 안 함" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "컬렉션 검색" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "브라우저와 연결 활성화" }, - "enableBrowserIntegrationDesc": { - "message": "브라우저와 연결하면 브라우저에서 생체 인식을 사용할 수 있습니다." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "DuckDuckgo 브라우저와 연결 허용" diff --git a/apps/desktop/src/locales/lt/messages.json b/apps/desktop/src/locales/lt/messages.json index a52fa5de68f..9e24de4ecd9 100644 --- a/apps/desktop/src/locales/lt/messages.json +++ b/apps/desktop/src/locales/lt/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Vengti dviprasmiškų simbolių" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Ieškoti rinkinyje" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Leisti naršyklės integravimą" }, - "enableBrowserIntegrationDesc": { - "message": "Naudojama biometrikai naršyklėje." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Leisti DuckDuckGo naršyklės integravimą" diff --git a/apps/desktop/src/locales/lv/messages.json b/apps/desktop/src/locales/lv/messages.json index 19b07379e5c..75a12bdf729 100644 --- a/apps/desktop/src/locales/lv/messages.json +++ b/apps/desktop/src/locales/lv/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Izvairīties no viegli sajaucamām rakstzīmēm" }, + "generatorPolicyInEffect": { + "message": "Veidotāja iespējām tika piemērotas uzņēmējdarbības nosacījumu prasības.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Meklēt krājumā" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Iespējot sasaistīšanu ar pārlūku" }, - "enableBrowserIntegrationDesc": { - "message": "Tiek izmantota biometrijai pārlūkā." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Atļaut sasaistīšanu ar DuckDuckGo pārlūku" diff --git a/apps/desktop/src/locales/me/messages.json b/apps/desktop/src/locales/me/messages.json index 217876fe76d..090b9e1014b 100644 --- a/apps/desktop/src/locales/me/messages.json +++ b/apps/desktop/src/locales/me/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Izbjegni dvosmislene karaktere" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Pretraži kolekciju" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Allow browser integration" }, - "enableBrowserIntegrationDesc": { - "message": "Used for biometrics in browser." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Allow DuckDuckGo browser integration" diff --git a/apps/desktop/src/locales/ml/messages.json b/apps/desktop/src/locales/ml/messages.json index 317925f9ae1..0441f91a6b2 100644 --- a/apps/desktop/src/locales/ml/messages.json +++ b/apps/desktop/src/locales/ml/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "അവ്യക്തമായ പ്രതീകങ്ങൾ ഒഴിവാക്കുക" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "കളക്ഷൻസ് തിരയുക" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Allow browser integration" }, - "enableBrowserIntegrationDesc": { - "message": "Used for biometrics in browser." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Allow DuckDuckGo browser integration" diff --git a/apps/desktop/src/locales/mr/messages.json b/apps/desktop/src/locales/mr/messages.json index 46c89b933c5..9504ecb1fa3 100644 --- a/apps/desktop/src/locales/mr/messages.json +++ b/apps/desktop/src/locales/mr/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Avoid ambiguous characters" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Search collection" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Allow browser integration" }, - "enableBrowserIntegrationDesc": { - "message": "Used for biometrics in browser." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Allow DuckDuckGo browser integration" diff --git a/apps/desktop/src/locales/my/messages.json b/apps/desktop/src/locales/my/messages.json index 32e42abe616..068ee9533e4 100644 --- a/apps/desktop/src/locales/my/messages.json +++ b/apps/desktop/src/locales/my/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Avoid ambiguous characters" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Search collection" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Allow browser integration" }, - "enableBrowserIntegrationDesc": { - "message": "Used for biometrics in browser." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Allow DuckDuckGo browser integration" diff --git a/apps/desktop/src/locales/nb/messages.json b/apps/desktop/src/locales/nb/messages.json index 5faa9df24ca..68f2417285a 100644 --- a/apps/desktop/src/locales/nb/messages.json +++ b/apps/desktop/src/locales/nb/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Unngå tvetydige tegn" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Søk i samling" }, @@ -540,16 +544,16 @@ } }, "masterPassword": { - "message": "Master password" + "message": "Hovedpassord" }, "masterPassImportant": { "message": "Your master password cannot be recovered if you forget it!" }, "confirmMasterPassword": { - "message": "Confirm master password" + "message": "Bekreft hovedpassord" }, "masterPassHintLabel": { - "message": "Master password hint" + "message": "Hint til hovedpassord" }, "joinOrganization": { "message": "Bli med i organisasjon" @@ -564,7 +568,7 @@ "message": "Account email" }, "requestHint": { - "message": "Request hint" + "message": "Be om hint" }, "requestPasswordHint": { "message": "Request password hint" @@ -710,13 +714,13 @@ "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, "yubiKeyTitleV2": { - "message": "Yubico OTP security key" + "message": "YubiKey OTP-sikkerhetsnøkkel" }, "yubiKeyDesc": { "message": "Bruk en YubiKey for å få tilgang til kontoen din. Virker med enheter av typene YubiKey 4, 4 Nano, 4C, og NEO." }, "duoDescV2": { - "message": "Enter a code generated by Duo Security.", + "message": "Oppgi en kode generert av Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Aktiver nettleserintegrasjon" }, - "enableBrowserIntegrationDesc": { - "message": "Nettleserintegrasjon brukes til biometri i nettleseren." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Tillat integrering av DuckDuckGo" diff --git a/apps/desktop/src/locales/ne/messages.json b/apps/desktop/src/locales/ne/messages.json index 37befac5bf8..1a80b28a365 100644 --- a/apps/desktop/src/locales/ne/messages.json +++ b/apps/desktop/src/locales/ne/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "अस्पष्ट अक्षरहरूबाट बच्नुहोस्" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "सङ्ग्रह खोज्नुहोस्" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Allow browser integration" }, - "enableBrowserIntegrationDesc": { - "message": "Used for biometrics in browser." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Allow DuckDuckGo browser integration" diff --git a/apps/desktop/src/locales/nl/messages.json b/apps/desktop/src/locales/nl/messages.json index 276985ce3a8..c5a9a6419e5 100644 --- a/apps/desktop/src/locales/nl/messages.json +++ b/apps/desktop/src/locales/nl/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Vermijd dubbelzinnige tekens" }, + "generatorPolicyInEffect": { + "message": "Bedrijfsbeleidseisen zijn toegepast op je generator-instellingen.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Doorzoek collectie" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Browserintegratie inschakelen" }, - "enableBrowserIntegrationDesc": { - "message": "Browserintegratie wordt gebruikt voor biometrie in de browser." + "enableBrowserIntegrationDesc1": { + "message": "Wordt gebruikt voor het toestaan van biometrische ontgrendelen in andere browsers dan Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "DuckDuckGo browserintegratie toestaan" diff --git a/apps/desktop/src/locales/nn/messages.json b/apps/desktop/src/locales/nn/messages.json index 0f7340c8c15..30905c3775e 100644 --- a/apps/desktop/src/locales/nn/messages.json +++ b/apps/desktop/src/locales/nn/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Unngå forvekslingsbare tegn" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Søk i samling" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Allow browser integration" }, - "enableBrowserIntegrationDesc": { - "message": "Used for biometrics in browser." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Allow DuckDuckGo browser integration" diff --git a/apps/desktop/src/locales/or/messages.json b/apps/desktop/src/locales/or/messages.json index cd28e8ac91b..537faa307ac 100644 --- a/apps/desktop/src/locales/or/messages.json +++ b/apps/desktop/src/locales/or/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Avoid ambiguous characters" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Search collection" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Allow browser integration" }, - "enableBrowserIntegrationDesc": { - "message": "Used for biometrics in browser." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Allow DuckDuckGo browser integration" diff --git a/apps/desktop/src/locales/pl/messages.json b/apps/desktop/src/locales/pl/messages.json index 3e29f2e9107..7ec69ea1fd4 100644 --- a/apps/desktop/src/locales/pl/messages.json +++ b/apps/desktop/src/locales/pl/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Unikaj niejednoznacznych znaków" }, + "generatorPolicyInEffect": { + "message": "Wymagania polityki przedsiębiorstwa zostały użyte do ustawienia opcji generatora.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Szukaj w kolekcji" }, @@ -561,16 +565,16 @@ "message": "Ustawienia" }, "accountEmail": { - "message": "Account email" + "message": "Adres e-mail konta" }, "requestHint": { - "message": "Request hint" + "message": "Poproś o podpowiedź" }, "requestPasswordHint": { - "message": "Request password hint" + "message": "Poproś o podpowiedź do hasła" }, "enterYourAccountEmailAddressAndYourPasswordHintWillBeSentToYou": { - "message": "Enter your account email address and your password hint will be sent to you" + "message": "Wprowadź adres e-mail swojego konta, a podpowiedź hasła zostanie wysłana do Ciebie" }, "passwordHint": { "message": "Podpowiedź do hasła" @@ -616,10 +620,10 @@ "message": "Konto zostało utworzone! Teraz możesz się zalogować." }, "newAccountCreated2": { - "message": "Your new account has been created!" + "message": "Twoje nowe konto zostało utworzone!" }, "youHaveBeenLoggedIn": { - "message": "You have been logged in!" + "message": "Zalogowano Cię!" }, "masterPassSent": { "message": "Wysłaliśmy Tobie wiadomość e-mail z podpowiedzią do hasła głównego." @@ -943,7 +947,7 @@ "message": "Blokowanie sejfu" }, "vaultTimeout1": { - "message": "Timeout" + "message": "Limit czasu" }, "vaultTimeoutDesc": { "message": "Wybierz, kiedy sejf zostanie zablokowany i wykonaj następującą akcję." @@ -1196,7 +1200,7 @@ "message": "Konto Premium możesz zakupić na stronie sejfu bitwarden.com. Czy chcesz otworzyć tę stronę?" }, "premiumPurchaseAlertV2": { - "message": "You can purchase Premium from your account settings on the Bitwarden web app." + "message": "Możesz kupić Premium w ustawieniach konta w aplikacji internetowej Bitwarden." }, "premiumCurrentMember": { "message": "Posiadasz konto Premium!" @@ -1301,7 +1305,7 @@ } }, "copySuccessful": { - "message": "Copy Successful" + "message": "Kopiowanie zakończone sukcesem" }, "errorRefreshingAccessToken": { "message": "Błąd podczas odświeżania tokenu" @@ -1571,7 +1575,7 @@ "message": "Zalecane dla bezpieczeństwa." }, "lockWithMasterPassOnRestart1": { - "message": "Lock with master password on restart" + "message": "Zablokuj hasłem głównym po uruchomieniu ponownym" }, "deleteAccount": { "message": "Usuń konto" @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Włącz połączenie z przeglądarką" }, - "enableBrowserIntegrationDesc": { - "message": "Używane do odblokowania danymi biometrycznymi." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Włącz połączenie z przeglądarką DuckDuckGo" @@ -2058,7 +2062,7 @@ "message": "Twoje hasło główne nie spełnia jednej lub kilku zasad organizacji. Aby uzyskać dostęp do sejfu, musisz teraz zaktualizować swoje hasło główne. Kontynuacja wyloguje Cię z bieżącej sesji, wymagając zalogowania się ponownie. Aktywne sesje na innych urządzeniach mogą pozostać aktywne przez maksymalnie jedną godzinę." }, "tdeDisabledMasterPasswordRequired": { - "message": "Your organization has disabled trusted device encryption. Please set a master password to access your vault." + "message": "Twoja organizacja wyłączyła szyfrowanie zaufanego urządzenia. Ustaw hasło główne, aby uzyskać dostęp do sejfu." }, "tryAgain": { "message": "Spróbuj ponownie" @@ -2103,7 +2107,7 @@ "message": "Minuty" }, "vaultTimeoutPolicyInEffect1": { - "message": "$HOURS$ hour(s) and $MINUTES$ minute(s) maximum.", + "message": "$HOURS$ godzin(y) i $MINUTES$ minut(y) maksymalnie.", "placeholders": { "hours": { "content": "$1", @@ -3078,15 +3082,15 @@ "message": "Text Sends" }, "allowScreenshots": { - "message": "Allow screen capture" + "message": "Pozwól na robienie zrzutów ekranu" }, "allowScreenshotsDesc": { - "message": "Allow screen capture of the Bitwarden desktop application." + "message": "Zezwalaj na przechwytywanie ekranu aplikacji desktopowej Bitwarden." }, "ssoError": { - "message": "No free ports could be found for the sso login." + "message": "Nie znaleziono wolnych portów dla logowania SSO." }, "fileSavedToDevice": { - "message": "File saved to device. Manage from your device downloads." + "message": "Plik zapisany na urządzeniu. Zarządzaj plikiem na swoim urządzeniu." } } diff --git a/apps/desktop/src/locales/pt_BR/messages.json b/apps/desktop/src/locales/pt_BR/messages.json index 7282812682f..078744ac802 100644 --- a/apps/desktop/src/locales/pt_BR/messages.json +++ b/apps/desktop/src/locales/pt_BR/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Evitar Caracteres Ambíguos" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Pesquisar coleção" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Ativar integração com o navegador" }, - "enableBrowserIntegrationDesc": { - "message": "A integração do navegador é usada para biometria no navegador." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Permitir integração ao navegador DuckDuckGo" diff --git a/apps/desktop/src/locales/pt_PT/messages.json b/apps/desktop/src/locales/pt_PT/messages.json index 69babd217c5..e11deea02a0 100644 --- a/apps/desktop/src/locales/pt_PT/messages.json +++ b/apps/desktop/src/locales/pt_PT/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Evitar caracteres ambíguos" }, + "generatorPolicyInEffect": { + "message": "Os requisitos da política empresarial foram aplicados às suas opções de gerador.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Procurar na coleção" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Permitir a integração do navegador" }, - "enableBrowserIntegrationDesc": { - "message": "Utilizado para a biometria no navegador." + "enableBrowserIntegrationDesc1": { + "message": "Utilizado para permitir o desbloqueio biométrico em navegadores que não sejam o Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Permitir a integração do navegador DuckDuckGo" diff --git a/apps/desktop/src/locales/ro/messages.json b/apps/desktop/src/locales/ro/messages.json index 42cc3839f93..25aa35d7e08 100644 --- a/apps/desktop/src/locales/ro/messages.json +++ b/apps/desktop/src/locales/ro/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Evitare de caractere ambigue" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Căutare în colecție" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Permiteți integrarea în browser" }, - "enableBrowserIntegrationDesc": { - "message": "Folosit pentru biometrie în browser." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Permiteți integrarea de browser DuckDuckGo" diff --git a/apps/desktop/src/locales/ru/messages.json b/apps/desktop/src/locales/ru/messages.json index 47516c9c5a8..3db5e022a45 100644 --- a/apps/desktop/src/locales/ru/messages.json +++ b/apps/desktop/src/locales/ru/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Избегать неоднозначных символов" }, + "generatorPolicyInEffect": { + "message": "К настройкам генератора были применены требования корпоративной политики.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Поиск в коллекции" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Разрешить интеграцию с браузером" }, - "enableBrowserIntegrationDesc": { - "message": "Используется для биометрии в браузере." + "enableBrowserIntegrationDesc1": { + "message": "Используется для разрешения биометрической разблокировки в браузерах, отличных от Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Разрешить интеграцию в браузер DuckDuckGo" diff --git a/apps/desktop/src/locales/si/messages.json b/apps/desktop/src/locales/si/messages.json index 8788d231165..497ae47b006 100644 --- a/apps/desktop/src/locales/si/messages.json +++ b/apps/desktop/src/locales/si/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Avoid ambiguous characters" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Search collection" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Allow browser integration" }, - "enableBrowserIntegrationDesc": { - "message": "Used for biometrics in browser." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Allow DuckDuckGo browser integration" diff --git a/apps/desktop/src/locales/sk/messages.json b/apps/desktop/src/locales/sk/messages.json index 749c26dd169..a90144e5b8c 100644 --- a/apps/desktop/src/locales/sk/messages.json +++ b/apps/desktop/src/locales/sk/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Vyhnúť sa zameniteľným znakom" }, + "generatorPolicyInEffect": { + "message": "Na nastavenie generátora boli uplatnené požiadavky pravidiel spoločnosti.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Hľadať v zbierke" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Povoliť integráciu v prehliadiači" }, - "enableBrowserIntegrationDesc": { - "message": "Integrácia v prehliadači sa používa na biometriu v prehliadači." + "enableBrowserIntegrationDesc1": { + "message": "Slúži na povolenie biometrického odomykania v prehliadačoch iných ako Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Povoliť integráciu prehliadača DuckDuckGo" diff --git a/apps/desktop/src/locales/sl/messages.json b/apps/desktop/src/locales/sl/messages.json index 46a8c103200..a75a6ce1f3e 100644 --- a/apps/desktop/src/locales/sl/messages.json +++ b/apps/desktop/src/locales/sl/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Izogibaj se dvoumnim znakom" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Preišči zbirko" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Dovoli integracijo z brskalnikom" }, - "enableBrowserIntegrationDesc": { - "message": "Used for biometrics in browser." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Allow DuckDuckGo browser integration" diff --git a/apps/desktop/src/locales/sr/messages.json b/apps/desktop/src/locales/sr/messages.json index 85649f0cafc..d74fb2c4675 100644 --- a/apps/desktop/src/locales/sr/messages.json +++ b/apps/desktop/src/locales/sr/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Избегавај двосмислене карактере" }, + "generatorPolicyInEffect": { + "message": "Захтеви политике предузећа су примењени на опције гнератора.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Претражи колекцију" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Укључи интеграцију са претраживачем" }, - "enableBrowserIntegrationDesc": { - "message": "Интеграција прегледача се користи за биометрију у прегледачу." + "enableBrowserIntegrationDesc1": { + "message": "Користи се за омогућавање биометријског откључавања у прегледачима који то нису Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Дозволи DuckDuckGo интерграцију претраживача" diff --git a/apps/desktop/src/locales/sv/messages.json b/apps/desktop/src/locales/sv/messages.json index a31f1f3310b..60311d61450 100644 --- a/apps/desktop/src/locales/sv/messages.json +++ b/apps/desktop/src/locales/sv/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Undvik tvetydiga tecken" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Sök i samling" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Tillåt webbläsarintegration" }, - "enableBrowserIntegrationDesc": { - "message": "Webbläsarintegration används för biometri i webbläsaren." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Tillåt integration av webbläsaren DuckDuckGo" diff --git a/apps/desktop/src/locales/te/messages.json b/apps/desktop/src/locales/te/messages.json index 46c89b933c5..9504ecb1fa3 100644 --- a/apps/desktop/src/locales/te/messages.json +++ b/apps/desktop/src/locales/te/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Avoid ambiguous characters" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Search collection" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Allow browser integration" }, - "enableBrowserIntegrationDesc": { - "message": "Used for biometrics in browser." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Allow DuckDuckGo browser integration" diff --git a/apps/desktop/src/locales/th/messages.json b/apps/desktop/src/locales/th/messages.json index 30da79efc8e..8d9243c8ddc 100644 --- a/apps/desktop/src/locales/th/messages.json +++ b/apps/desktop/src/locales/th/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "หลีกเลี่ยงอักขระที่ไม่ชัดเจน" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Search collection" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Allow browser integration" }, - "enableBrowserIntegrationDesc": { - "message": "Used for biometrics in browser." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Allow DuckDuckGo browser integration" diff --git a/apps/desktop/src/locales/tr/messages.json b/apps/desktop/src/locales/tr/messages.json index af22a36b2af..042247d9c4b 100644 --- a/apps/desktop/src/locales/tr/messages.json +++ b/apps/desktop/src/locales/tr/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Okurken karışabilecek karakterleri kullanma" }, + "generatorPolicyInEffect": { + "message": "Üreteç seçeneklerinize kurumsal ilke gereksinimleri uygulandı.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Koleksiyonda ara" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Tarayıcı entegrasyonuna izin ver" }, - "enableBrowserIntegrationDesc": { - "message": "Tarayıcıda biyometrik doğrulama için kullanılır." + "enableBrowserIntegrationDesc1": { + "message": "Safari dışındaki tarayıcılarda biyometrik kilit açmaya izin vermek için kullanılır." }, "enableDuckDuckGoBrowserIntegration": { "message": "DuckDuckGo tarayıcı entegrasyonuna izin ver" diff --git a/apps/desktop/src/locales/uk/messages.json b/apps/desktop/src/locales/uk/messages.json index 3a218e47dea..49df2e97e18 100644 --- a/apps/desktop/src/locales/uk/messages.json +++ b/apps/desktop/src/locales/uk/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Уникати неоднозначних символів" }, + "generatorPolicyInEffect": { + "message": "До налаштувань генератора застосовано вимоги політики компанії.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Шукати в збірці" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Дозволити інтеграцію з браузером" }, - "enableBrowserIntegrationDesc": { - "message": "Використовується для біометрії в браузері." + "enableBrowserIntegrationDesc1": { + "message": "Використовується для біометричного розблокування у браузерах, крім Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Дозволити інтеграцію з браузером DuckDuckGo" diff --git a/apps/desktop/src/locales/vi/messages.json b/apps/desktop/src/locales/vi/messages.json index 854cb697fa2..8a05619556d 100644 --- a/apps/desktop/src/locales/vi/messages.json +++ b/apps/desktop/src/locales/vi/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "Tránh các ký tự dễ gây nhầm lẫn" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "Tìm kiếm bộ sưu tập" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "Cho phép tích hợp với trình duyệt" }, - "enableBrowserIntegrationDesc": { - "message": "Sử dụng để xác thực sinh trắc học trên trình duyệt." + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "Cho phép tích hợp trình duyệt DuckDuckGo" diff --git a/apps/desktop/src/locales/zh_CN/messages.json b/apps/desktop/src/locales/zh_CN/messages.json index a2a650dbc9e..43c17f199e4 100644 --- a/apps/desktop/src/locales/zh_CN/messages.json +++ b/apps/desktop/src/locales/zh_CN/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "避免易混淆的字符" }, + "generatorPolicyInEffect": { + "message": "企业策略要求应用到您的生成器选项中。", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "搜索集合" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "允许浏览器集成" }, - "enableBrowserIntegrationDesc": { - "message": "用于在浏览器中提供生物识别。" + "enableBrowserIntegrationDesc1": { + "message": "用于在非 Safari 浏览器中允许生物识别解锁。" }, "enableDuckDuckGoBrowserIntegration": { "message": "允许 DuckDuckGo 浏览器集成" diff --git a/apps/desktop/src/locales/zh_TW/messages.json b/apps/desktop/src/locales/zh_TW/messages.json index 954af24c45f..e08615f783d 100644 --- a/apps/desktop/src/locales/zh_TW/messages.json +++ b/apps/desktop/src/locales/zh_TW/messages.json @@ -444,6 +444,10 @@ "ambiguous": { "message": "避免易混淆的字元" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "searchCollection": { "message": "搜尋集合" }, @@ -1771,8 +1775,8 @@ "enableBrowserIntegration": { "message": "允許瀏覽器整合" }, - "enableBrowserIntegrationDesc": { - "message": "用於在瀏覽器中提供生物特徵辨識。" + "enableBrowserIntegrationDesc1": { + "message": "Used to allow biometric unlock in browsers that are not Safari." }, "enableDuckDuckGoBrowserIntegration": { "message": "允許 DuckDuckGo 瀏覽器整合" diff --git a/apps/desktop/src/main/window.main.ts b/apps/desktop/src/main/window.main.ts index 8f7ea4fd1ed..8c78f531d73 100644 --- a/apps/desktop/src/main/window.main.ts +++ b/apps/desktop/src/main/window.main.ts @@ -323,7 +323,7 @@ export class WindowMain { } private async updateWindowState(configKey: string, win: BrowserWindow) { - if (win == null) { + if (win == null || win.isDestroyed()) { return; } diff --git a/apps/web/src/app/billing/individual/premium/premium-v2.component.html b/apps/web/src/app/billing/individual/premium/premium-v2.component.html index bdf6ff87d19..eb93d8ef6a3 100644 --- a/apps/web/src/app/billing/individual/premium/premium-v2.component.html +++ b/apps/web/src/app/billing/individual/premium/premium-v2.component.html @@ -66,33 +66,39 @@ -

{{ "uploadLicenseFilePremium" | i18n }}

-
- - {{ "licenseFile" | i18n }} -
- - {{ - licenseFormGroup.value.file ? licenseFormGroup.value.file.name : ("noFileChosen" | i18n) - }} -
- - {{ "licenseFileDesc" | i18n: "bitwarden_premium_license.json" }} -
- -
+ +

{{ "uploadLicenseFilePremium" | i18n }}

+
+ + {{ "licenseFile" | i18n }} +
+ + {{ + licenseFormGroup.value.file ? licenseFormGroup.value.file.name : ("noFileChosen" | i18n) + }} +
+ + {{ "licenseFileDesc" | i18n: "bitwarden_premium_license.json" }} +
+ +
+
+
diff --git a/apps/web/src/app/billing/individual/premium/premium-v2.component.ts b/apps/web/src/app/billing/individual/premium/premium-v2.component.ts index cf66dac2f76..4f6d30530c2 100644 --- a/apps/web/src/app/billing/individual/premium/premium-v2.component.ts +++ b/apps/web/src/app/billing/individual/premium/premium-v2.component.ts @@ -7,6 +7,8 @@ import { combineLatest, concatMap, from, Observable, of } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions"; +import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; @@ -36,6 +38,10 @@ export class PremiumV2Component { protected cloudWebVaultURL: string; protected isSelfHost = false; + protected useLicenseUploaderComponent$ = this.configService.getFeatureFlag$( + FeatureFlag.PM11901_RefactorSelfHostingLicenseUploader, + ); + protected readonly familyPlanMaxUserCount = 6; protected readonly premiumPrice = 10; protected readonly storageGBPrice = 4; @@ -44,6 +50,7 @@ export class PremiumV2Component { private activatedRoute: ActivatedRoute, private apiService: ApiService, private billingAccountProfileStateService: BillingAccountProfileStateService, + private configService: ConfigService, private environmentService: EnvironmentService, private i18nService: I18nService, private platformUtilsService: PlatformUtilsService, @@ -78,6 +85,9 @@ export class PremiumV2Component { finalizeUpgrade = async () => { await this.apiService.refreshIdentityToken(); await this.syncService.fullSync(true); + }; + + postFinalizeUpgrade = async () => { this.toastService.showToast({ variant: "success", title: null, @@ -119,6 +129,7 @@ export class PremiumV2Component { await this.apiService.postAccountLicense(formData); await this.finalizeUpgrade(); + await this.postFinalizeUpgrade(); }; submitPayment = async (): Promise => { @@ -138,6 +149,7 @@ export class PremiumV2Component { await this.apiService.postPremium(formData); await this.finalizeUpgrade(); + await this.postFinalizeUpgrade(); }; protected get additionalStorageCost(): number { @@ -161,4 +173,8 @@ export class PremiumV2Component { protected get total(): number { return this.subtotal + this.estimatedTax; } + + protected async onLicenseFileSelectedChanged(): Promise { + await this.postFinalizeUpgrade(); + } } diff --git a/apps/web/src/app/billing/organizations/change-plan-dialog.component.html b/apps/web/src/app/billing/organizations/change-plan-dialog.component.html index 27d51af92b3..e6ed6475c4a 100644 --- a/apps/web/src/app/billing/organizations/change-plan-dialog.component.html +++ b/apps/web/src/app/billing/organizations/change-plan-dialog.component.html @@ -757,7 +757,7 @@ {{ "serviceAccounts" | i18n }} × {{ selectedPlan.SecretsManager.additionalPricePerServiceAccount | currency: "$" }} - /{{ "month" | i18n }} + /{{ "year" | i18n }} {{ additionalServiceAccountTotal(selectedPlan) | currency: "$" }}

diff --git a/apps/web/src/app/billing/organizations/change-plan-dialog.component.ts b/apps/web/src/app/billing/organizations/change-plan-dialog.component.ts index 42a987664f0..c7cd7e45a9e 100644 --- a/apps/web/src/app/billing/organizations/change-plan-dialog.component.ts +++ b/apps/web/src/app/billing/organizations/change-plan-dialog.component.ts @@ -497,7 +497,7 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy { return 0; } - const result = plan.PasswordManager.seatPrice * Math.abs(this.organization.seats || 0); + const result = plan.PasswordManager.seatPrice * Math.abs(this.sub?.seats || 0); return result; } diff --git a/apps/web/src/app/billing/organizations/organization-plans.component.html b/apps/web/src/app/billing/organizations/organization-plans.component.html index 5992af5f544..e6e2610d67c 100644 --- a/apps/web/src/app/billing/organizations/organization-plans.component.html +++ b/apps/web/src/app/billing/organizations/organization-plans.component.html @@ -7,32 +7,38 @@ {{ "loading" | i18n }} -

{{ "uploadLicenseFileOrg" | i18n }}

- - - {{ "licenseFile" | i18n }} -
- - {{ selectedFile?.name ?? ("noFileChosen" | i18n) }} -
- - {{ "licenseFileDesc" | i18n: "bitwarden_organization_license.json" }} -
- - + +

{{ "uploadLicenseFileOrg" | i18n }}

+
+ + {{ "licenseFile" | i18n }} +
+ + {{ selectedFile?.name ?? ("noFileChosen" | i18n) }} +
+ + {{ "licenseFileDesc" | i18n: "bitwarden_organization_license.json" }} +
+ +
+
+
{ + this.toastService.showToast({ + variant: "success", + title: this.i18nService.t("organizationCreated"), + message: this.i18nService.t("organizationReadyToGo"), + }); + + if (!this.acceptingSponsorship && !this.isInTrialFlow) { + // 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/" + organizationId]); + } + + if (this.isInTrialFlow) { + this.onTrialBillingSuccess.emit({ + orgId: organizationId, + subLabelText: this.billingSubLabelText(), + }); + } + + this.onSuccess.emit({ organizationId: organizationId }); + + // TODO: No one actually listening to this message? + this.messagingService.send("organizationCreated", { organizationId: organizationId }); + } } diff --git a/apps/web/src/app/billing/shared/billing-shared.module.ts b/apps/web/src/app/billing/shared/billing-shared.module.ts index b966729c1df..57491a73e6d 100644 --- a/apps/web/src/app/billing/shared/billing-shared.module.ts +++ b/apps/web/src/app/billing/shared/billing-shared.module.ts @@ -13,6 +13,8 @@ import { OffboardingSurveyComponent } from "./offboarding-survey.component"; import { PaymentV2Component } from "./payment/payment-v2.component"; import { PaymentComponent } from "./payment/payment.component"; import { PaymentMethodComponent } from "./payment-method.component"; +import { IndividualSelfHostingLicenseUploaderComponent } from "./self-hosting-license-uploader/individual-self-hosting-license-uploader.component"; +import { OrganizationSelfHostingLicenseUploaderComponent } from "./self-hosting-license-uploader/organization-self-hosting-license-uploader.component"; import { SecretsManagerSubscribeComponent } from "./sm-subscribe.component"; import { TaxInfoComponent } from "./tax-info.component"; import { UpdateLicenseDialogComponent } from "./update-license-dialog.component"; @@ -40,6 +42,8 @@ import { VerifyBankAccountComponent } from "./verify-bank-account/verify-bank-ac OffboardingSurveyComponent, AdjustPaymentDialogV2Component, AdjustStorageDialogV2Component, + IndividualSelfHostingLicenseUploaderComponent, + OrganizationSelfHostingLicenseUploaderComponent, ], exports: [ SharedModule, @@ -53,6 +57,8 @@ import { VerifyBankAccountComponent } from "./verify-bank-account/verify-bank-ac OffboardingSurveyComponent, VerifyBankAccountComponent, PaymentV2Component, + IndividualSelfHostingLicenseUploaderComponent, + OrganizationSelfHostingLicenseUploaderComponent, ], }) export class BillingSharedModule {} diff --git a/apps/web/src/app/billing/shared/self-hosting-license-uploader/abstract-self-hosting-license-uploader.component.ts b/apps/web/src/app/billing/shared/self-hosting-license-uploader/abstract-self-hosting-license-uploader.component.ts new file mode 100644 index 00000000000..01605eae7dc --- /dev/null +++ b/apps/web/src/app/billing/shared/self-hosting-license-uploader/abstract-self-hosting-license-uploader.component.ts @@ -0,0 +1,81 @@ +import { FormBuilder, FormGroup, Validators } from "@angular/forms"; + +import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; +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 { LicenseUploaderFormModel } from "./license-uploader-form-model"; + +/** + * Shared implementation for processing license file uploads. + * @remarks Requires self-hosting. + */ +export abstract class AbstractSelfHostingLicenseUploaderComponent { + protected form: FormGroup; + + protected constructor( + protected readonly formBuilder: FormBuilder, + protected readonly i18nService: I18nService, + protected readonly platformUtilsService: PlatformUtilsService, + protected readonly toastService: ToastService, + protected readonly tokenService: TokenService, + ) { + const isSelfHosted = this.platformUtilsService.isSelfHost(); + + if (!isSelfHosted) { + throw new Error("This component should only be used in self-hosted environments"); + } + + this.form = this.formBuilder.group({ + file: [null, [Validators.required]], + }); + this.submit = this.submit.bind(this); + } + + /** + * Gets the submitted license upload form model. + * @protected + */ + protected get formValue(): LicenseUploaderFormModel { + return this.form.value as LicenseUploaderFormModel; + } + + /** + * Triggered when a different license file is selected. + * @param event + */ + onLicenseFileSelectedChanged(event: Event): void { + const element = event.target as HTMLInputElement; + this.form.value.file = element.files.length > 0 ? element.files[0] : null; + } + + /** + * Submits the license upload form. + * @protected + */ + protected async submit(): Promise { + this.form.markAllAsTouched(); + + if (this.form.invalid) { + return this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: this.i18nService.t("selectFile"), + }); + } + + const emailVerified = await this.tokenService.getEmailVerified(); + if (!emailVerified) { + return this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: this.i18nService.t("verifyEmailFirst"), + }); + } + } + + abstract get description(): string; + + abstract get hintFileName(): string; +} diff --git a/apps/web/src/app/billing/shared/self-hosting-license-uploader/individual-self-hosting-license-uploader.component.ts b/apps/web/src/app/billing/shared/self-hosting-license-uploader/individual-self-hosting-license-uploader.component.ts new file mode 100644 index 00000000000..0d7698e00fd --- /dev/null +++ b/apps/web/src/app/billing/shared/self-hosting-license-uploader/individual-self-hosting-license-uploader.component.ts @@ -0,0 +1,60 @@ +import { Component, EventEmitter, Output } from "@angular/core"; +import { FormBuilder } from "@angular/forms"; + +import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { TokenService } from "@bitwarden/common/auth/abstractions/token.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 { ToastService } from "@bitwarden/components"; + +import { AbstractSelfHostingLicenseUploaderComponent } from "../../shared/self-hosting-license-uploader/abstract-self-hosting-license-uploader.component"; + +/** + * Processes license file uploads for individual plans. + * @remarks Requires self-hosting. + */ +@Component({ + selector: "individual-self-hosting-license-uploader", + templateUrl: "./self-hosting-license-uploader.component.html", +}) +export class IndividualSelfHostingLicenseUploaderComponent extends AbstractSelfHostingLicenseUploaderComponent { + /** + * Emitted when a license file has been successfully uploaded & processed. + */ + @Output() onLicenseFileUploaded: EventEmitter = new EventEmitter(); + + constructor( + protected readonly apiService: ApiService, + protected readonly formBuilder: FormBuilder, + protected readonly i18nService: I18nService, + protected readonly platformUtilsService: PlatformUtilsService, + protected readonly syncService: SyncService, + protected readonly toastService: ToastService, + protected readonly tokenService: TokenService, + ) { + super(formBuilder, i18nService, platformUtilsService, toastService, tokenService); + } + + protected async submit(): Promise { + await super.submit(); + + const formData = new FormData(); + formData.append("license", this.formValue.file); + + await this.apiService.postAccountLicense(formData); + + await this.apiService.refreshIdentityToken(); + await this.syncService.fullSync(true); + + this.onLicenseFileUploaded.emit(); + } + + get description(): string { + return "uploadLicenseFilePremium"; + } + + get hintFileName(): string { + return "bitwarden_premium_license.json"; + } +} diff --git a/apps/web/src/app/billing/shared/self-hosting-license-uploader/license-uploader-form-model.ts b/apps/web/src/app/billing/shared/self-hosting-license-uploader/license-uploader-form-model.ts new file mode 100644 index 00000000000..42ce1be2ea4 --- /dev/null +++ b/apps/web/src/app/billing/shared/self-hosting-license-uploader/license-uploader-form-model.ts @@ -0,0 +1,3 @@ +export interface LicenseUploaderFormModel { + file: File; +} diff --git a/apps/web/src/app/billing/shared/self-hosting-license-uploader/organization-self-hosting-license-uploader.component.ts b/apps/web/src/app/billing/shared/self-hosting-license-uploader/organization-self-hosting-license-uploader.component.ts new file mode 100644 index 00000000000..79c3cb83a43 --- /dev/null +++ b/apps/web/src/app/billing/shared/self-hosting-license-uploader/organization-self-hosting-license-uploader.component.ts @@ -0,0 +1,85 @@ +import { Component, EventEmitter, Output } from "@angular/core"; +import { FormBuilder } from "@angular/forms"; + +import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction"; +import { OrganizationKeysRequest } from "@bitwarden/common/admin-console/models/request/organization-keys.request"; +import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; +import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; +import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { SyncService } from "@bitwarden/common/platform/sync"; +import { OrgKey } from "@bitwarden/common/types/key"; +import { ToastService } from "@bitwarden/components"; + +import { AbstractSelfHostingLicenseUploaderComponent } from "../../shared/self-hosting-license-uploader/abstract-self-hosting-license-uploader.component"; + +/** + * Processes license file uploads for organizations. + * @remarks Requires self-hosting. + */ +@Component({ + selector: "organization-self-hosting-license-uploader", + templateUrl: "./self-hosting-license-uploader.component.html", +}) +export class OrganizationSelfHostingLicenseUploaderComponent extends AbstractSelfHostingLicenseUploaderComponent { + /** + * Notifies the parent component of the `organizationId` the license was created for. + */ + @Output() onLicenseFileUploaded: EventEmitter = new EventEmitter(); + + constructor( + protected readonly formBuilder: FormBuilder, + protected readonly i18nService: I18nService, + protected readonly platformUtilsService: PlatformUtilsService, + protected readonly toastService: ToastService, + protected readonly tokenService: TokenService, + private readonly apiService: ApiService, + private readonly encryptService: EncryptService, + private readonly cryptoService: CryptoService, + private readonly organizationApiService: OrganizationApiServiceAbstraction, + private readonly syncService: SyncService, + ) { + super(formBuilder, i18nService, platformUtilsService, toastService, tokenService); + } + + protected async submit(): Promise { + await super.submit(); + + const orgKey = await this.cryptoService.makeOrgKey(); + const key = orgKey[0].encryptedString; + const collection = await this.encryptService.encrypt( + this.i18nService.t("defaultCollection"), + orgKey[1], + ); + const collectionCt = collection.encryptedString; + const orgKeys = await this.cryptoService.makeKeyPair(orgKey[1]); + + const fd = new FormData(); + fd.append("license", this.formValue.file); + fd.append("key", key); + fd.append("collectionName", collectionCt); + const response = await this.organizationApiService.createLicense(fd); + const orgId = response.id; + + await this.apiService.refreshIdentityToken(); + + // Org Keys live outside of the OrganizationLicense - add the keys to the org here + const request = new OrganizationKeysRequest(orgKeys[0], orgKeys[1].encryptedString); + await this.organizationApiService.updateKeys(orgId, request); + + await this.apiService.refreshIdentityToken(); + await this.syncService.fullSync(true); + + this.onLicenseFileUploaded.emit(orgId); + } + + get description(): string { + return "uploadLicenseFileOrg"; + } + + get hintFileName(): string { + return "bitwarden_organization_license.json"; + } +} diff --git a/apps/web/src/app/billing/shared/self-hosting-license-uploader/self-hosting-license-uploader.component.html b/apps/web/src/app/billing/shared/self-hosting-license-uploader/self-hosting-license-uploader.component.html new file mode 100644 index 00000000000..2238c10dd4a --- /dev/null +++ b/apps/web/src/app/billing/shared/self-hosting-license-uploader/self-hosting-license-uploader.component.html @@ -0,0 +1,26 @@ +

{{ "uploadLicenseFileOrg" | i18n }}

+ + + {{ description | i18n }} +
+ + {{ form.value.file ? form.value.file.name : ("noFileChosen" | i18n) }} +
+ + {{ "licenseFileDesc" | i18n: hintFileName }} +
+ + 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 7d4309b7bc6..cfefbbe4d74 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 @@ -5,6 +5,7 @@ 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 { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { OrganizationId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { CipherRepromptType } from "@bitwarden/common/vault/enums/cipher-reprompt-type"; @@ -81,7 +82,7 @@ export class CipherReportComponent implements OnDestroy { if (filterId === 0) { cipherCount = this.allCiphers.length; } else if (filterId === 1) { - cipherCount = this.allCiphers.filter((c: any) => c.orgFilterStatus === null).length; + cipherCount = this.allCiphers.filter((c) => c.organizationId === null).length; } else { this.organizations.filter((org: Organization) => { if (org.id === filterId) { @@ -89,22 +90,20 @@ export class CipherReportComponent implements OnDestroy { return org; } }); - cipherCount = this.allCiphers.filter( - (c: any) => c.orgFilterStatus === orgFilterStatus, - ).length; + cipherCount = this.allCiphers.filter((c) => c.organizationId === orgFilterStatus).length; } return cipherCount; } async filterOrgToggle(status: any) { - this.currentFilterStatus = status; - if (status === 0) { - this.dataSource.filter = null; - } else if (status === 1) { - this.dataSource.filter = (c: any) => c.orgFilterStatus == null; - } else { - this.dataSource.filter = (c: any) => c.orgFilterStatus === status; + let filter = null; + if (typeof status === "number" && status === 1) { + filter = (c: CipherView) => c.organizationId == null; + } else if (typeof status === "string") { + const orgId = status as OrganizationId; + filter = (c: CipherView) => c.organizationId === orgId; } + this.dataSource.filter = filter; } async load() { @@ -183,9 +182,7 @@ export class CipherReportComponent implements OnDestroy { protected filterCiphersByOrg(ciphersList: CipherView[]) { this.allCiphers = [...ciphersList]; - this.ciphers = ciphersList.map((ciph: any) => { - ciph.orgFilterStatus = ciph.organizationId; - + this.ciphers = ciphersList.map((ciph) => { if (this.filterStatus.indexOf(ciph.organizationId) === -1 && ciph.organizationId != null) { this.filterStatus.push(ciph.organizationId); } else if (this.filterStatus.indexOf(1) === -1 && ciph.organizationId == null) { @@ -193,7 +190,6 @@ export class CipherReportComponent implements OnDestroy { } return ciph; }); - this.dataSource.data = this.ciphers; if (this.filterStatus.length > 2) { diff --git a/apps/web/src/app/tools/reports/pages/exposed-passwords-report.component.html b/apps/web/src/app/tools/reports/pages/exposed-passwords-report.component.html index bcd5a28812a..b3f2ae581b3 100644 --- a/apps/web/src/app/tools/reports/pages/exposed-passwords-report.component.html +++ b/apps/web/src/app/tools/reports/pages/exposed-passwords-report.component.html @@ -34,7 +34,9 @@ {{ "owner" | i18n }} - + + {{ "timesExposed" | i18n }} + diff --git a/apps/web/src/app/tools/reports/pages/reused-passwords-report.component.html b/apps/web/src/app/tools/reports/pages/reused-passwords-report.component.html index e836c14996f..af336c94854 100644 --- a/apps/web/src/app/tools/reports/pages/reused-passwords-report.component.html +++ b/apps/web/src/app/tools/reports/pages/reused-passwords-report.component.html @@ -39,7 +39,7 @@ {{ "name" | i18n }} {{ "owner" | i18n }} - + {{ "timesReused" | i18n }} 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 0ebecab9f10..4ee0e2986bd 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 @@ -32,12 +32,16 @@ - + - {{ "name" | i18n }} - {{ "owner" | i18n }} - + {{ "name" | i18n }} + + {{ "owner" | i18n }} + + + {{ "weakness" | i18n }} + @@ -80,7 +84,7 @@
{{ r.subTitle }} - + - - {{ passwordStrengthMap.get(r.id)[0] | i18n }} + + {{ r.reportValue.label | i18n }} 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 f33e0626abb..7782e96e97e 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 @@ -14,16 +14,17 @@ import { PasswordRepromptService } from "@bitwarden/vault"; import { CipherReportComponent } from "./cipher-report.component"; +type ReportScore = { label: string; badgeVariant: BadgeVariant }; +type ReportResult = CipherView & { reportValue: ReportScore }; + @Component({ selector: "app-weak-passwords-report", templateUrl: "weak-passwords-report.component.html", }) export class WeakPasswordsReportComponent extends CipherReportComponent implements OnInit { - passwordStrengthMap = new Map(); disabled = true; - private passwordStrengthCache = new Map(); - weakPasswordCiphers: CipherView[] = []; + weakPasswordCiphers: ReportResult[] = []; constructor( protected cipherService: CipherService, @@ -49,16 +50,15 @@ export class WeakPasswordsReportComponent extends CipherReportComponent implemen } async setCiphers() { - const allCiphers: any = await this.getAllCiphers(); - this.passwordStrengthCache = new Map(); + const allCiphers = await this.getAllCiphers(); this.weakPasswordCiphers = []; this.filterStatus = [0]; this.findWeakPasswords(allCiphers); } - protected findWeakPasswords(ciphers: any[]): void { + protected findWeakPasswords(ciphers: CipherView[]): void { ciphers.forEach((ciph) => { - const { type, login, isDeleted, edit, viewPassword, id } = ciph; + const { type, login, isDeleted, edit, viewPassword } = ciph; if ( type !== CipherType.Login || login.password == null || @@ -71,50 +71,39 @@ export class WeakPasswordsReportComponent extends CipherReportComponent implemen } const hasUserName = this.isUserNameNotEmpty(ciph); - const cacheKey = this.getCacheKey(ciph); - if (!this.passwordStrengthCache.has(cacheKey)) { - let userInput: string[] = []; - if (hasUserName) { - const atPosition = login.username.indexOf("@"); - if (atPosition > -1) { - userInput = userInput - .concat( - login.username - .substr(0, atPosition) - .trim() - .toLowerCase() - .split(/[^A-Za-z0-9]/), - ) - .filter((i) => i.length >= 3); - } else { - userInput = login.username - .trim() - .toLowerCase() - .split(/[^A-Za-z0-9]/) - .filter((i: any) => i.length >= 3); - } + let userInput: string[] = []; + if (hasUserName) { + const atPosition = login.username.indexOf("@"); + if (atPosition > -1) { + userInput = userInput + .concat( + login.username + .substr(0, atPosition) + .trim() + .toLowerCase() + .split(/[^A-Za-z0-9]/), + ) + .filter((i) => i.length >= 3); + } else { + userInput = login.username + .trim() + .toLowerCase() + .split(/[^A-Za-z0-9]/) + .filter((i) => i.length >= 3); } - const result = this.passwordStrengthService.getPasswordStrength( - login.password, - null, - userInput.length > 0 ? userInput : null, - ); - this.passwordStrengthCache.set(cacheKey, result.score); } - const score = this.passwordStrengthCache.get(cacheKey); - - if (score != null && score <= 2) { - this.passwordStrengthMap.set(id, this.scoreKey(score)); - this.weakPasswordCiphers.push(ciph); - } - }); - this.weakPasswordCiphers.sort((a, b) => { - return ( - this.passwordStrengthCache.get(this.getCacheKey(a)) - - this.passwordStrengthCache.get(this.getCacheKey(b)) + const result = this.passwordStrengthService.getPasswordStrength( + login.password, + null, + userInput.length > 0 ? userInput : null, ); - }); + if (result.score != null && result.score <= 2) { + const scoreValue = this.scoreKey(result.score); + const row = { ...ciph, reportValue: scoreValue } as ReportResult; + this.weakPasswordCiphers.push(row); + } + }); this.filterCiphersByOrg(this.weakPasswordCiphers); } @@ -127,20 +116,16 @@ export class WeakPasswordsReportComponent extends CipherReportComponent implemen return !Utils.isNullOrWhitespace(c.login.username); } - private getCacheKey(c: CipherView): string { - return c.login.password + "_____" + (this.isUserNameNotEmpty(c) ? c.login.username : ""); - } - - private scoreKey(score: number): [string, BadgeVariant] { + private scoreKey(score: number): ReportScore { switch (score) { case 4: - return ["strong", "success"]; + return { label: "strong", badgeVariant: "success" }; case 3: - return ["good", "primary"]; + return { label: "good", badgeVariant: "primary" }; case 2: - return ["weak", "warning"]; + return { label: "weak", badgeVariant: "warning" }; default: - return ["veryWeak", "danger"]; + return { label: "veryWeak", badgeVariant: "danger" }; } } } 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 a1d07345352..fe889aa9775 100644 --- a/apps/web/src/app/vault/org-vault/vault.component.ts +++ b/apps/web/src/app/vault/org-vault/vault.component.ts @@ -27,6 +27,7 @@ import { switchMap, takeUntil, tap, + withLatestFrom, } from "rxjs/operators"; import { @@ -491,15 +492,13 @@ export class VaultComponent implements OnInit, OnDestroy { firstSetup$ .pipe( - switchMap(() => - combineLatest([this.route.queryParams, allCipherMap$, allCollections$, organization$]), - ), + switchMap(() => this.route.queryParams), + withLatestFrom(allCipherMap$, allCollections$, organization$), switchMap(async ([qParams, allCiphersMap]) => { const cipherId = getCipherIdFromParams(qParams); if (!cipherId) { return; } - const cipher = allCiphersMap[cipherId]; if (cipher) { diff --git a/apps/web/src/locales/af/messages.json b/apps/web/src/locales/af/messages.json index 31b2e1ecdc6..e4896b63a84 100644 --- a/apps/web/src/locales/af/messages.json +++ b/apps/web/src/locales/af/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Voeg syfer toe" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Wagwoordgeskiedenis" }, diff --git a/apps/web/src/locales/ar/messages.json b/apps/web/src/locales/ar/messages.json index bfa8c4e38ba..25f7ccd8f10 100644 --- a/apps/web/src/locales/ar/messages.json +++ b/apps/web/src/locales/ar/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "بما في ذلك الأرقام" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "سجل كلمات المرور" }, diff --git a/apps/web/src/locales/az/messages.json b/apps/web/src/locales/az/messages.json index 10e84f1e955..b745617ebae 100644 --- a/apps/web/src/locales/az/messages.json +++ b/apps/web/src/locales/az/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Rəqəm əlavə et" }, + "generatorPolicyInEffect": { + "message": "Müəssisə siyasət tələbləri, yaradıcı seçimlərinizə tətbiq edildi.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Parol tarixçəsi" }, diff --git a/apps/web/src/locales/be/messages.json b/apps/web/src/locales/be/messages.json index 71ac5920a0a..26fcce71fa8 100644 --- a/apps/web/src/locales/be/messages.json +++ b/apps/web/src/locales/be/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Уключыць лічбу" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Гісторыя пароляў" }, diff --git a/apps/web/src/locales/bg/messages.json b/apps/web/src/locales/bg/messages.json index bec147c11e7..3869f44f41f 100644 --- a/apps/web/src/locales/bg/messages.json +++ b/apps/web/src/locales/bg/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "И цифри" }, + "generatorPolicyInEffect": { + "message": "Изискванията на политиката за големи компании бяха приложени към настройките на генератора.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Хронология на паролата" }, diff --git a/apps/web/src/locales/bn/messages.json b/apps/web/src/locales/bn/messages.json index 276dd760241..2fcc9c9e293 100644 --- a/apps/web/src/locales/bn/messages.json +++ b/apps/web/src/locales/bn/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Include number" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Password history" }, diff --git a/apps/web/src/locales/bs/messages.json b/apps/web/src/locales/bs/messages.json index 82e3979880f..8b9fd8a1616 100644 --- a/apps/web/src/locales/bs/messages.json +++ b/apps/web/src/locales/bs/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Include number" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Password history" }, diff --git a/apps/web/src/locales/ca/messages.json b/apps/web/src/locales/ca/messages.json index 1f8d01e3541..e6e11e50a89 100644 --- a/apps/web/src/locales/ca/messages.json +++ b/apps/web/src/locales/ca/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Inclou número" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Historial de les contrasenyes" }, diff --git a/apps/web/src/locales/cs/messages.json b/apps/web/src/locales/cs/messages.json index 3c605153fa2..dc2076b2c40 100644 --- a/apps/web/src/locales/cs/messages.json +++ b/apps/web/src/locales/cs/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Zahrnout číslice" }, + "generatorPolicyInEffect": { + "message": "Na volby generátoru byly uplatněny požadavky podnikových zásad.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Historie hesel" }, @@ -9003,22 +9007,22 @@ "message": "zakoupení uživatelé odebráni" }, "environmentVariables": { - "message": "Environment variables" + "message": "Proměnné prostředí" }, "organizationId": { - "message": "Organization ID" + "message": "ID organizace" }, "projectIds": { - "message": "Project IDs" + "message": "ID projektu" }, "projectId": { - "message": "Project ID" + "message": "ID projektu" }, "projectsAccessedByMachineAccount": { - "message": "The following projects can be accessed by this machine account." + "message": "Následující projekty mohou být přístupné z tohoto počítačového účtu." }, "config": { - "message": "Config" + "message": "Nastavení" }, "learnMoreAboutEmergencyAccess": { "message": "Další informace o nouzovém přístupu" diff --git a/apps/web/src/locales/cy/messages.json b/apps/web/src/locales/cy/messages.json index dc59ad0079e..7a24f52cde7 100644 --- a/apps/web/src/locales/cy/messages.json +++ b/apps/web/src/locales/cy/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Include number" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Password history" }, diff --git a/apps/web/src/locales/da/messages.json b/apps/web/src/locales/da/messages.json index be07e684cc3..a15d161ba80 100644 --- a/apps/web/src/locales/da/messages.json +++ b/apps/web/src/locales/da/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Inkludér ciffer" }, + "generatorPolicyInEffect": { + "message": "Virksomhedspolitikkrav gør sig gældende på generatorvalgmulighder.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Adgangskodehistorik" }, diff --git a/apps/web/src/locales/de/messages.json b/apps/web/src/locales/de/messages.json index c7961eba8f6..77e21a69651 100644 --- a/apps/web/src/locales/de/messages.json +++ b/apps/web/src/locales/de/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Ziffern einschließen" }, + "generatorPolicyInEffect": { + "message": "Die Unternehmensrichtlinien-Anforderungen wurden auf deine Generator-Optionen angewendet.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Passwortverlauf" }, diff --git a/apps/web/src/locales/el/messages.json b/apps/web/src/locales/el/messages.json index bc70723da71..bf1fa4d0804 100644 --- a/apps/web/src/locales/el/messages.json +++ b/apps/web/src/locales/el/messages.json @@ -70,7 +70,7 @@ } }, "itemHistory": { - "message": "Item history" + "message": "Ιστορικό στοιχείου" }, "authenticatorKey": { "message": "Κλειδί αυθεντικοποίησης" @@ -111,7 +111,7 @@ } }, "showMatchDetection": { - "message": "Show match detection $WEBSITE$", + "message": "Εμφάνιση ανίχνευσης αντιστοιχίας $WEBSITE$", "placeholders": { "website": { "content": "$1", @@ -120,7 +120,7 @@ } }, "hideMatchDetection": { - "message": "Hide match detection $WEBSITE$", + "message": "Απόκρυψη ανίχνευσης αντιστοιχίας $WEBSITE$", "placeholders": { "website": { "content": "$1", @@ -225,7 +225,7 @@ "message": "Ληγμένη κάρτα" }, "cardExpiredMessage": { - "message": "If you've renewed it, update the card's information" + "message": "Εάν την ανανεώσατε, ενημερώστε τα στοιχεία της κάρτας" }, "expirationMonth": { "message": "Μήνας λήξης" @@ -270,7 +270,7 @@ "message": "Δυαδικό" }, "cfTypeCheckbox": { - "message": "Checkbox" + "message": "Πλαίσιο ελέγχου" }, "cfTypeLinked": { "message": "Συνδεδεμένο", @@ -641,13 +641,13 @@ "message": "Αντιγραφή τηλεφώνου" }, "copyEmail": { - "message": "Copy email" + "message": "Αντιγραφή email" }, "copyCompany": { "message": "Αντιγραφή εταιρείας" }, "copySSN": { - "message": "Copy Social Security number" + "message": "Αντιγραφή ΑΜΚΑ" }, "copyPassportNumber": { "message": "Αντιγραφή αριθμού διαβατηρίου" @@ -1027,13 +1027,13 @@ "message": "Ρυθμίσεις" }, "accountEmail": { - "message": "Account email" + "message": "Email λογαριασμού" }, "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" @@ -1079,7 +1079,7 @@ "message": "Your new account has been created!" }, "youHaveBeenLoggedIn": { - "message": "You have been logged in!" + "message": "Έχετε συνδεθεί!" }, "trialAccountCreated": { "message": "Η δημιουργία του λογαριασμού ολοκληρώθηκε με επιτυχία." @@ -1228,7 +1228,7 @@ "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, "yubiKeyTitleV2": { - "message": "Yubico OTP security key" + "message": "Κλειδί ασφαλείας YubiKey OTP" }, "yubiKeyDesc": { "message": "Χρησιμοποιήστε ένα YubiKey για να αποκτήσετε πρόσβαση στο λογαριασμό σας. Λειτουργεί με συσκευές σειράς YubiKey 4, 5 και συσκευές NEO." @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Συμπερίληψη Αριθμών" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Ιστορικό Κωδικού" }, @@ -5107,7 +5111,7 @@ } }, "viewSend": { - "message": "View Send", + "message": "Προβολή Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "viewSendHiddenEmailWarning": { @@ -5145,10 +5149,10 @@ "message": "Η υπόδειξη κωδικού πρόσβασης, δεν μπορεί να είναι η ίδια με τον κωδικό πρόσβασης σας." }, "enrollAccountRecovery": { - "message": "Enroll in account recovery" + "message": "Εγγραφή στην ανάκτηση λογαριασμού" }, "enrolledAccountRecovery": { - "message": "Enrolled in account recovery" + "message": "Έγινε εγγραφή στην ανάκτηση λογαριασμού" }, "withdrawAccountRecovery": { "message": "Withdraw from account recovery" @@ -5160,7 +5164,7 @@ "message": "Επιτυχής απόσυρση!" }, "eventEnrollAccountRecovery": { - "message": "User $ID$ enrolled in account recovery.", + "message": "Ο χρήστης $ID$ εγγράφηκε στην ανάκτηση λογαριασμού.", "placeholders": { "id": { "content": "$1", @@ -6238,13 +6242,13 @@ "message": "Τυχαία Λέξη" }, "usernameGenerator": { - "message": "Username generator" + "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." @@ -6382,7 +6386,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": { @@ -6392,7 +6396,7 @@ } }, "forwarderNoUrl": { - "message": "Invalid $SERVICENAME$ url.", + "message": "Μη έγκυρο URL $SERVICENAME$.", "description": "Displayed when the url of the forwarding service wasn't supplied.", "placeholders": { "servicename": { @@ -6402,7 +6406,7 @@ } }, "forwarderUnknownError": { - "message": "Unknown $SERVICENAME$ error occurred.", + "message": "Παρουσιάστηκε άγνωστο σφάλμα $SERVICENAME$.", "description": "Displayed when the forwarding service failed due to an unknown error.", "placeholders": { "servicename": { @@ -6588,7 +6592,7 @@ "message": "Duo two-step login is required for your account." }, "launchDuo": { - "message": "Launch Duo" + "message": "Εκκίνηση Duo" }, "turnOn": { "message": "Ενεργοποίηση" @@ -6726,7 +6730,7 @@ "description": "A label for a type-to-filter input field to choose projects." }, "searchProjects": { - "message": "Search projects", + "message": "Αναζήτηση έργων", "description": "Label for the search bar used to search projects." }, "project": { @@ -6901,19 +6905,19 @@ "description": "Title indicating what permissions a service account has" }, "projectCommaSecret": { - "message": "Project, Secret", + "message": "Έργο, Μυστικό", "description": "" }, "serviceAccountName": { - "message": "Service account name", + "message": "Όνομα λογαριασμού υπηρεσίας", "description": "Label for the name of a service account" }, "serviceAccountCreated": { - "message": "Service account created", + "message": "Ο λογαριασμός υπηρεσίας δημιουργήθηκε", "description": "Notifies that a new service account has been created" }, "serviceAccountUpdated": { - "message": "Service account updated", + "message": "Ο λογαριασμός υπηρεσίας ενημερώθηκε", "description": "Notifies that a service account has been updated" }, "newSaSelectAccess": { @@ -7085,7 +7089,7 @@ "message": "Ενημέρωση" }, "plusNMore": { - "message": "+ $QUANTITY$ more", + "message": "+ $QUANTITY$ ακόμα", "placeholders": { "quantity": { "content": "$1", @@ -7193,13 +7197,13 @@ "message": "Removing a domain cannot be undone. Are you sure you want to continue?" }, "domainRemoved": { - "message": "Domain removed" + "message": "Ο τομέας αφαιρέθηκε" }, "domainSaved": { - "message": "Domain saved" + "message": "Ο τομέας αποθηκεύτηκε" }, "domainVerified": { - "message": "Domain verified" + "message": "Ο τομέας επαληθεύτηκε" }, "duplicateDomainError": { "message": "You can't claim the same domain twice." @@ -7289,13 +7293,13 @@ "message": "Επαλήθευση με βιομετρικά" }, "awaitingConfirmation": { - "message": "Awaiting confirmation" + "message": "Σε αναμονή επιβεβαίωσης" }, "couldNotCompleteBiometrics": { "message": "Could not complete biometrics." }, "needADifferentMethod": { - "message": "Need a different method?" + "message": "Χρειάζεστε μια διαφορετική μέθοδο;" }, "useMasterPassword": { "message": "Χρήση κύριου κωδικού πρόσβασης" @@ -7310,7 +7314,7 @@ "message": "Enter the verification code that was sent to your email." }, "resendCode": { - "message": "Resend code" + "message": "Επαναποστολή κωδικού" }, "memberColumnHeader": { "message": "Μέλος" @@ -7337,7 +7341,7 @@ "message": "Member status filter" }, "inviteMember": { - "message": "Invite member" + "message": "Πρόσκληση μέλους" }, "needsConfirmation": { "message": "Χρειάζεται επιβεβαίωση" @@ -7732,7 +7736,7 @@ "message": "Request admin approval" }, "approveWithMasterPassword": { - "message": "Approve with master password" + "message": "Έγκριση με κύριο κωδικό πρόσβασης" }, "trustedDeviceEncryption": { "message": "Κρυπτογράφηση έμπιστης συσκευής" @@ -7790,7 +7794,7 @@ "description": "Default title for the user verification dialog." }, "recoverAccount": { - "message": "Recover account" + "message": "Ανάκτηση λογαριασμού" }, "updatedTempPassword": { "message": "User updated a password issued through account recovery." @@ -7800,7 +7804,7 @@ "description": "Confirmation message that one or more users gained access to Secrets Manager" }, "activateAccess": { - "message": "Activate access" + "message": "Ενεργοποίηση πρόσβασης" }, "bulkEnableSecretsManagerDescription": { "message": "Grant the following members access to Secrets Manager. The role granted in the Password Manager will apply to Secrets Manager.", @@ -7814,7 +7818,7 @@ "description": "A 'fingerprint phrase' is a unique word phrase (similar to a passphrase) that a user can use to authenticate their organization's public key with another user, for the purposes of sharing." }, "deviceApprovals": { - "message": "Device approvals" + "message": "Εγκρίσεις συσκευής" }, "deviceApprovalsDesc": { "message": "Approve login requests below to allow the requesting member to finish logging in. Unapproved requests expire after 1 week. Verify the member’s information before approving." @@ -7969,10 +7973,10 @@ "message": "Free 2-person Organizations" }, "unlimitedSecrets": { - "message": "Unlimited secrets" + "message": "Απεριόριστα μυστικά" }, "unlimitedProjects": { - "message": "Unlimited projects" + "message": "Απεριόριστα έργα" }, "projectsIncluded": { "message": "$COUNT$ projects included", @@ -8050,10 +8054,10 @@ "message": "Secrets Manager plan price" }, "passwordManager": { - "message": "Password Manager" + "message": "Διαχείριση κωδικών πρόσβασης" }, "freeOrganization": { - "message": "Free Organization" + "message": "Δωρεάν οργανισμός" }, "limitServiceAccounts": { "message": "Limit service accounts (optional)" @@ -8242,13 +8246,13 @@ "message": "Provider Portal" }, "success": { - "message": "Success" + "message": "Επιτυχία" }, "restrictedGroupAccess": { - "message": "You cannot add yourself to groups." + "message": "Δεν μπορείτε να προσθέσετε τον εαυτό σας σε ομάδες." }, "cannotAddYourselfToCollections": { - "message": "You cannot add yourself to collections." + "message": "Δεν μπορείτε να προσθέσετε τον εαυτό σας σε συλλογές." }, "assign": { "message": "Assign" @@ -8385,15 +8389,15 @@ "message": "Machine accounts cannot be created in suspended organizations. Please contact your organization owner for assistance." }, "machineAccount": { - "message": "Machine account", + "message": "Λογαριασμός μηχανήματος", "description": "A machine user which can be used to automate processes and access secrets in the system." }, "machineAccounts": { - "message": "Machine accounts", + "message": "Λογαριασμοί μηχανημάτων", "description": "The title for the section that deals with machine accounts." }, "newMachineAccount": { - "message": "New machine account", + "message": "Νέος λογαριασμός μηχανήματος", "description": "Title for creating a new machine account." }, "machineAccountsNoItemsMessage": { @@ -8405,15 +8409,15 @@ "description": "Title to indicate that there are no machine accounts to display." }, "deleteMachineAccounts": { - "message": "Delete machine accounts", + "message": "Διαγραφή λογαριασμών μηχανημάτων", "description": "Title for the action to delete one or multiple machine accounts." }, "deleteMachineAccount": { - "message": "Delete machine account", + "message": "Διαγραφή λογαριασμού μηχανήματος", "description": "Title for the action to delete a single machine account." }, "viewMachineAccount": { - "message": "View machine account", + "message": "Προβολή λογαριασμού μηχανήματος", "description": "Action to view the details of a machine account." }, "deleteMachineAccountDialogMessage": { @@ -8438,21 +8442,21 @@ } }, "deleteMachineAccountToast": { - "message": "Machine account deleted" + "message": "Ο λογαριασμός μηχανήματος διαγράφηκε" }, "deleteMachineAccountsToast": { - "message": "Machine accounts deleted" + "message": "Οι λογαριασμοί μηχανημάτων διαγράφηκαν" }, "searchMachineAccounts": { - "message": "Search machine accounts", + "message": "Αναζήτηση λογαριασμών μηχανημάτων", "description": "Placeholder text for searching machine accounts." }, "editMachineAccount": { - "message": "Edit machine account", + "message": "Επεξεργασία λογαριασμού μηχανήματος", "description": "Title for editing a machine account." }, "machineAccountName": { - "message": "Machine account name", + "message": "Όνομα λογαριασμού μηχανήματος", "description": "Label for the name of a machine account" }, "machineAccountCreated": { @@ -8572,7 +8576,7 @@ } }, "providerDeleted": { - "message": "Provider deleted" + "message": "Ο πάροχος διαγράφηκε" }, "providerDeletedDesc": { "message": "The Provider and all associated data has been deleted." @@ -8657,7 +8661,7 @@ "message": "month per member" }, "seats": { - "message": "Seats" + "message": "Θέσεις" }, "addOrganization": { "message": "Προσθήκη οργανισμού" @@ -8754,7 +8758,7 @@ "message": "Managed Service Provider" }, "orgSeats": { - "message": "Organization Seats" + "message": "Θέσεις οργανισμού" }, "providerDiscount": { "message": "Έκπτωση $AMOUNT$%", @@ -8769,7 +8773,7 @@ "message": "Low KDF iterations. Increase your iterations to improve the security of your account." }, "changeKDFSettings": { - "message": "Change KDF settings" + "message": "Αλλαγή ρυθμίσεων KDF" }, "secureYourInfrastructure": { "message": "Secure your infrastructure" @@ -8784,10 +8788,10 @@ "message": "Stay ahead of security vulnerabilities by upgrading to a paid plan for enhanced monitoring." }, "approveAllRequests": { - "message": "Approve all requests" + "message": "Έγκριση όλων των αιτημάτων" }, "allLoginRequestsApproved": { - "message": "All login requests approved" + "message": "Όλα τα αιτήματα σύνδεσης εγκρίθηκαν" }, "payPal": { "message": "PayPal" @@ -8842,19 +8846,19 @@ "message": "(No Collection Permission)" }, "memberAccessReportNoGroup": { - "message": "(No Group)" + "message": "(Χωρίς ομάδα)" }, "memberAccessReportTwoFactorEnabledTrue": { - "message": "On" + "message": "Ενεργός" }, "memberAccessReportTwoFactorEnabledFalse": { - "message": "Off" + "message": "Ανενεργός" }, "memberAccessReportAuthenticationEnabledTrue": { - "message": "On" + "message": "Ενεργή" }, "memberAccessReportAuthenticationEnabledFalse": { - "message": "Off" + "message": "Ανενεργή" }, "higherKDFIterations": { "message": "Higher KDF iterations can help protect your master password from being brute forced by an attacker." @@ -8957,10 +8961,10 @@ "message": "After making updates in the Bitwarden cloud server, upload your license file to apply the most recent changes." }, "addToFolder": { - "message": "Add to folder" + "message": "Προσθήκη σε φάκελο" }, "selectFolder": { - "message": "Select folder" + "message": "Επιλογή φακέλου" }, "personalItemTransferWarningSingular": { "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." @@ -9021,10 +9025,10 @@ "message": "Config" }, "learnMoreAboutEmergencyAccess": { - "message": "Learn more about emergency access" + "message": "Μάθετε περισσότερα για την πρόσβαση έκτακτης ανάγκης" }, "learnMoreAboutMatchDetection": { - "message": "Learn more about match detection" + "message": "Μάθετε περισσότερα για την ανίχνευση αντιστοιχίας" }, "learnMoreAboutMasterPasswordReprompt": { "message": "Learn more about master password re-prompt" @@ -9063,13 +9067,13 @@ "message": "Learn more about Bitwarden's API" }, "fileSends": { - "message": "File Sends" + "message": "Send αρχείων" }, "textSends": { - "message": "Text Sends" + "message": "Send κειμένων" }, "includesXMembers": { - "message": "for $COUNT$ member", + "message": "για $COUNT$ μέλος(η)", "placeholders": { "count": { "content": "$1", @@ -9099,7 +9103,7 @@ } }, "includeSsoAuthenticationMessage": { - "message": "SSO Authentication" + "message": "Πιστοποίηση SSO" }, "familiesPlanInvLimitReachedManageBilling": { "message": "Families organizations may have up to $SEATCOUNT$ members. Upgrade to a paid plan to invite more members.", @@ -9156,16 +9160,16 @@ "message": "GB additional storage" }, "premiumAccounts": { - "message": "6 premium accounts" + "message": "6 λογαριασμοί premium" }, "unlimitedSharing": { - "message": "Unlimited sharing" + "message": "Απεριόριστη κοινή χρήση" }, "unlimitedCollections": { - "message": "Unlimited collections" + "message": "Απεριόριστες συλλογές" }, "secureDataSharing": { - "message": "Secure data sharing" + "message": "Ασφαλής κοινή χρήση δεδομένων" }, "eventLogMonitoring": { "message": "Event log monitoring" @@ -9177,22 +9181,22 @@ "message": "Passwordless SSO" }, "accountRecovery": { - "message": "Account recovery" + "message": "Ανάκτηση λογαριασμού" }, "customRoles": { - "message": "Custom roles" + "message": "Προσαρμοσμένοι ρόλοι" }, "unlimitedSecretsStorage": { "message": "Unlimited secrets storage" }, "unlimitedUsers": { - "message": "Unlimited users" + "message": "Απεριόριστοι χρήστες" }, "UpTo50MachineAccounts": { - "message": "Up to 50 machine accounts" + "message": "Έως και 50 λογαριασμοί μηχανημάτων" }, "UpTo20MachineAccounts": { - "message": "Up to 20 machine accounts" + "message": "Έως και 20 λογαριασμοί μηχανημάτων" }, "current": { "message": "Current" @@ -9201,7 +9205,7 @@ "message": "Your Secrets Manager subscription will upgrade based on the plan selected" }, "bitwardenPasswordManager": { - "message": "Bitwarden Password Manager" + "message": "Bitwarden: Διαχείριση κωδικών πρόσβασης" }, "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." @@ -9220,6 +9224,6 @@ "message": "Απόκρυψη αριθμού χαρακτήρων" }, "editAccess": { - "message": "Edit access" + "message": "Επεξεργασία πρόσβασης" } } diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index ed3bc14c254..63dbd6ff9ce 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -2199,6 +2199,9 @@ "checkExposedPasswords": { "message": "Check exposed passwords" }, + "timesExposed": { + "message": "Times exposed" + }, "exposedXTimes": { "message": "Exposed $COUNT$ time(s)", "placeholders": { @@ -2233,6 +2236,9 @@ "noWeakPasswords": { "message": "No items in your vault have weak passwords." }, + "weakness": { + "message": "Weakness" + }, "reusedPasswordsReport": { "message": "Reused passwords" }, @@ -2258,6 +2264,9 @@ "noReusedPasswords": { "message": "No logins in your vault have passwords that are being reused." }, + "timesReused": { + "message": "Times reused" + }, "reusedXTimes": { "message": "Reused $COUNT$ times", "placeholders": { diff --git a/apps/web/src/locales/en_GB/messages.json b/apps/web/src/locales/en_GB/messages.json index 2f54c367692..72462e3786a 100644 --- a/apps/web/src/locales/en_GB/messages.json +++ b/apps/web/src/locales/en_GB/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Include number" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Password history" }, diff --git a/apps/web/src/locales/en_IN/messages.json b/apps/web/src/locales/en_IN/messages.json index a32fe1a382f..0d076726327 100644 --- a/apps/web/src/locales/en_IN/messages.json +++ b/apps/web/src/locales/en_IN/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Include number" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Password history" }, diff --git a/apps/web/src/locales/eo/messages.json b/apps/web/src/locales/eo/messages.json index 955a362b5f3..3052b4f5205 100644 --- a/apps/web/src/locales/eo/messages.json +++ b/apps/web/src/locales/eo/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Inkluzivi numeron" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Pasvorta Historio" }, diff --git a/apps/web/src/locales/es/messages.json b/apps/web/src/locales/es/messages.json index 751dd63f8fe..f665756842e 100644 --- a/apps/web/src/locales/es/messages.json +++ b/apps/web/src/locales/es/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Incluir número" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Historial de contraseñas" }, diff --git a/apps/web/src/locales/et/messages.json b/apps/web/src/locales/et/messages.json index b69360d0891..8acf520cb6f 100644 --- a/apps/web/src/locales/et/messages.json +++ b/apps/web/src/locales/et/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Numbriga" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Paroolide ajalugu" }, diff --git a/apps/web/src/locales/eu/messages.json b/apps/web/src/locales/eu/messages.json index aab9e193ad6..930b83584be 100644 --- a/apps/web/src/locales/eu/messages.json +++ b/apps/web/src/locales/eu/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Sartu zenbakia" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Pasahitz historia" }, diff --git a/apps/web/src/locales/fa/messages.json b/apps/web/src/locales/fa/messages.json index c1f9660643b..fe707354049 100644 --- a/apps/web/src/locales/fa/messages.json +++ b/apps/web/src/locales/fa/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "شامل عدد" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "تاریخچه کلمه عبور" }, diff --git a/apps/web/src/locales/fi/messages.json b/apps/web/src/locales/fi/messages.json index 2be651f3b65..15923a3c85f 100644 --- a/apps/web/src/locales/fi/messages.json +++ b/apps/web/src/locales/fi/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Sisällytä numero" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Salasanahistoria" }, diff --git a/apps/web/src/locales/fil/messages.json b/apps/web/src/locales/fil/messages.json index c907b7fc2a3..b24dc06d18c 100644 --- a/apps/web/src/locales/fil/messages.json +++ b/apps/web/src/locales/fil/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Magsama ng mga numero" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Kasaysayan ng password" }, diff --git a/apps/web/src/locales/fr/messages.json b/apps/web/src/locales/fr/messages.json index c1c669acc74..c41479177c8 100644 --- a/apps/web/src/locales/fr/messages.json +++ b/apps/web/src/locales/fr/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Inclure un Chiffre" }, + "generatorPolicyInEffect": { + "message": "Les exigences de la politique de sécurité de l'entreprise ont été appliquées aux options de votre générateur.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Historique des mots de passe" }, diff --git a/apps/web/src/locales/gl/messages.json b/apps/web/src/locales/gl/messages.json index d41fbb4ff49..e8ed2bc6008 100644 --- a/apps/web/src/locales/gl/messages.json +++ b/apps/web/src/locales/gl/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Include number" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Password history" }, diff --git a/apps/web/src/locales/he/messages.json b/apps/web/src/locales/he/messages.json index 2dd52d914bc..72c0840832a 100644 --- a/apps/web/src/locales/he/messages.json +++ b/apps/web/src/locales/he/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "כלול מספרים" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "היסטוריית סיסמאות" }, diff --git a/apps/web/src/locales/hi/messages.json b/apps/web/src/locales/hi/messages.json index 0f08cf9ad5b..2af048332b3 100644 --- a/apps/web/src/locales/hi/messages.json +++ b/apps/web/src/locales/hi/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Include number" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Password history" }, diff --git a/apps/web/src/locales/hr/messages.json b/apps/web/src/locales/hr/messages.json index 82afe5fe3ab..055592ca382 100644 --- a/apps/web/src/locales/hr/messages.json +++ b/apps/web/src/locales/hr/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Uključi broj" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Povijest" }, diff --git a/apps/web/src/locales/hu/messages.json b/apps/web/src/locales/hu/messages.json index 7db2c68e09e..65dd6330a78 100644 --- a/apps/web/src/locales/hu/messages.json +++ b/apps/web/src/locales/hu/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Szám is" }, + "generatorPolicyInEffect": { + "message": "A vállalati házirend követelményei kerülnek alkalmazásra a generátor beállításaira.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Jelszóelőzmények" }, diff --git a/apps/web/src/locales/id/messages.json b/apps/web/src/locales/id/messages.json index 8fb655a4ad6..910d9a47629 100644 --- a/apps/web/src/locales/id/messages.json +++ b/apps/web/src/locales/id/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Sertakan Digit" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Riwayat Kata Sandi" }, diff --git a/apps/web/src/locales/it/messages.json b/apps/web/src/locales/it/messages.json index 7628e19211a..86d68b29f99 100644 --- a/apps/web/src/locales/it/messages.json +++ b/apps/web/src/locales/it/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Includi numero" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Cronologia delle password" }, diff --git a/apps/web/src/locales/ja/messages.json b/apps/web/src/locales/ja/messages.json index a6bdd82e13e..3694666f24e 100644 --- a/apps/web/src/locales/ja/messages.json +++ b/apps/web/src/locales/ja/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "数字を含む" }, + "generatorPolicyInEffect": { + "message": "生成オプションにエンタープライズポリシー要件を適用しました", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "パスワードの履歴" }, diff --git a/apps/web/src/locales/ka/messages.json b/apps/web/src/locales/ka/messages.json index d24cef82ec6..c19eba3cf9b 100644 --- a/apps/web/src/locales/ka/messages.json +++ b/apps/web/src/locales/ka/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Include number" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Password history" }, diff --git a/apps/web/src/locales/km/messages.json b/apps/web/src/locales/km/messages.json index de896a154c4..b00f71df724 100644 --- a/apps/web/src/locales/km/messages.json +++ b/apps/web/src/locales/km/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Include number" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Password history" }, diff --git a/apps/web/src/locales/kn/messages.json b/apps/web/src/locales/kn/messages.json index cf6597a3b1d..35227fb425c 100644 --- a/apps/web/src/locales/kn/messages.json +++ b/apps/web/src/locales/kn/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "ಸಂಖ್ಯೆಯನ್ನು ಸೇರಿಸಿ" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "ಪಾಸ್ವರ್ಡ್ ಇತಿಹಾಸ" }, diff --git a/apps/web/src/locales/ko/messages.json b/apps/web/src/locales/ko/messages.json index 51e53d0ec25..7803f09d522 100644 --- a/apps/web/src/locales/ko/messages.json +++ b/apps/web/src/locales/ko/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "숫자 추가" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "비밀번호 변경 기록" }, diff --git a/apps/web/src/locales/lv/messages.json b/apps/web/src/locales/lv/messages.json index 7c79cb9e989..4a0039cb06b 100644 --- a/apps/web/src/locales/lv/messages.json +++ b/apps/web/src/locales/lv/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Iekļaut ciparu" }, + "generatorPolicyInEffect": { + "message": "Veidotāja iespējām tika piemērotas uzņēmējdarbības nosacījumu prasības.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Paroles izmaiņu vēsture" }, diff --git a/apps/web/src/locales/ml/messages.json b/apps/web/src/locales/ml/messages.json index e3f9c72ea09..5053266687e 100644 --- a/apps/web/src/locales/ml/messages.json +++ b/apps/web/src/locales/ml/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "നമ്പർ ഉൾപ്പെടുത്തുക" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "പാസ്സ്‌വേഡ് ചരിത്രം" }, diff --git a/apps/web/src/locales/mr/messages.json b/apps/web/src/locales/mr/messages.json index de896a154c4..b00f71df724 100644 --- a/apps/web/src/locales/mr/messages.json +++ b/apps/web/src/locales/mr/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Include number" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Password history" }, diff --git a/apps/web/src/locales/my/messages.json b/apps/web/src/locales/my/messages.json index de896a154c4..b00f71df724 100644 --- a/apps/web/src/locales/my/messages.json +++ b/apps/web/src/locales/my/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Include number" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Password history" }, diff --git a/apps/web/src/locales/nb/messages.json b/apps/web/src/locales/nb/messages.json index ca478c0e5d7..b228e618bb1 100644 --- a/apps/web/src/locales/nb/messages.json +++ b/apps/web/src/locales/nb/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Inkluder siffer" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Passordhistorikk" }, diff --git a/apps/web/src/locales/ne/messages.json b/apps/web/src/locales/ne/messages.json index dd0b9042e71..56d3cc013b7 100644 --- a/apps/web/src/locales/ne/messages.json +++ b/apps/web/src/locales/ne/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Include number" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Password history" }, diff --git a/apps/web/src/locales/nl/messages.json b/apps/web/src/locales/nl/messages.json index 9564258a68b..0213fcec644 100644 --- a/apps/web/src/locales/nl/messages.json +++ b/apps/web/src/locales/nl/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Cijfer toevoegen" }, + "generatorPolicyInEffect": { + "message": "Bedrijfsbeleidseisen zijn toegepast op je generator-instellingen.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Geschiedenis" }, diff --git a/apps/web/src/locales/nn/messages.json b/apps/web/src/locales/nn/messages.json index 1ccc3b7700d..662db9c1655 100644 --- a/apps/web/src/locales/nn/messages.json +++ b/apps/web/src/locales/nn/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Inkluder tal" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Passordoversyn" }, diff --git a/apps/web/src/locales/or/messages.json b/apps/web/src/locales/or/messages.json index de896a154c4..b00f71df724 100644 --- a/apps/web/src/locales/or/messages.json +++ b/apps/web/src/locales/or/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Include number" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Password history" }, diff --git a/apps/web/src/locales/pl/messages.json b/apps/web/src/locales/pl/messages.json index fbc7ccbe781..f41c635c768 100644 --- a/apps/web/src/locales/pl/messages.json +++ b/apps/web/src/locales/pl/messages.json @@ -37,7 +37,7 @@ "message": "Notatki" }, "note": { - "message": "Note" + "message": "Notatka" }, "customFields": { "message": "Pola niestandardowe" @@ -49,19 +49,19 @@ "message": "Dane logowania" }, "personalDetails": { - "message": "Personal details" + "message": "Dane osobowe" }, "identification": { - "message": "Identification" + "message": "Tożsamość" }, "contactInfo": { - "message": "Contact info" + "message": "Daje kontaktowe" }, "cardDetails": { - "message": "Card details" + "message": "Szczegóły karty" }, "cardBrandDetails": { - "message": "$BRAND$ details", + "message": "Szczegóły $BRAND$", "placeholders": { "brand": { "content": "$1", @@ -70,7 +70,7 @@ } }, "itemHistory": { - "message": "Item history" + "message": "Historia elementu" }, "authenticatorKey": { "message": "Klucz uwierzytelniający" @@ -82,7 +82,7 @@ "message": "Strona internetowa (URI)" }, "websiteUriCount": { - "message": "Website (URI) $COUNT$", + "message": "Strona internetowa (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": { @@ -111,7 +111,7 @@ } }, "showMatchDetection": { - "message": "Show match detection $WEBSITE$", + "message": "Pokaż wykrywanie dopasowań $WEBSITE$", "placeholders": { "website": { "content": "$1", @@ -120,7 +120,7 @@ } }, "hideMatchDetection": { - "message": "Hide match detection $WEBSITE$", + "message": "Ukryj wykrywanie dopasowań $WEBSITE$", "placeholders": { "website": { "content": "$1", @@ -144,7 +144,7 @@ "message": "Kod zabezpieczający (CVV)" }, "securityCodeSlashCVV": { - "message": "Security code / CVV" + "message": "Kod zabezpieczający / CVV" }, "identityName": { "message": "Nazwa profilu" @@ -222,10 +222,10 @@ "message": "Doktor" }, "cardExpiredTitle": { - "message": "Expired card" + "message": "Karta wygasła" }, "cardExpiredMessage": { - "message": "If you've renewed it, update the card's information" + "message": "Jeśli ją wznowiłeś, zaktualizuj informacje o karcie" }, "expirationMonth": { "message": "Miesiąc wygaśnięcia" @@ -246,7 +246,7 @@ "message": "Bitwarden może przechowywać i wypełniać kody weryfikacyjne. Wybierz ikonę aparatu, aby zrobić zrzut ekranu z kodem QR lub skopiuj i wklej klucz do tego pola." }, "learnMoreAboutAuthenticators": { - "message": "Learn more about authenticators" + "message": "Dowiedz się więcej o uwierzytelniaczach" }, "folder": { "message": "Folder" @@ -270,17 +270,17 @@ "message": "Wartość logiczna" }, "cfTypeCheckbox": { - "message": "Checkbox" + "message": "Pole wyboru" }, "cfTypeLinked": { "message": "Powiązane pole", "description": "This describes a field that is 'linked' (related) to another field." }, "fieldType": { - "message": "Field type" + "message": "Typ pola" }, "fieldLabel": { - "message": "Field label" + "message": "Etykieta pola" }, "remove": { "message": "Usuń" @@ -476,7 +476,7 @@ "message": "Imię i nazwisko" }, "address": { - "message": "Address" + "message": "Adres" }, "address1": { "message": "Adres 1" @@ -521,7 +521,7 @@ "message": "Zobacz element" }, "newItemHeader": { - "message": "New $TYPE$", + "message": "Nowy $TYPE$", "placeholders": { "type": { "content": "$1", @@ -530,7 +530,7 @@ } }, "editItemHeader": { - "message": "Edit $TYPE$", + "message": "Edytuj $TYPE$", "placeholders": { "type": { "content": "$1", @@ -539,7 +539,7 @@ } }, "viewItemType": { - "message": "View $ITEMTYPE$", + "message": "Zobacz $TYPE$", "placeholders": { "itemtype": { "content": "$1", @@ -593,7 +593,7 @@ } }, "copySuccessful": { - "message": "Copy Successful" + "message": "Kopiowanie zakończone sukcesem" }, "copyValue": { "message": "Kopiuj wartość", @@ -620,7 +620,7 @@ "description": "Copy URI to clipboard" }, "copyCustomField": { - "message": "Copy $FIELD$", + "message": "Skopiuj $FIELD$", "placeholders": { "field": { "content": "$1", @@ -629,34 +629,34 @@ } }, "copyWebsite": { - "message": "Copy website" + "message": "Skopiuj stronę internetową" }, "copyNotes": { - "message": "Copy notes" + "message": "Skopiuj notatki" }, "copyAddress": { - "message": "Copy address" + "message": "Skopiuj adres" }, "copyPhone": { - "message": "Copy phone" + "message": "Skopiuj telefon" }, "copyEmail": { - "message": "Copy email" + "message": "Skopiuj e-mail" }, "copyCompany": { - "message": "Copy company" + "message": "Skopiuj firmę" }, "copySSN": { - "message": "Copy Social Security number" + "message": "Skopiuj numer PESEL" }, "copyPassportNumber": { - "message": "Copy passport number" + "message": "Skopiuj numer paszportu" }, "copyLicenseNumber": { - "message": "Copy license number" + "message": "Skopiuj numer licencji" }, "copyName": { - "message": "Copy name" + "message": "Skopiuj nazwę" }, "me": { "message": "Ja" @@ -1005,7 +1005,7 @@ "message": "Podpowiedź do hasła głównego (opcjonalnie)" }, "newMasterPassHint": { - "message": "New master password hint (optional)" + "message": "Nowa podpowiedź hasła głównego (opcjonalnie)" }, "masterPassHintLabel": { "message": "Podpowiedź do hasła głównego" @@ -1027,16 +1027,16 @@ "message": "Ustawienia" }, "accountEmail": { - "message": "Account email" + "message": "Adres e-mail konta" }, "requestHint": { - "message": "Request hint" + "message": "Poproś o podpowiedź" }, "requestPasswordHint": { - "message": "Request password hint" + "message": "Poproś o podpowiedź do hasła" }, "enterYourAccountEmailAddressAndYourPasswordHintWillBeSentToYou": { - "message": "Enter your account email address and your password hint will be sent to you" + "message": "Wprowadź adres e-mail swojego konta, a podpowiedź hasła zostanie wysłana do Ciebie" }, "passwordHint": { "message": "Podpowiedź do hasła" @@ -1076,10 +1076,10 @@ "message": "Konto zostało utworzone! Teraz możesz się zalogować." }, "newAccountCreated2": { - "message": "Your new account has been created!" + "message": "Twoje nowe konto zostało utworzone!" }, "youHaveBeenLoggedIn": { - "message": "You have been logged in!" + "message": "Zalogowano Cię!" }, "trialAccountCreated": { "message": "Konto zostało utworzone." @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Uwzględnij cyfry" }, + "generatorPolicyInEffect": { + "message": "Wymagania polityki przedsiębiorstwa zostały użyte do ustawienia opcji generatora.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Historia hasła" }, @@ -3979,10 +3983,10 @@ } }, "encryptionKeyUpdateCannotProceed": { - "message": "Encryption key update cannot proceed" + "message": "Aktualizacja klucza szyfrowania nie może być kontynuowana" }, "keyUpdateFoldersFailed": { - "message": "When updating your encryption key, your folders could not be decrypted. To continue with the update, your folders must be deleted. No vault items will be deleted if you proceed." + "message": "Podczas aktualizacji klucza szyfrowania, folderów nie można odszyfrować. Aby kontynuować aktualizację, foldery muszą zostać usunięte. Żadne elementy sejfu nie zostaną usunięte." }, "keyUpdated": { "message": "Klucz został zaktualizowany" @@ -4060,7 +4064,7 @@ "message": "Blokowanie sejfu" }, "vaultTimeout1": { - "message": "Timeout" + "message": "Limit czasu" }, "vaultTimeoutDesc": { "message": "Wybierz kiedy sejf zostanie zablokowany i wykonaj następującą akcję." @@ -4129,7 +4133,7 @@ "message": "Zaznaczono" }, "recommended": { - "message": "Recommended" + "message": "Zalecany" }, "ownership": { "message": "Właściciel" @@ -4601,7 +4605,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "copyLink": { - "message": "Kopiuj link" + "message": "Skopiuj link" }, "copySendLink": { "message": "Kopiuj link wysyłki", @@ -5013,13 +5017,13 @@ "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, "developmentDevOpsAndITTeamsChooseBWSecret": { - "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + "message": "Developerzy, DevOps i zespoły IT wybierają Menedżera Sekretnych Bitwarden do bezpiecznego zarządzania i wdrażania swojej infrastruktury i tajemnic." }, "centralizeSecretsManagement": { "message": "Centralizuj zarządzanie sekretami." }, "centralizeSecretsManagementDescription": { - "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + "message": "Bezpiecznie przechowuj i zarządzaj sekretami w jednej lokalizacji, aby zapobiec niekontrolowanemu rozprzestrzenianiu się sekretów w całej organizacji." }, "preventSecretLeaks": { "message": "Zapobiegaj wyciekom sekretów." @@ -5064,7 +5068,7 @@ "message": "E-mail z prośbą o dostęp do menedżera sekretów wiadomości został wysłany do administratorów." }, "requestAccessSMDefaultEmailContent": { - "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + "message": "Cześć,\n\nproszę o subskrypcję Mendeżera sekretów Bitwarden dla naszego zespołu. Twoje wsparcie będzie dla nas bardzo ważne!\n\nMendeżer sekretów Bitwarden to kompleksowe, szyfrowane rozwiązanie do zarządzania sekretami w celu bezpiecznego przechowywania, udostępniania i wdrażania danych uwierzytelniających maszyny, takich jak klucze API, hasła do baz danych i certyfikaty uwierzytelniające.\n\nMendeżer sekretów pomoże nam:\n\n- Zwiększyć bezpieczeństwo\n- Usprawnić operacje\n- Zapobiegać kosztownym wyciekom tajnych danych\n\nAby poprosić o bezpłatną wersję próbną dla naszego zespołu, skontaktuj się z Bitwarden.\n\nDziękuje za pomoc!" }, "giveMembersAccess": { "message": "Daj użytkownikom dostęp do:" @@ -5107,7 +5111,7 @@ } }, "viewSend": { - "message": "View Send", + "message": "Zobacz Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "viewSendHiddenEmailWarning": { @@ -5489,19 +5493,19 @@ "message": "Twoje hasło główne nie spełnia jednej lub kilku zasad organizacji. Aby uzyskać dostęp do sejfu, musisz teraz zaktualizować swoje hasło główne. Kontynuacja wyloguje Cię z bieżącej sesji, wymagając zalogowania się ponownie. Aktywne sesje na innych urządzeniach mogą pozostać aktywne przez maksymalnie jedną godzinę." }, "automaticAppLogin": { - "message": "Automatically log in users for allowed applications" + "message": "Automatycznie zaloguj użytkowników dla dozwolonych aplikacji" }, "automaticAppLoginDesc": { - "message": "Login forms will automatically be filled and submitted for apps launched from your configured identity provider." + "message": "Formularze logowania zostaną automatycznie wypełnione i przesłane dla aplikacji uruchomionych od skonfigurowanego dostawcy tożsamości." }, "automaticAppLoginIdpHostLabel": { - "message": "Identity provider host" + "message": "Host dostawcy tożsamości" }, "automaticAppLoginIdpHostDesc": { - "message": "Enter your identity provider host URL. Enter multiple URLs by separating with a comma." + "message": "Wprowadź adres URL hosta dostawcy tożsamości. Wprowadź wiele adresów URL oddzielając przecinkami." }, "tdeDisabledMasterPasswordRequired": { - "message": "Your organization has updated your decryption options. Please set a master password to access your vault." + "message": "Twoja organizacja zaktualizowała opcje szyfrowania. Ustaw hasło główne, aby uzyskać dostęp do sejfu." }, "maximumVaultTimeout": { "message": "Blokowanie sejfu" @@ -5535,7 +5539,7 @@ } }, "vaultTimeoutPolicyInEffect1": { - "message": "$HOURS$ hour(s) and $MINUTES$ minute(s) maximum.", + "message": "$HOURS$ godzin(y) i $MINUTES$ minut(y) maksymalnie.", "placeholders": { "hours": { "content": "$1", @@ -6238,23 +6242,23 @@ "message": "Losowe słowo" }, "usernameGenerator": { - "message": "Username generator" + "message": "Generator nazw użytkownika" }, "useThisPassword": { - "message": "Use this password" + "message": "Użyj tego hasła" }, "useThisUsername": { - "message": "Use this username" + "message": "Użyj tej nazwy użytkownika" }, "securePasswordGenerated": { - "message": "Secure password generated! Don't forget to also update your password on the website." + "message": "Wygenerowane bezpieczne hasło! Nie zapomnij również zaktualizować hasła na stronie." }, "useGeneratorHelpTextPartOne": { - "message": "Use the generator", + "message": "Użyj generatora", "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": ", aby utworzyć mocne unikalne hasło", "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": { @@ -6696,11 +6700,11 @@ "description": "Action to create a new secret." }, "copySecretName": { - "message": "Kopiuj nazwę sekretu", + "message": "Skopiuj nazwę sekretu", "description": "Action to copy the name of a secret to the system's clipboard." }, "copySecretValue": { - "message": "Kopiuj wartość sekretu", + "message": "Skopiuj wartość sekretu", "description": "Action to copy the value of a secret to the system's clipboard." }, "deleteSecret": { @@ -7166,7 +7170,7 @@ "message": "Zweryfikuj ponownie domenę" }, "copyDnsTxtRecord": { - "message": "Kopiuj rekord DNS TXT" + "message": "Skopiuj rekord DNS TXT" }, "dnsTxtRecord": { "message": "Rekord DNS TXT" @@ -7427,7 +7431,7 @@ "message": "Przesyłanie plików" }, "upload": { - "message": "Upload" + "message": "Wyślij" }, "acceptedFormats": { "message": "Dozwolone formaty:" @@ -8291,7 +8295,7 @@ "message": "Dodaj pole" }, "editField": { - "message": "Edit field" + "message": "Edytuj pole" }, "items": { "message": "Elementy" @@ -8684,19 +8688,19 @@ "message": "Zarządzaj płatnościami z portalu dostawcy" }, "continueSettingUpFreeTrial": { - "message": "Continue setting up your free trial of Bitwarden" + "message": "Kontynuuj konfigurację darmowego okresu próbnego Bitwarden" }, "continueSettingUpFreeTrialPasswordManager": { - "message": "Continue setting up your free trial of Bitwarden Password Manager" + "message": "Kontynuuj konfigurację darmowego okresu próbnego w Menedżerze haseł Bitwarden" }, "continueSettingUpFreeTrialSecretsManager": { - "message": "Continue setting up your free trial of Bitwarden Secrets Manager" + "message": "Kontynuuj konfigurację darmowego okresu próbnego Menedżera Sekretnych Bitwarden" }, "enterTeamsOrgInfo": { "message": "Enter your Teams organization information" }, "enterFamiliesOrgInfo": { - "message": "Enter your Families organization information" + "message": "Wprowadź informacje o swojej organizacji rodzinnej" }, "enterEnterpriseOrgInfo": { "message": "Enter your Enterprise organization information" @@ -8836,25 +8840,25 @@ "message": "Dostęp członków organizacji audytowej do wszystkich grup, kolekcji i elementów kolekcji. Eksport CSV zapewnia szczegółowy podział na członków, w tym informacje o uprawnieniach do zbierania i konfiguracjach kont." }, "memberAccessReportNoCollection": { - "message": "(No Collection)" + "message": "(Bez Kolekcji)" }, "memberAccessReportNoCollectionPermission": { - "message": "(No Collection Permission)" + "message": "(Brak uprawnień do kolekcji)" }, "memberAccessReportNoGroup": { - "message": "(No Group)" + "message": "(Brak grupy)" }, "memberAccessReportTwoFactorEnabledTrue": { - "message": "On" + "message": "Wł." }, "memberAccessReportTwoFactorEnabledFalse": { - "message": "Off" + "message": "Wył." }, "memberAccessReportAuthenticationEnabledTrue": { - "message": "On" + "message": "Wł." }, "memberAccessReportAuthenticationEnabledFalse": { - "message": "Off" + "message": "Wył." }, "higherKDFIterations": { "message": "Wyższe wartości iteracji KDF mogą pomóc chronić Twoje hasło główne przed złamaniem przez atakującego." @@ -8887,7 +8891,7 @@ "message": "Dodaj osoby lub grupy, aby udostępnić dostęp do tego sekretu" }, "secretMachineAccountsDescription": { - "message": "Przyznaj dostęp kontom maszynowym do tego sekretu." + "message": "Przyznaj dostęp kontom dla maszyn do tego sekretu." }, "secretMachineAccountsEmptyMessage": { "message": "Dodaj konta maszyn, aby udzielić dostępu do tego sekretu" @@ -9003,64 +9007,64 @@ "message": "zakupione miejsca usunięte" }, "environmentVariables": { - "message": "Environment variables" + "message": "Zmienne Środowiskowe" }, "organizationId": { - "message": "Organization ID" + "message": "Identyfikator organizacji" }, "projectIds": { - "message": "Project IDs" + "message": "ID projektów" }, "projectId": { - "message": "Project ID" + "message": "ID projektu" }, "projectsAccessedByMachineAccount": { - "message": "The following projects can be accessed by this machine account." + "message": "Poniższe projekty mogą być dostępne na tym koncie dla maszyn." }, "config": { - "message": "Config" + "message": "Konfiguracja" }, "learnMoreAboutEmergencyAccess": { - "message": "Learn more about emergency access" + "message": "Dowiedz się więcej o dostępie awaryjnym" }, "learnMoreAboutMatchDetection": { - "message": "Learn more about match detection" + "message": "Dowiedz się więcej o wykrywaniu dopasowania" }, "learnMoreAboutMasterPasswordReprompt": { - "message": "Learn more about master password re-prompt" + "message": "Dowiedz się więcej o ponownym pytaniu o hasło główne" }, "learnMoreAboutSearchingYourVault": { - "message": "Learn more about searching your vault" + "message": "Dowiedz się więcej o przeszukiwaniu swojego sejfu" }, "learnMoreAboutYourAccountFingerprintPhrase": { - "message": "Learn about your account fingerprint phrase" + "message": "Dowiedz się więcej o unikalnym identyfikatorze konta" }, "impactOfRotatingYourEncryptionKey": { - "message": "Impact of rotating your encryption key" + "message": "Wpływ rotacji klucza szyfrowania" }, "learnMoreAboutEncryptionAlgorithms": { - "message": "Learn more about encryption algorithms" + "message": "Dowiedz się więcej o algorytmach szyfrowania" }, "learnMoreAboutKDFIterations": { - "message": "Learn more about KDF iterations" + "message": "Dowiedz się więcej o iteracjach KDF" }, "learnMoreAboutLocalization": { - "message": "Learn more about localization" + "message": "Dowiedz się więcej o lokalizacji" }, "learnMoreAboutWebsiteIcons": { - "message": "Learn more about using website icons" + "message": "Dowiedz się więcej o korzystaniu z ikon witryny" }, "learnMoreAboutUserAccess": { - "message": "Learn more about user access" + "message": "Dowiedz się więcej o dostępie użytkownika" }, "learnMoreAboutMemberRoles": { - "message": "Learn more about member roles and permissions" + "message": "Dowiedz się więcej o rolach i uprawnieniach użytkowników" }, "whatIsACvvNumber": { - "message": "What is a CVV number?" + "message": "Czym jest numer CVV?" }, "learnMoreAboutApi": { - "message": "Learn more about Bitwarden's API" + "message": "Dowiedz się więcej o API Bitwarden" }, "fileSends": { "message": "File Sends" @@ -9087,7 +9091,7 @@ } }, "optionalOnPremHosting": { - "message": "Optional on-premises hosting" + "message": "Opcjonalny hosting lokalny" }, "upgradeFreeOrganization": { "message": "Ulepsz swoją organizację $NAME$ ", @@ -9120,7 +9124,7 @@ } }, "upgradePlans": { - "message": "Upgrade your plan to invite members and experience powerful security features." + "message": "Ulepsz swój plan, aby zaprosić członków i korzystać z zaawansowanych funkcji bezpieczeństwa." }, "upgradeDiscount": { "message": "Zaoszczędź $AMOUNT$%", @@ -9132,10 +9136,10 @@ } }, "enterprisePlanUpgradeMessage": { - "message": "Advanced capabilities for larger organizations" + "message": "Zaawansowane możliwości dla większych organizacji" }, "teamsPlanUpgradeMessage": { - "message": "Resilient protection for growing teams" + "message": "Silna ochrona dla rosnących zespołów" }, "teamsInviteMessage": { "message": "Zaproś nieograniczoną liczbę członków" @@ -9147,7 +9151,7 @@ "message": "Synchronizuj grupy i użytkowników z użyciem katalogu" }, "familyPlanUpgradeMessage": { - "message": "Secure your family logins" + "message": "Zabezpiecz dane logowania rodziny" }, "accessToPremiumFeatures": { "message": "Dostęp do funkcji Premium" @@ -9156,70 +9160,70 @@ "message": "GB dodatkowej przestrzeni" }, "premiumAccounts": { - "message": "6 premium accounts" + "message": "6 kont premium" }, "unlimitedSharing": { - "message": "Unlimited sharing" + "message": "Nieograniczone udostępnianie" }, "unlimitedCollections": { - "message": "Unlimited collections" + "message": "Nieograniczona liczba kolekcji" }, "secureDataSharing": { - "message": "Secure data sharing" + "message": "Bezpieczne udostępnianie danych" }, "eventLogMonitoring": { - "message": "Event log monitoring" + "message": "Monitorowanie zdarzeń" }, "directoryIntegration": { "message": "Directory integration" }, "passwordLessSso": { - "message": "Passwordless SSO" + "message": "SSO bez hasła" }, "accountRecovery": { - "message": "Account recovery" + "message": "Odzyskiwanie konta" }, "customRoles": { - "message": "Custom roles" + "message": "Niestandardowe role" }, "unlimitedSecretsStorage": { - "message": "Unlimited secrets storage" + "message": "Nielimitowane przechowywanie sekretów" }, "unlimitedUsers": { - "message": "Unlimited users" + "message": "Nieograniczona liczba użytkowników" }, "UpTo50MachineAccounts": { - "message": "Up to 50 machine accounts" + "message": "Do 50 kont dla maszyn" }, "UpTo20MachineAccounts": { - "message": "Up to 20 machine accounts" + "message": "Do 20 kont dla maszyn" }, "current": { - "message": "Current" + "message": "Bieżący" }, "secretsManagerSubscriptionInfo": { - "message": "Your Secrets Manager subscription will upgrade based on the plan selected" + "message": "Subskrypcja Menedżera sekretów zostanie zaktualizowana zgodnie z wybranym planem" }, "bitwardenPasswordManager": { - "message": "Bitwarden Password Manager" + "message": "Menedżer Haseł Bitwarden" }, "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." + "message": "Bezpłatna roczna subskrypcja programu Mendeżera haseł zostanie uaktualniona do wybranego planu. Opłata zostanie naliczona dopiero po zakończeniu okresu bezpłatnego." }, "fileSavedToDevice": { - "message": "File saved to device. Manage from your device downloads." + "message": "Plik zapisany na urządzeniu. Zarządzaj plikiem na swoim urządzeniu." }, "publicApi": { - "message": "Public API", + "message": "Publiczne API", "description": "The text, 'API', is an acronym and should not be translated." }, "showCharacterCount": { - "message": "Show character count" + "message": "Pokaż liczbę znaków" }, "hideCharacterCount": { - "message": "Hide character count" + "message": "Ukryj liczbę znaków" }, "editAccess": { - "message": "Edit access" + "message": "Edytuj dostęp" } } diff --git a/apps/web/src/locales/pt_BR/messages.json b/apps/web/src/locales/pt_BR/messages.json index 35e0c664f63..557510b78d3 100644 --- a/apps/web/src/locales/pt_BR/messages.json +++ b/apps/web/src/locales/pt_BR/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Incluir Número" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Histórico de Senha" }, diff --git a/apps/web/src/locales/pt_PT/messages.json b/apps/web/src/locales/pt_PT/messages.json index 0455402a94e..9770a574034 100644 --- a/apps/web/src/locales/pt_PT/messages.json +++ b/apps/web/src/locales/pt_PT/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Incluir número" }, + "generatorPolicyInEffect": { + "message": "Os requisitos da política empresarial foram aplicados às suas opções de gerador.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Histórico de palavras-passe" }, diff --git a/apps/web/src/locales/ro/messages.json b/apps/web/src/locales/ro/messages.json index b60c3a5bb64..7c2fcbeef95 100644 --- a/apps/web/src/locales/ro/messages.json +++ b/apps/web/src/locales/ro/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Se includ cifre" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Istoric parole" }, diff --git a/apps/web/src/locales/ru/messages.json b/apps/web/src/locales/ru/messages.json index a771d49ab2c..1ad7a81088d 100644 --- a/apps/web/src/locales/ru/messages.json +++ b/apps/web/src/locales/ru/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Добавить цифру" }, + "generatorPolicyInEffect": { + "message": "К настройкам генератора были применены требования корпоративной политики.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "История паролей" }, diff --git a/apps/web/src/locales/si/messages.json b/apps/web/src/locales/si/messages.json index f0f2fdb14da..9b4a66346f1 100644 --- a/apps/web/src/locales/si/messages.json +++ b/apps/web/src/locales/si/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Include number" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Password history" }, diff --git a/apps/web/src/locales/sk/messages.json b/apps/web/src/locales/sk/messages.json index b5cdd9781bf..8fdb9c65cb8 100644 --- a/apps/web/src/locales/sk/messages.json +++ b/apps/web/src/locales/sk/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Zahrnúť číslo" }, + "generatorPolicyInEffect": { + "message": "Na nastavenie generátora boli uplatnené požiadavky pravidiel spoločnosti.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "História hesla" }, diff --git a/apps/web/src/locales/sl/messages.json b/apps/web/src/locales/sl/messages.json index b5b2a744532..b292e7a357d 100644 --- a/apps/web/src/locales/sl/messages.json +++ b/apps/web/src/locales/sl/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Vključi številko" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Zgodovina gesel" }, diff --git a/apps/web/src/locales/sr/messages.json b/apps/web/src/locales/sr/messages.json index 588cce614be..7f464f49e44 100644 --- a/apps/web/src/locales/sr/messages.json +++ b/apps/web/src/locales/sr/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Убаци број" }, + "generatorPolicyInEffect": { + "message": "Захтеви политике предузећа су примењени на опције генератора.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Историја Лозинке" }, @@ -9003,22 +9007,22 @@ "message": "купљена места уклоњена" }, "environmentVariables": { - "message": "Environment variables" + "message": "Променљиве окружења" }, "organizationId": { - "message": "Organization ID" + "message": "ИД Организације" }, "projectIds": { - "message": "Project IDs" + "message": "ИД Пројекте" }, "projectId": { - "message": "Project ID" + "message": "ИД Пројекта" }, "projectsAccessedByMachineAccount": { - "message": "The following projects can be accessed by this machine account." + "message": "Следећим пројектима се може приступити преко овог машинског налога." }, "config": { - "message": "Config" + "message": "Подешавање" }, "learnMoreAboutEmergencyAccess": { "message": "Сазнајте више о приступу у хитним случајевима" diff --git a/apps/web/src/locales/sr_CS/messages.json b/apps/web/src/locales/sr_CS/messages.json index c9eb9391c1a..0fa58e64ac9 100644 --- a/apps/web/src/locales/sr_CS/messages.json +++ b/apps/web/src/locales/sr_CS/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Include number" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Istorija lozinki" }, diff --git a/apps/web/src/locales/sv/messages.json b/apps/web/src/locales/sv/messages.json index 43817b3f763..9a7a5870f6b 100644 --- a/apps/web/src/locales/sv/messages.json +++ b/apps/web/src/locales/sv/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Inkludera siffra" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Lösenordshistorik" }, diff --git a/apps/web/src/locales/te/messages.json b/apps/web/src/locales/te/messages.json index de896a154c4..b00f71df724 100644 --- a/apps/web/src/locales/te/messages.json +++ b/apps/web/src/locales/te/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Include number" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Password history" }, diff --git a/apps/web/src/locales/th/messages.json b/apps/web/src/locales/th/messages.json index e9160221b09..b1b61a9adcd 100644 --- a/apps/web/src/locales/th/messages.json +++ b/apps/web/src/locales/th/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Include number" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Password history" }, diff --git a/apps/web/src/locales/tr/messages.json b/apps/web/src/locales/tr/messages.json index 03a18764bf0..b3783fb2496 100644 --- a/apps/web/src/locales/tr/messages.json +++ b/apps/web/src/locales/tr/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Rakam ekle" }, + "generatorPolicyInEffect": { + "message": "Üreteç seçeneklerinize kurumsal ilke gereksinimleri uygulandı.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Parola geçmişi" }, diff --git a/apps/web/src/locales/uk/messages.json b/apps/web/src/locales/uk/messages.json index 745ca2379c9..3041c4220c0 100644 --- a/apps/web/src/locales/uk/messages.json +++ b/apps/web/src/locales/uk/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Включити число" }, + "generatorPolicyInEffect": { + "message": "До налаштувань генератора застосовано вимоги політики компанії.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Історія паролів" }, diff --git a/apps/web/src/locales/vi/messages.json b/apps/web/src/locales/vi/messages.json index 529c08a56fb..56e9f879f67 100644 --- a/apps/web/src/locales/vi/messages.json +++ b/apps/web/src/locales/vi/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "Bao gồm cả số" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "Lịch sử mật khẩu" }, diff --git a/apps/web/src/locales/zh_CN/messages.json b/apps/web/src/locales/zh_CN/messages.json index 28bb2f86185..0e842c24ba5 100644 --- a/apps/web/src/locales/zh_CN/messages.json +++ b/apps/web/src/locales/zh_CN/messages.json @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "包含数字" }, + "generatorPolicyInEffect": { + "message": "企业策略要求应用到您的生成器选项中。", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "密码历史记录" }, @@ -8684,13 +8688,13 @@ "message": "从提供商门户管理账单" }, "continueSettingUpFreeTrial": { - "message": "Continue setting up your free trial of Bitwarden" + "message": "继续设置您的免费试用版 Bitwarden" }, "continueSettingUpFreeTrialPasswordManager": { - "message": "Continue setting up your free trial of Bitwarden Password Manager" + "message": "继续设置您的免费试用版 Bitwarden 密码管理器" }, "continueSettingUpFreeTrialSecretsManager": { - "message": "Continue setting up your free trial of Bitwarden Secrets Manager" + "message": "继续设置您的免费试用版 Bitwarden 机密管理器" }, "enterTeamsOrgInfo": { "message": "输入您的团队组织信息" diff --git a/apps/web/src/locales/zh_TW/messages.json b/apps/web/src/locales/zh_TW/messages.json index 12ff2018a2e..bba5457f558 100644 --- a/apps/web/src/locales/zh_TW/messages.json +++ b/apps/web/src/locales/zh_TW/messages.json @@ -46,7 +46,7 @@ "message": "持卡人姓名" }, "loginCredentials": { - "message": "Login credentials" + "message": "登入憑證" }, "personalDetails": { "message": "Personal details" @@ -641,7 +641,7 @@ "message": "Copy phone" }, "copyEmail": { - "message": "Copy email" + "message": "複製電子郵件地址" }, "copyCompany": { "message": "Copy company" @@ -1475,6 +1475,10 @@ "includeNumber": { "message": "包含數字" }, + "generatorPolicyInEffect": { + "message": "Enterprise policy requirements have been applied to your generator options.", + "description": "Indicates that a policy limits the credential generator screen." + }, "passwordHistory": { "message": "密碼歷史記錄" }, diff --git a/libs/angular/src/admin-console/components/collections.component.ts b/libs/angular/src/admin-console/components/collections.component.ts index d6801aa155e..93410afaaea 100644 --- a/libs/angular/src/admin-console/components/collections.component.ts +++ b/libs/angular/src/admin-console/components/collections.component.ts @@ -72,7 +72,7 @@ export class CollectionsComponent implements OnInit { if (this.organization.canEditAllCiphers) { return !!(c as any).checked; } else { - return !!(c as any).checked && c.readOnly == null; + return !!(c as any).checked && !c.readOnly; } }) .map((c) => c.id); diff --git a/libs/auth/src/angular/input-password/input-password.component.ts b/libs/auth/src/angular/input-password/input-password.component.ts index 0aecb6e3783..dbacf28054b 100644 --- a/libs/auth/src/angular/input-password/input-password.component.ts +++ b/libs/auth/src/angular/input-password/input-password.component.ts @@ -129,38 +129,13 @@ export class InputPasswordComponent { const password = this.formGroup.controls.password.value; - // Check if password is breached (if breached, user chooses to accept and continue or not) - const passwordIsBreached = - this.formGroup.controls.checkForBreaches.value && - (await this.auditService.passwordLeaked(password)); - - if (passwordIsBreached) { - const userAcceptedDialog = await this.dialogService.openSimpleDialog({ - title: { key: "exposedMasterPassword" }, - content: { key: "exposedMasterPasswordDesc" }, - type: "warning", - }); - - if (!userAcceptedDialog) { - return; - } - } - - // Check if password meets org policy requirements - if ( - this.masterPasswordPolicyOptions != null && - !this.policyService.evaluateMasterPassword( - this.passwordStrengthScore, - password, - this.masterPasswordPolicyOptions, - ) - ) { - this.toastService.showToast({ - variant: "error", - title: this.i18nService.t("errorOccurred"), - message: this.i18nService.t("masterPasswordPolicyRequirementsNotMet"), - }); + const passwordEvaluatedSuccessfully = await this.evaluatePassword( + password, + this.passwordStrengthScore, + this.formGroup.controls.checkForBreaches.value, + ); + if (!passwordEvaluatedSuccessfully) { return; } @@ -194,4 +169,69 @@ export class InputPasswordComponent { password, }); }; + + // Returns true if the password passes all checks, false otherwise + private async evaluatePassword( + password: string, + passwordStrengthScore: PasswordStrengthScore, + checkForBreaches: boolean, + ) { + // Check if the password is breached, weak, or both + const passwordIsBreached = + checkForBreaches && (await this.auditService.passwordLeaked(password)); + + const passwordWeak = passwordStrengthScore != null && passwordStrengthScore < 3; + + if (passwordIsBreached && passwordWeak) { + const userAcceptedDialog = await this.dialogService.openSimpleDialog({ + title: { key: "weakAndExposedMasterPassword" }, + content: { key: "weakAndBreachedMasterPasswordDesc" }, + type: "warning", + }); + + if (!userAcceptedDialog) { + return false; + } + } else if (passwordWeak) { + const userAcceptedDialog = await this.dialogService.openSimpleDialog({ + title: { key: "weakMasterPasswordDesc" }, + content: { key: "weakMasterPasswordDesc" }, + type: "warning", + }); + + if (!userAcceptedDialog) { + return false; + } + } else if (passwordIsBreached) { + const userAcceptedDialog = await this.dialogService.openSimpleDialog({ + title: { key: "exposedMasterPassword" }, + content: { key: "exposedMasterPasswordDesc" }, + type: "warning", + }); + + if (!userAcceptedDialog) { + return false; + } + } + + // Check if password meets org policy requirements + if ( + this.masterPasswordPolicyOptions != null && + !this.policyService.evaluateMasterPassword( + this.passwordStrengthScore, + password, + this.masterPasswordPolicyOptions, + ) + ) { + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: this.i18nService.t("masterPasswordPolicyRequirementsNotMet"), + }); + + return false; + } + + return true; + } } diff --git a/libs/common/src/enums/feature-flag.enum.ts b/libs/common/src/enums/feature-flag.enum.ts index 7ac473ff6ab..505fe33e82a 100644 --- a/libs/common/src/enums/feature-flag.enum.ts +++ b/libs/common/src/enums/feature-flag.enum.ts @@ -33,6 +33,7 @@ export enum FeatureFlag { NotificationBarAddLoginImprovements = "notification-bar-add-login-improvements", AC2476_DeprecateStripeSourcesAPI = "AC-2476-deprecate-stripe-sources-api", CipherKeyEncryption = "cipher-key-encryption", + PM11901_RefactorSelfHostingLicenseUploader = "PM-11901-refactor-self-hosting-license-uploader", } export type AllowedFeatureFlagTypes = boolean | number | string; @@ -76,6 +77,7 @@ export const DefaultFeatureFlagValue = { [FeatureFlag.NotificationBarAddLoginImprovements]: FALSE, [FeatureFlag.AC2476_DeprecateStripeSourcesAPI]: FALSE, [FeatureFlag.CipherKeyEncryption]: FALSE, + [FeatureFlag.PM11901_RefactorSelfHostingLicenseUploader]: FALSE, } satisfies Record; export type DefaultFeatureFlagValueType = typeof DefaultFeatureFlagValue; diff --git a/libs/common/src/models/response/profile.response.ts b/libs/common/src/models/response/profile.response.ts index 6b6555fc566..24aeb11cdbb 100644 --- a/libs/common/src/models/response/profile.response.ts +++ b/libs/common/src/models/response/profile.response.ts @@ -21,6 +21,7 @@ export class ProfileResponse extends BaseResponse { securityStamp: string; forcePasswordReset: boolean; usesKeyConnector: boolean; + managedByOrganizationId?: string | null; organizations: ProfileOrganizationResponse[] = []; providers: ProfileProviderResponse[] = []; providerOrganizations: ProfileProviderOrganizationResponse[] = []; @@ -42,6 +43,7 @@ export class ProfileResponse extends BaseResponse { this.securityStamp = this.getResponseProperty("SecurityStamp"); this.forcePasswordReset = this.getResponseProperty("ForcePasswordReset") ?? false; this.usesKeyConnector = this.getResponseProperty("UsesKeyConnector") ?? false; + this.managedByOrganizationId = this.getResponseProperty("ManagedByOrganizationId"); const organizations = this.getResponseProperty("Organizations"); if (organizations != null) { diff --git a/libs/common/src/platform/models/domain/domain-base.spec.ts b/libs/common/src/platform/models/domain/domain-base.spec.ts new file mode 100644 index 00000000000..0bdee21e3c1 --- /dev/null +++ b/libs/common/src/platform/models/domain/domain-base.spec.ts @@ -0,0 +1,139 @@ +import { mock, MockProxy } from "jest-mock-extended"; + +import { makeEncString, makeSymmetricCryptoKey } from "../../../../spec"; +import { EncryptService } from "../../abstractions/encrypt.service"; +import { Utils } from "../../misc/utils"; + +import Domain from "./domain-base"; +import { EncString } from "./enc-string"; + +class TestDomain extends Domain { + plainText: string; + encToString: EncString; + encString2: EncString; +} + +describe("DomainBase", () => { + let encryptService: MockProxy; + const key = makeSymmetricCryptoKey(64); + + beforeEach(() => { + encryptService = mock(); + }); + + function setUpCryptography() { + encryptService.encrypt.mockImplementation((value) => { + let data: string; + if (typeof value === "string") { + data = value; + } else { + data = Utils.fromBufferToUtf8(value); + } + + return Promise.resolve(makeEncString(data)); + }); + + encryptService.decryptToUtf8.mockImplementation((value) => { + return Promise.resolve(value.data); + }); + + encryptService.decryptToBytes.mockImplementation((value) => { + return Promise.resolve(value.dataBytes); + }); + } + + describe("decryptWithKey", () => { + it("domain property types are decryptable", async () => { + const domain = new TestDomain(); + + await domain["decryptObjWithKey"]( + // @ts-expect-error -- clear is not of type EncString + ["plainText"], + makeSymmetricCryptoKey(64), + mock(), + ); + + await domain["decryptObjWithKey"]( + // @ts-expect-error -- Clear is not of type EncString + ["encToString", "encString2", "plainText"], + makeSymmetricCryptoKey(64), + mock(), + ); + + const decrypted = await domain["decryptObjWithKey"]( + ["encToString"], + makeSymmetricCryptoKey(64), + mock(), + ); + + // @ts-expect-error -- encString2 was not decrypted + decrypted as { encToString: string; encString2: string; plainText: string }; + + // encString2 was not decrypted, so it's still an EncString + decrypted as { encToString: string; encString2: EncString; plainText: string }; + }); + + it("decrypts the encrypted properties", async () => { + setUpCryptography(); + + const domain = new TestDomain(); + + domain.encToString = await encryptService.encrypt("string", key); + + const decrypted = await domain["decryptObjWithKey"](["encToString"], key, encryptService); + + expect(decrypted).toEqual({ + encToString: "string", + }); + }); + + it("decrypts multiple encrypted properties", async () => { + setUpCryptography(); + + const domain = new TestDomain(); + + domain.encToString = await encryptService.encrypt("string", key); + domain.encString2 = await encryptService.encrypt("string2", key); + + const decrypted = await domain["decryptObjWithKey"]( + ["encToString", "encString2"], + key, + encryptService, + ); + + expect(decrypted).toEqual({ + encToString: "string", + encString2: "string2", + }); + }); + + it("does not decrypt properties that are not encrypted", async () => { + const domain = new TestDomain(); + domain.plainText = "clear"; + + const decrypted = await domain["decryptObjWithKey"]([], key, encryptService); + + expect(decrypted).toEqual({ + plainText: "clear", + }); + }); + + it("does not decrypt properties that were not requested to be decrypted", async () => { + setUpCryptography(); + + const domain = new TestDomain(); + + domain.plainText = "clear"; + domain.encToString = makeEncString("string"); + domain.encString2 = makeEncString("string2"); + + const decrypted = await domain["decryptObjWithKey"]([], key, encryptService); + + expect(decrypted).toEqual({ + plainText: "clear", + encToString: makeEncString("string"), + encString2: makeEncString("string2"), + }); + }); + }); +}); diff --git a/libs/common/src/platform/models/domain/domain-base.ts b/libs/common/src/platform/models/domain/domain-base.ts index f7273d2435b..1cfcfac02ff 100644 --- a/libs/common/src/platform/models/domain/domain-base.ts +++ b/libs/common/src/platform/models/domain/domain-base.ts @@ -1,8 +1,18 @@ +import { ConditionalExcept, ConditionalKeys, Constructor } from "type-fest"; + import { View } from "../../../models/view/view"; +import { EncryptService } from "../../abstractions/encrypt.service"; import { EncString } from "./enc-string"; import { SymmetricCryptoKey } from "./symmetric-crypto-key"; +// eslint-disable-next-line @typescript-eslint/ban-types +type EncStringKeys = ConditionalKeys, EncString>; +export type DecryptedObject< + TEncryptedObject, + TDecryptedKeys extends EncStringKeys, +> = Record & Omit; + // https://contributing.bitwarden.com/architecture/clients/data-model#domain export default class Domain { protected buildDomainModel( @@ -80,4 +90,60 @@ export default class Domain { await Promise.all(promises); return viewModel; } + + /** + * Decrypts the requested properties of the domain object with the provided key and encrypt service. + * + * If a property is null, the result will be null. + * @see {@link EncString.decryptWithKey} for more details on decryption behavior. + * + * @param encryptedProperties The properties to decrypt. Type restricted to EncString properties of the domain object. + * @param key The key to use for decryption. + * @param encryptService The encryption service to use for decryption. + * @param _ The constructor of the domain object. Used for type inference if the domain object is not automatically inferred. + * @returns An object with the requested properties decrypted and the rest of the domain object untouched. + */ + protected async decryptObjWithKey< + TThis extends Domain, + const TEncryptedKeys extends EncStringKeys, + >( + this: TThis, + encryptedProperties: TEncryptedKeys[], + key: SymmetricCryptoKey, + encryptService: EncryptService, + _: Constructor = this.constructor as Constructor, + ): Promise> { + const promises = []; + + for (const prop of encryptedProperties) { + const value = (this as any)[prop] as EncString; + promises.push(this.decryptProperty(prop, value, key, encryptService)); + } + + const decryptedObjects = await Promise.all(promises); + const decryptedObject = decryptedObjects.reduce( + (acc, obj) => { + return { ...acc, ...obj }; + }, + { ...this }, + ); + return decryptedObject as DecryptedObject; + } + + private async decryptProperty>( + propertyKey: TEncryptedKeys, + value: EncString, + key: SymmetricCryptoKey, + encryptService: EncryptService, + ) { + let decrypted: string = null; + if (value) { + decrypted = await value.decryptWithKey(key, encryptService); + } else { + decrypted = null; + } + return { + [propertyKey]: decrypted, + }; + } } 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 7583c37e1e7..39d58831772 100644 --- a/libs/common/src/platform/models/domain/enc-string.spec.ts +++ b/libs/common/src/platform/models/domain/enc-string.spec.ts @@ -1,11 +1,12 @@ import { mock, MockProxy } from "jest-mock-extended"; -import { makeStaticByteArray } from "../../../../spec"; +import { makeEncString, makeStaticByteArray } from "../../../../spec"; import { EncryptService } from "../../../platform/abstractions/encrypt.service"; import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-crypto-key"; import { UserKey, OrgKey } from "../../../types/key"; import { CryptoService } from "../../abstractions/crypto.service"; import { EncryptionType } from "../../enums"; +import { Utils } from "../../misc/utils"; import { ContainerService } from "../../services/container.service"; import { EncString } from "./enc-string"; @@ -113,6 +114,77 @@ describe("EncString", () => { }); }); + describe("decryptWithKey", () => { + const encString = new EncString(EncryptionType.Rsa2048_OaepSha256_B64, "data"); + + const cryptoService = mock(); + const encryptService = mock(); + encryptService.decryptToUtf8 + .calledWith(encString, expect.anything()) + .mockResolvedValue("decrypted"); + + function setupEncryption() { + encryptService.encrypt.mockImplementation(async (data, key) => { + if (typeof data === "string") { + return makeEncString(data); + } else { + return makeEncString(Utils.fromBufferToUtf8(data)); + } + }); + encryptService.decryptToUtf8.mockImplementation(async (encString, key) => { + return encString.data; + }); + encryptService.decryptToBytes.mockImplementation(async (encString, key) => { + return encString.dataBytes; + }); + } + + beforeEach(() => { + (window as any).bitwardenContainerService = new ContainerService( + cryptoService, + encryptService, + ); + }); + + it("decrypts using the provided key and encryptService", async () => { + setupEncryption(); + + const key = new SymmetricCryptoKey(makeStaticByteArray(32)); + await encString.decryptWithKey(key, encryptService); + + expect(encryptService.decryptToUtf8).toHaveBeenCalledWith(encString, key); + }); + + it("fails to decrypt when key is null", async () => { + const decrypted = await encString.decryptWithKey(null, encryptService); + + expect(decrypted).toBe("[error: cannot decrypt]"); + expect(encString.decryptedValue).toBe("[error: cannot decrypt]"); + }); + + it("fails to decrypt when encryptService is null", async () => { + const decrypted = await encString.decryptWithKey( + new SymmetricCryptoKey(makeStaticByteArray(32)), + null, + ); + + expect(decrypted).toBe("[error: cannot decrypt]"); + expect(encString.decryptedValue).toBe("[error: cannot decrypt]"); + }); + + it("fails to decrypt when encryptService throws", async () => { + encryptService.decryptToUtf8.mockRejectedValue("error"); + + const decrypted = await encString.decryptWithKey( + new SymmetricCryptoKey(makeStaticByteArray(32)), + encryptService, + ); + + expect(decrypted).toBe("[error: cannot decrypt]"); + expect(encString.decryptedValue).toBe("[error: cannot decrypt]"); + }); + }); + describe("AesCbc256_B64", () => { it("constructor", () => { const encString = new EncString(EncryptionType.AesCbc256_B64, "data", "iv"); diff --git a/libs/common/src/platform/models/domain/enc-string.ts b/libs/common/src/platform/models/domain/enc-string.ts index 1f4c8caf39c..0b0a597acd3 100644 --- a/libs/common/src/platform/models/domain/enc-string.ts +++ b/libs/common/src/platform/models/domain/enc-string.ts @@ -1,11 +1,14 @@ import { Jsonify, Opaque } from "type-fest"; +import { EncryptService } from "../../abstractions/encrypt.service"; import { EncryptionType, EXPECTED_NUM_PARTS_BY_ENCRYPTION_TYPE } from "../../enums"; import { Encrypted } from "../../interfaces/encrypted"; import { Utils } from "../../misc/utils"; import { SymmetricCryptoKey } from "./symmetric-crypto-key"; +export const DECRYPT_ERROR = "[error: cannot decrypt]"; + export class EncString implements Encrypted { encryptedString?: EncryptedString; encryptionType?: EncryptionType; @@ -167,11 +170,24 @@ export class EncString implements Encrypted { const encryptService = Utils.getContainerService().getEncryptService(); this.decryptedValue = await encryptService.decryptToUtf8(this, key); } catch (e) { - this.decryptedValue = "[error: cannot decrypt]"; + this.decryptedValue = DECRYPT_ERROR; } return this.decryptedValue; } + async decryptWithKey(key: SymmetricCryptoKey, encryptService: EncryptService) { + try { + if (key == null) { + throw new Error("No key to decrypt EncString"); + } + + this.decryptedValue = await encryptService.decryptToUtf8(this, key); + } catch (e) { + this.decryptedValue = DECRYPT_ERROR; + } + + return this.decryptedValue; + } private async getKeyForDecryption(orgId: string) { const cryptoService = Utils.getContainerService().getCryptoService(); return orgId != null diff --git a/libs/common/src/vault/models/domain/folder.spec.ts b/libs/common/src/vault/models/domain/folder.spec.ts index 69134d19cfb..785852b884e 100644 --- a/libs/common/src/vault/models/domain/folder.spec.ts +++ b/libs/common/src/vault/models/domain/folder.spec.ts @@ -1,4 +1,7 @@ -import { mockEnc, mockFromJson } from "../../../../spec"; +import { mock, MockProxy } from "jest-mock-extended"; + +import { makeEncString, makeSymmetricCryptoKey, mockEnc, mockFromJson } from "../../../../spec"; +import { EncryptService } from "../../../platform/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"; @@ -60,4 +63,42 @@ describe("Folder", () => { expect(actual).toMatchObject(expected); }); }); + + describe("decryptWithKey", () => { + let encryptService: MockProxy; + const key = makeSymmetricCryptoKey(64); + + beforeEach(() => { + encryptService = mock(); + encryptService.decryptToUtf8.mockImplementation((value) => { + return Promise.resolve(value.data); + }); + }); + + it("decrypts the name", async () => { + const folder = new Folder(); + folder.name = makeEncString("encName"); + + const view = await folder.decryptWithKey(key, encryptService); + + expect(view).toEqual({ + name: "encName", + }); + }); + + it("assigns the folder id and revision date", async () => { + const folder = new Folder(); + folder.id = "id"; + folder.revisionDate = new Date("2022-01-31T12:00:00.000Z"); + + const view = await folder.decryptWithKey(key, encryptService); + + expect(view).toEqual( + expect.objectContaining({ + id: "id", + revisionDate: new Date("2022-01-31T12:00:00.000Z"), + }), + ); + }); + }); }); diff --git a/libs/common/src/vault/models/domain/folder.ts b/libs/common/src/vault/models/domain/folder.ts index 9505bad7058..da9e9811d4c 100644 --- a/libs/common/src/vault/models/domain/folder.ts +++ b/libs/common/src/vault/models/domain/folder.ts @@ -1,10 +1,18 @@ import { Jsonify } from "type-fest"; +import { EncryptService } from "../../../platform/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"; import { FolderData } from "../data/folder.data"; import { FolderView } from "../view/folder.view"; +export class Test extends Domain { + id: string; + name: EncString; + revisionDate: Date; +} + export class Folder extends Domain { id: string; name: EncString; @@ -39,6 +47,17 @@ export class Folder extends Domain { ); } + async decryptWithKey( + key: SymmetricCryptoKey, + encryptService: EncryptService, + ): Promise { + const decrypted = await this.decryptObjWithKey(["name"], key, encryptService, Folder); + + const view = new FolderView(decrypted); + view.name = decrypted.name; + return view; + } + static fromJSON(obj: Jsonify) { const revisionDate = obj.revisionDate == null ? null : new Date(obj.revisionDate); return Object.assign(new Folder(), obj, { name: EncString.fromJSON(obj.name), revisionDate }); diff --git a/libs/common/src/vault/models/view/folder.view.ts b/libs/common/src/vault/models/view/folder.view.ts index 7e5c51bc307..47659c2739c 100644 --- a/libs/common/src/vault/models/view/folder.view.ts +++ b/libs/common/src/vault/models/view/folder.view.ts @@ -1,6 +1,7 @@ import { Jsonify } from "type-fest"; import { View } from "../../../models/view/view"; +import { DecryptedObject } from "../../../platform/models/domain/domain-base"; import { Folder } from "../domain/folder"; import { ITreeNodeObject } from "../domain/tree-node"; @@ -9,7 +10,7 @@ export class FolderView implements View, ITreeNodeObject { name: string = null; revisionDate: Date = null; - constructor(f?: Folder) { + constructor(f?: Folder | DecryptedObject) { if (!f) { return; } diff --git a/libs/tools/generator/components/src/catchall-settings.component.html b/libs/tools/generator/components/src/catchall-settings.component.html new file mode 100644 index 00000000000..0b2a9e69ef3 --- /dev/null +++ b/libs/tools/generator/components/src/catchall-settings.component.html @@ -0,0 +1,6 @@ +
+ + {{ "domainName" | i18n }} + + +
diff --git a/libs/tools/generator/components/src/catchall-settings.component.ts b/libs/tools/generator/components/src/catchall-settings.component.ts new file mode 100644 index 00000000000..1d7ba7608de --- /dev/null +++ b/libs/tools/generator/components/src/catchall-settings.component.ts @@ -0,0 +1,86 @@ +import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from "@angular/core"; +import { FormBuilder } from "@angular/forms"; +import { BehaviorSubject, skip, Subject, takeUntil } from "rxjs"; + +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { UserId } from "@bitwarden/common/types/guid"; +import { + CatchallGenerationOptions, + CredentialGeneratorService, + Generators, +} from "@bitwarden/generator-core"; + +import { DependenciesModule } from "./dependencies"; +import { completeOnAccountSwitch } from "./util"; + +/** Options group for catchall emails */ +@Component({ + standalone: true, + selector: "tools-catchall-settings", + templateUrl: "catchall-settings.component.html", + imports: [DependenciesModule], +}) +export class CatchallSettingsComponent implements OnInit, OnDestroy { + /** Instantiates the component + * @param accountService queries user availability + * @param generatorService settings and policy logic + * @param formBuilder reactive form controls + */ + constructor( + private formBuilder: FormBuilder, + private generatorService: CredentialGeneratorService, + private accountService: AccountService, + ) {} + + /** Binds the component to a specific user's settings. + * When this input is not provided, the form binds to the active + * user + */ + @Input() + userId: UserId | null; + + /** Emits settings updates and completes if the settings become unavailable. + * @remarks this does not emit the initial settings. If you would like + * to receive live settings updates including the initial update, + * use `CredentialGeneratorService.settings$(...)` instead. + */ + @Output() + readonly onUpdated = new EventEmitter(); + + /** The template's control bindings */ + protected settings = this.formBuilder.group({ + catchallDomain: [Generators.catchall.settings.initial.catchallDomain], + }); + + async ngOnInit() { + const singleUserId$ = this.singleUserId$(); + const settings = await this.generatorService.settings(Generators.catchall, { singleUserId$ }); + + settings.pipe(takeUntil(this.destroyed$)).subscribe((s) => { + this.settings.patchValue(s, { emitEvent: false }); + }); + + // the first emission is the current value; subsequent emissions are updates + settings.pipe(skip(1), takeUntil(this.destroyed$)).subscribe(this.onUpdated); + + this.settings.valueChanges.pipe(takeUntil(this.destroyed$)).subscribe(settings); + } + + private singleUserId$() { + // FIXME: this branch should probably scan for the user and make sure + // the account is unlocked + if (this.userId) { + return new BehaviorSubject(this.userId as UserId).asObservable(); + } + + return this.accountService.activeAccount$.pipe( + completeOnAccountSwitch(), + takeUntil(this.destroyed$), + ); + } + + private readonly destroyed$ = new Subject(); + ngOnDestroy(): void { + this.destroyed$.complete(); + } +} diff --git a/libs/tools/generator/components/src/dependencies.ts b/libs/tools/generator/components/src/dependencies.ts index d96ff0db8d6..ba9219b237a 100644 --- a/libs/tools/generator/components/src/dependencies.ts +++ b/libs/tools/generator/components/src/dependencies.ts @@ -19,6 +19,7 @@ import { ItemModule, SectionComponent, SectionHeaderComponent, + SelectModule, ToggleGroupModule, } from "@bitwarden/components"; import { @@ -46,6 +47,7 @@ const RANDOMIZER = new SafeInjectionToken("Randomizer"); ReactiveFormsModule, SectionComponent, SectionHeaderComponent, + SelectModule, ToggleGroupModule, ], providers: [ diff --git a/libs/tools/generator/components/src/index.ts b/libs/tools/generator/components/src/index.ts index 4423f8a1ec9..9367a32546c 100644 --- a/libs/tools/generator/components/src/index.ts +++ b/libs/tools/generator/components/src/index.ts @@ -1,5 +1,9 @@ -export { PassphraseSettingsComponent } from "./passphrase-settings.component"; +export { CatchallSettingsComponent } from "./catchall-settings.component"; export { CredentialGeneratorHistoryComponent } from "./credential-generator-history.component"; export { EmptyCredentialHistoryComponent } from "./empty-credential-history.component"; +export { PassphraseSettingsComponent } from "./passphrase-settings.component"; export { PasswordSettingsComponent } from "./password-settings.component"; export { PasswordGeneratorComponent } from "./password-generator.component"; +export { SubaddressSettingsComponent } from "./subaddress-settings.component"; +export { UsernameGeneratorComponent } from "./username-generator.component"; +export { UsernameSettingsComponent } from "./username-settings.component"; diff --git a/libs/tools/generator/components/src/passphrase-settings.component.ts b/libs/tools/generator/components/src/passphrase-settings.component.ts index acbd96f10d3..bfb3425bf63 100644 --- a/libs/tools/generator/components/src/passphrase-settings.component.ts +++ b/libs/tools/generator/components/src/passphrase-settings.component.ts @@ -39,7 +39,7 @@ export class PassphraseSettingsComponent implements OnInit, OnDestroy { private accountService: AccountService, ) {} - /** Binds the passphrase component to a specific user's settings. + /** Binds the component to a specific user's settings. * When this input is not provided, the form binds to the active * user */ @@ -59,15 +59,15 @@ export class PassphraseSettingsComponent implements OnInit, OnDestroy { readonly onUpdated = new EventEmitter(); protected settings = this.formBuilder.group({ - [Controls.numWords]: [Generators.Passphrase.settings.initial.numWords], - [Controls.wordSeparator]: [Generators.Passphrase.settings.initial.wordSeparator], - [Controls.capitalize]: [Generators.Passphrase.settings.initial.capitalize], - [Controls.includeNumber]: [Generators.Passphrase.settings.initial.includeNumber], + [Controls.numWords]: [Generators.passphrase.settings.initial.numWords], + [Controls.wordSeparator]: [Generators.passphrase.settings.initial.wordSeparator], + [Controls.capitalize]: [Generators.passphrase.settings.initial.capitalize], + [Controls.includeNumber]: [Generators.passphrase.settings.initial.includeNumber], }); async ngOnInit() { const singleUserId$ = this.singleUserId$(); - const settings = await this.generatorService.settings(Generators.Passphrase, { singleUserId$ }); + const settings = await this.generatorService.settings(Generators.passphrase, { singleUserId$ }); // skips reactive event emissions to break a subscription cycle settings.pipe(takeUntil(this.destroyed$)).subscribe((s) => { @@ -79,16 +79,16 @@ export class PassphraseSettingsComponent implements OnInit, OnDestroy { // dynamic policy enforcement this.generatorService - .policy$(Generators.Passphrase, { userId$: singleUserId$ }) + .policy$(Generators.passphrase, { userId$: singleUserId$ }) .pipe(takeUntil(this.destroyed$)) .subscribe(({ constraints }) => { this.settings .get(Controls.numWords) - .setValidators(toValidators(Controls.numWords, Generators.Passphrase, constraints)); + .setValidators(toValidators(Controls.numWords, Generators.passphrase, constraints)); this.settings .get(Controls.wordSeparator) - .setValidators(toValidators(Controls.wordSeparator, Generators.Passphrase, constraints)); + .setValidators(toValidators(Controls.wordSeparator, Generators.passphrase, constraints)); // forward word boundaries to the template (can't do it through the rx form) this.minNumWords = constraints.numWords.min; diff --git a/libs/tools/generator/components/src/password-generator.component.ts b/libs/tools/generator/components/src/password-generator.component.ts index 1519df4a674..b6d8fbf60da 100644 --- a/libs/tools/generator/components/src/password-generator.component.ts +++ b/libs/tools/generator/components/src/password-generator.component.ts @@ -3,8 +3,12 @@ import { BehaviorSubject, distinctUntilChanged, map, Subject, switchMap, takeUnt import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { UserId } from "@bitwarden/common/types/guid"; -import { CredentialGeneratorService, Generators, GeneratorType } from "@bitwarden/generator-core"; -import { GeneratedCredential } from "@bitwarden/generator-history"; +import { + CredentialGeneratorService, + Generators, + PasswordAlgorithm, + GeneratedCredential, +} from "@bitwarden/generator-core"; import { DependenciesModule } from "./dependencies"; import { PassphraseSettingsComponent } from "./passphrase-settings.component"; @@ -24,7 +28,7 @@ export class PasswordGeneratorComponent implements OnInit, OnDestroy { private zone: NgZone, ) {} - /** Binds the passphrase component to a specific user's settings. + /** Binds the component to a specific user's settings. * When this input is not provided, the form binds to the active * user */ @@ -32,7 +36,7 @@ export class PasswordGeneratorComponent implements OnInit, OnDestroy { userId: UserId | null; /** tracks the currently selected credential type */ - protected credentialType$ = new BehaviorSubject("password"); + protected credentialType$ = new BehaviorSubject("password"); /** Emits the last generated value. */ protected readonly value$ = new BehaviorSubject(""); @@ -46,7 +50,7 @@ export class PasswordGeneratorComponent implements OnInit, OnDestroy { /** Tracks changes to the selected credential type * @param type the new credential type */ - protected onCredentialTypeChanged(type: GeneratorType) { + protected onCredentialTypeChanged(type: PasswordAlgorithm) { if (this.credentialType$.value !== type) { this.credentialType$.next(type); this.generate$.next(); @@ -85,7 +89,7 @@ export class PasswordGeneratorComponent implements OnInit, OnDestroy { }); } - private typeToGenerator$(type: GeneratorType) { + private typeToGenerator$(type: PasswordAlgorithm) { const dependencies = { on$: this.generate$, userId$: this.userId$, @@ -93,10 +97,10 @@ export class PasswordGeneratorComponent implements OnInit, OnDestroy { switch (type) { case "password": - return this.generatorService.generate$(Generators.Password, dependencies); + return this.generatorService.generate$(Generators.password, dependencies); case "passphrase": - return this.generatorService.generate$(Generators.Passphrase, dependencies); + return this.generatorService.generate$(Generators.passphrase, dependencies); default: throw new Error(`Invalid generator type: "${type}"`); } diff --git a/libs/tools/generator/components/src/password-settings.component.ts b/libs/tools/generator/components/src/password-settings.component.ts index 2553bba3f72..d9fd6cd99c9 100644 --- a/libs/tools/generator/components/src/password-settings.component.ts +++ b/libs/tools/generator/components/src/password-settings.component.ts @@ -67,14 +67,14 @@ export class PasswordSettingsComponent implements OnInit, OnDestroy { readonly onUpdated = new EventEmitter(); protected settings = this.formBuilder.group({ - [Controls.length]: [Generators.Password.settings.initial.length], - [Controls.uppercase]: [Generators.Password.settings.initial.uppercase], - [Controls.lowercase]: [Generators.Password.settings.initial.lowercase], - [Controls.number]: [Generators.Password.settings.initial.number], - [Controls.special]: [Generators.Password.settings.initial.special], - [Controls.minNumber]: [Generators.Password.settings.initial.minNumber], - [Controls.minSpecial]: [Generators.Password.settings.initial.minSpecial], - [Controls.avoidAmbiguous]: [!Generators.Password.settings.initial.ambiguous], + [Controls.length]: [Generators.password.settings.initial.length], + [Controls.uppercase]: [Generators.password.settings.initial.uppercase], + [Controls.lowercase]: [Generators.password.settings.initial.lowercase], + [Controls.number]: [Generators.password.settings.initial.number], + [Controls.special]: [Generators.password.settings.initial.special], + [Controls.minNumber]: [Generators.password.settings.initial.minNumber], + [Controls.minSpecial]: [Generators.password.settings.initial.minSpecial], + [Controls.avoidAmbiguous]: [!Generators.password.settings.initial.ambiguous], }); private get numbers() { @@ -95,7 +95,7 @@ export class PasswordSettingsComponent implements OnInit, OnDestroy { async ngOnInit() { const singleUserId$ = this.singleUserId$(); - const settings = await this.generatorService.settings(Generators.Password, { singleUserId$ }); + const settings = await this.generatorService.settings(Generators.password, { singleUserId$ }); // bind settings to the UI settings @@ -116,19 +116,19 @@ export class PasswordSettingsComponent implements OnInit, OnDestroy { // bind policy to the template this.generatorService - .policy$(Generators.Password, { userId$: singleUserId$ }) + .policy$(Generators.password, { userId$: singleUserId$ }) .pipe(takeUntil(this.destroyed$)) .subscribe(({ constraints }) => { this.settings .get(Controls.length) - .setValidators(toValidators(Controls.length, Generators.Password, constraints)); + .setValidators(toValidators(Controls.length, Generators.password, constraints)); this.minNumber.setValidators( - toValidators(Controls.minNumber, Generators.Password, constraints), + toValidators(Controls.minNumber, Generators.password, constraints), ); this.minSpecial.setValidators( - toValidators(Controls.minSpecial, Generators.Password, constraints), + toValidators(Controls.minSpecial, Generators.password, constraints), ); // forward word boundaries to the template (can't do it through the rx form) diff --git a/libs/tools/generator/components/src/subaddress-settings.component.html b/libs/tools/generator/components/src/subaddress-settings.component.html new file mode 100644 index 00000000000..16f3aea28bf --- /dev/null +++ b/libs/tools/generator/components/src/subaddress-settings.component.html @@ -0,0 +1,6 @@ +
+ + {{ "email" | i18n }} + + +
diff --git a/libs/tools/generator/components/src/subaddress-settings.component.ts b/libs/tools/generator/components/src/subaddress-settings.component.ts new file mode 100644 index 00000000000..ed55cb51ba0 --- /dev/null +++ b/libs/tools/generator/components/src/subaddress-settings.component.ts @@ -0,0 +1,86 @@ +import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from "@angular/core"; +import { FormBuilder } from "@angular/forms"; +import { BehaviorSubject, skip, Subject, takeUntil } from "rxjs"; + +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { UserId } from "@bitwarden/common/types/guid"; +import { + CredentialGeneratorService, + Generators, + SubaddressGenerationOptions, +} from "@bitwarden/generator-core"; + +import { DependenciesModule } from "./dependencies"; +import { completeOnAccountSwitch } from "./util"; + +/** Options group for plus-addressed emails */ +@Component({ + standalone: true, + selector: "tools-subaddress-settings", + templateUrl: "subaddress-settings.component.html", + imports: [DependenciesModule], +}) +export class SubaddressSettingsComponent implements OnInit, OnDestroy { + /** Instantiates the component + * @param accountService queries user availability + * @param generatorService settings and policy logic + * @param formBuilder reactive form controls + */ + constructor( + private formBuilder: FormBuilder, + private generatorService: CredentialGeneratorService, + private accountService: AccountService, + ) {} + + /** Binds the component to a specific user's settings. + * When this input is not provided, the form binds to the active + * user + */ + @Input() + userId: UserId | null; + + /** Emits settings updates and completes if the settings become unavailable. + * @remarks this does not emit the initial settings. If you would like + * to receive live settings updates including the initial update, + * use `CredentialGeneratorService.settings$(...)` instead. + */ + @Output() + readonly onUpdated = new EventEmitter(); + + /** The template's control bindings */ + protected settings = this.formBuilder.group({ + subaddressEmail: [Generators.subaddress.settings.initial.subaddressEmail], + }); + + async ngOnInit() { + const singleUserId$ = this.singleUserId$(); + const settings = await this.generatorService.settings(Generators.subaddress, { singleUserId$ }); + + settings.pipe(takeUntil(this.destroyed$)).subscribe((s) => { + this.settings.patchValue(s, { emitEvent: false }); + }); + + // the first emission is the current value; subsequent emissions are updates + settings.pipe(skip(1), takeUntil(this.destroyed$)).subscribe(this.onUpdated); + + this.settings.valueChanges.pipe(takeUntil(this.destroyed$)).subscribe(settings); + } + + private singleUserId$() { + // FIXME: this branch should probably scan for the user and make sure + // the account is unlocked + if (this.userId) { + return new BehaviorSubject(this.userId as UserId).asObservable(); + } + + return this.accountService.activeAccount$.pipe( + completeOnAccountSwitch(), + takeUntil(this.destroyed$), + ); + } + + private readonly destroyed$ = new Subject(); + ngOnDestroy(): void { + this.destroyed$.complete(); + } +} diff --git a/libs/tools/generator/components/src/username-generator.component.html b/libs/tools/generator/components/src/username-generator.component.html new file mode 100644 index 00000000000..413de931452 --- /dev/null +++ b/libs/tools/generator/components/src/username-generator.component.html @@ -0,0 +1,51 @@ + +
+ +
+
+ + +
+
+ + +
{{ "options" | i18n }}
+
+
+ +
+ + {{ "type" | i18n }} + + {{ + credentialTypeHint$ | async + }} + +
+ + + +
+
+
diff --git a/libs/tools/generator/components/src/username-generator.component.ts b/libs/tools/generator/components/src/username-generator.component.ts new file mode 100644 index 00000000000..e5327cc66eb --- /dev/null +++ b/libs/tools/generator/components/src/username-generator.component.ts @@ -0,0 +1,238 @@ +import { Component, EventEmitter, Input, NgZone, OnDestroy, OnInit, Output } from "@angular/core"; +import { FormBuilder } from "@angular/forms"; +import { + BehaviorSubject, + distinctUntilChanged, + filter, + map, + ReplaySubject, + Subject, + switchMap, + takeUntil, + withLatestFrom, +} from "rxjs"; + +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { UserId } from "@bitwarden/common/types/guid"; +import { Option } from "@bitwarden/components/src/select/option"; +import { + CredentialAlgorithm, + CredentialGeneratorInfo, + CredentialGeneratorService, + GeneratedCredential, + Generators, + isEmailAlgorithm, + isUsernameAlgorithm, +} from "@bitwarden/generator-core"; + +import { CatchallSettingsComponent } from "./catchall-settings.component"; +import { DependenciesModule } from "./dependencies"; +import { SubaddressSettingsComponent } from "./subaddress-settings.component"; +import { UsernameSettingsComponent } from "./username-settings.component"; +import { completeOnAccountSwitch } from "./util"; + +/** Component that generates usernames and emails */ +@Component({ + standalone: true, + selector: "tools-username-generator", + templateUrl: "username-generator.component.html", + imports: [ + DependenciesModule, + CatchallSettingsComponent, + SubaddressSettingsComponent, + UsernameSettingsComponent, + ], +}) +export class UsernameGeneratorComponent implements OnInit, OnDestroy { + /** Instantiates the username generator + * @param generatorService generates credentials; stores preferences + * @param i18nService localizes generator algorithm descriptions + * @param accountService discovers the active user when one is not provided + * @param zone detects generator settings updates originating from the generator services + * @param formBuilder binds reactive form + */ + constructor( + private generatorService: CredentialGeneratorService, + private i18nService: I18nService, + private accountService: AccountService, + private zone: NgZone, + private formBuilder: FormBuilder, + ) {} + + /** Binds the component to a specific user's settings. When this input is not provided, + * the form binds to the active user + */ + @Input() + userId: UserId | null; + + /** Emits credentials created from a generation request. */ + @Output() + readonly onGenerated = new EventEmitter(); + + /** Tracks the selected generation algorithm */ + protected credential = this.formBuilder.group({ + type: ["username" as CredentialAlgorithm], + }); + + async ngOnInit() { + if (this.userId) { + this.userId$.next(this.userId); + } else { + this.singleUserId$().pipe(takeUntil(this.destroyed)).subscribe(this.userId$); + } + + this.generatorService + .algorithms$(["email", "username"], { userId$: this.userId$ }) + .pipe( + map((algorithms) => this.toOptions(algorithms)), + takeUntil(this.destroyed), + ) + .subscribe(this.typeOptions$); + + this.algorithm$ + .pipe( + map((a) => a?.descriptionKey && this.i18nService.t(a?.descriptionKey)), + takeUntil(this.destroyed), + ) + .subscribe((hint) => { + // update subjects within the angular zone so that the + // template bindings refresh immediately + this.zone.run(() => { + this.credentialTypeHint$.next(hint); + }); + }); + + // wire up the generator + this.algorithm$ + .pipe( + switchMap((algorithm) => this.typeToGenerator$(algorithm.id)), + takeUntil(this.destroyed), + ) + .subscribe((generated) => { + // update subjects within the angular zone so that the + // template bindings refresh immediately + this.zone.run(() => { + this.onGenerated.next(generated); + this.value$.next(generated.credential); + }); + }); + + // assume the last-visible generator algorithm is the user's preferred one + const preferences = await this.generatorService.preferences({ singleUserId$: this.userId$ }); + this.credential.valueChanges + .pipe(withLatestFrom(preferences), takeUntil(this.destroyed)) + .subscribe(([{ type }, preference]) => { + if (isEmailAlgorithm(type)) { + preference.email.algorithm = type; + preference.email.updated = new Date(); + } else if (isUsernameAlgorithm(type)) { + preference.username.algorithm = type; + preference.username.updated = new Date(); + } else { + return; + } + + preferences.next(preference); + }); + + // populate the form with the user's preferences to kick off interactivity + preferences.pipe(takeUntil(this.destroyed)).subscribe(({ email, username }) => { + // this generator supports email & username; the last preference + // set by the user "wins" + const preference = email.updated > username.updated ? email.algorithm : username.algorithm; + + // break subscription loop + this.credential.setValue({ type: preference }, { emitEvent: false }); + + const algorithm = this.generatorService.algorithm(preference); + // update subjects within the angular zone so that the + // template bindings refresh immediately + this.zone.run(() => { + this.algorithm$.next(algorithm); + }); + }); + + // generate on load unless the generator prohibits it + this.algorithm$ + .pipe( + distinctUntilChanged((prev, next) => prev.id === next.id), + filter((a) => !a.onlyOnRequest), + takeUntil(this.destroyed), + ) + .subscribe(() => this.generate$.next()); + } + + private typeToGenerator$(type: CredentialAlgorithm) { + const dependencies = { + on$: this.generate$, + userId$: this.userId$, + }; + + switch (type) { + case "catchall": + return this.generatorService.generate$(Generators.catchall, dependencies); + + case "subaddress": + return this.generatorService.generate$(Generators.subaddress, dependencies); + + case "username": + return this.generatorService.generate$(Generators.username, dependencies); + + default: + throw new Error(`Invalid generator type: "${type}"`); + } + } + + /** Lists the credential types supported by the component. */ + protected typeOptions$ = new BehaviorSubject[]>([]); + + /** tracks the currently selected credential type */ + protected algorithm$ = new ReplaySubject(1); + + /** Emits hint key for the currently selected credential type */ + protected credentialTypeHint$ = new ReplaySubject(1); + + /** Emits the last generated value. */ + protected readonly value$ = new BehaviorSubject(""); + + /** Emits when the userId changes */ + protected readonly userId$ = new BehaviorSubject(null); + + /** Emits when a new credential is requested */ + protected readonly generate$ = new Subject(); + + private singleUserId$() { + // FIXME: this branch should probably scan for the user and make sure + // the account is unlocked + if (this.userId) { + return new BehaviorSubject(this.userId as UserId).asObservable(); + } + + return this.accountService.activeAccount$.pipe( + completeOnAccountSwitch(), + takeUntil(this.destroyed), + ); + } + + private toOptions(algorithms: CredentialGeneratorInfo[]) { + const options: Option[] = algorithms.map((algorithm) => ({ + value: algorithm.id, + label: this.i18nService.t(algorithm.nameKey), + })); + + return options; + } + + private readonly destroyed = new Subject(); + ngOnDestroy() { + this.destroyed.complete(); + + // finalize subjects + this.generate$.complete(); + this.value$.complete(); + + // finalize component bindings + this.onGenerated.complete(); + } +} diff --git a/libs/tools/generator/components/src/username-settings.component.html b/libs/tools/generator/components/src/username-settings.component.html new file mode 100644 index 00000000000..4a4f8cd9feb --- /dev/null +++ b/libs/tools/generator/components/src/username-settings.component.html @@ -0,0 +1,10 @@ +
+ + + {{ "capitalize" | i18n }} + + + + {{ "includeNumber" | i18n }} + +
diff --git a/libs/tools/generator/components/src/username-settings.component.ts b/libs/tools/generator/components/src/username-settings.component.ts new file mode 100644 index 00000000000..978bd05ca79 --- /dev/null +++ b/libs/tools/generator/components/src/username-settings.component.ts @@ -0,0 +1,87 @@ +import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from "@angular/core"; +import { FormBuilder } from "@angular/forms"; +import { BehaviorSubject, skip, Subject, takeUntil } from "rxjs"; + +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { UserId } from "@bitwarden/common/types/guid"; +import { + CredentialGeneratorService, + EffUsernameGenerationOptions, + Generators, +} from "@bitwarden/generator-core"; + +import { DependenciesModule } from "./dependencies"; +import { completeOnAccountSwitch } from "./util"; + +/** Options group for usernames */ +@Component({ + standalone: true, + selector: "tools-username-settings", + templateUrl: "username-settings.component.html", + imports: [DependenciesModule], +}) +export class UsernameSettingsComponent implements OnInit, OnDestroy { + /** Instantiates the component + * @param accountService queries user availability + * @param generatorService settings and policy logic + * @param formBuilder reactive form controls + */ + constructor( + private formBuilder: FormBuilder, + private generatorService: CredentialGeneratorService, + private accountService: AccountService, + ) {} + + /** Binds the component to a specific user's settings. + * When this input is not provided, the form binds to the active + * user + */ + @Input() + userId: UserId | null; + + /** Emits settings updates and completes if the settings become unavailable. + * @remarks this does not emit the initial settings. If you would like + * to receive live settings updates including the initial update, + * use `CredentialGeneratorService.settings$(...)` instead. + */ + @Output() + readonly onUpdated = new EventEmitter(); + + /** The template's control bindings */ + protected settings = this.formBuilder.group({ + wordCapitalize: [Generators.username.settings.initial.wordCapitalize], + wordIncludeNumber: [Generators.username.settings.initial.wordIncludeNumber], + }); + + async ngOnInit() { + const singleUserId$ = this.singleUserId$(); + const settings = await this.generatorService.settings(Generators.username, { singleUserId$ }); + + settings.pipe(takeUntil(this.destroyed$)).subscribe((s) => { + this.settings.patchValue(s, { emitEvent: false }); + }); + + // the first emission is the current value; subsequent emissions are updates + settings.pipe(skip(1), takeUntil(this.destroyed$)).subscribe(this.onUpdated); + + this.settings.valueChanges.pipe(takeUntil(this.destroyed$)).subscribe(settings); + } + + private singleUserId$() { + // FIXME: this branch should probably scan for the user and make sure + // the account is unlocked + if (this.userId) { + return new BehaviorSubject(this.userId as UserId).asObservable(); + } + + return this.accountService.activeAccount$.pipe( + completeOnAccountSwitch(), + takeUntil(this.destroyed$), + ); + } + + private readonly destroyed$ = new Subject(); + ngOnDestroy(): void { + this.destroyed$.complete(); + } +} diff --git a/libs/tools/generator/core/src/data/default-credential-preferences.ts b/libs/tools/generator/core/src/data/default-credential-preferences.ts new file mode 100644 index 00000000000..c26d44b3b79 --- /dev/null +++ b/libs/tools/generator/core/src/data/default-credential-preferences.ts @@ -0,0 +1,18 @@ +import { CredentialPreference } from "../types"; + +import { EmailAlgorithms, PasswordAlgorithms, UsernameAlgorithms } from "./generator-types"; + +export const DefaultCredentialPreferences: CredentialPreference = Object.freeze({ + email: Object.freeze({ + algorithm: EmailAlgorithms[0], + updated: new Date(0), + }), + password: Object.freeze({ + algorithm: PasswordAlgorithms[0], + updated: new Date(0), + }), + username: Object.freeze({ + algorithm: UsernameAlgorithms[0], + updated: new Date(0), + }), +}); diff --git a/libs/tools/generator/core/src/data/generator-types.ts b/libs/tools/generator/core/src/data/generator-types.ts index c68131f6042..6c351b82e33 100644 --- a/libs/tools/generator/core/src/data/generator-types.ts +++ b/libs/tools/generator/core/src/data/generator-types.ts @@ -1,5 +1,15 @@ -/** Types of passwords that may be configured by the password generator */ -export const PasswordTypes = Object.freeze(["password", "passphrase"] as const); +/** Types of passwords that may be generated by the credential generator */ +export const PasswordAlgorithms = Object.freeze(["password", "passphrase"] as const); -/** Types of generators that may be configured by the password generator */ -export const GeneratorTypes = Object.freeze([...PasswordTypes, "username"] as const); +/** Types of usernames that may be generated by the credential generator */ +export const UsernameAlgorithms = Object.freeze(["username"] as const); + +/** Types of email addresses that may be generated by the credential generator */ +export const EmailAlgorithms = Object.freeze(["catchall", "forwarder", "subaddress"] as const); + +/** All types of credentials that may be generated by the credential generator */ +export const CredentialAlgorithms = Object.freeze([ + ...PasswordAlgorithms, + ...UsernameAlgorithms, + ...EmailAlgorithms, +] as const); diff --git a/libs/tools/generator/core/src/data/generators.ts b/libs/tools/generator/core/src/data/generators.ts index f71d484f9c2..2c96b0c2d39 100644 --- a/libs/tools/generator/core/src/data/generators.ts +++ b/libs/tools/generator/core/src/data/generators.ts @@ -1,23 +1,51 @@ +import { PolicyType } from "@bitwarden/common/admin-console/enums"; +import { Policy } from "@bitwarden/common/admin-console/models/domain/policy"; +import { IdentityConstraint } from "@bitwarden/common/tools/state/identity-state-constraint"; + import { Randomizer } from "../abstractions"; -import { PasswordRandomizer } from "../engine"; -import { PASSPHRASE_SETTINGS, PASSWORD_SETTINGS } from "../strategies/storage"; +import { EmailRandomizer, PasswordRandomizer, UsernameRandomizer } from "../engine"; import { + DefaultPolicyEvaluator, + DynamicPasswordPolicyConstraints, + PassphraseGeneratorOptionsEvaluator, + passphraseLeastPrivilege, + PassphrasePolicyConstraints, + PasswordGeneratorOptionsEvaluator, + passwordLeastPrivilege, +} from "../policies"; +import { + CATCHALL_SETTINGS, + EFF_USERNAME_SETTINGS, + PASSPHRASE_SETTINGS, + PASSWORD_SETTINGS, + SUBADDRESS_SETTINGS, +} from "../strategies/storage"; +import { + CatchallGenerationOptions, CredentialGenerator, + CredentialGeneratorConfiguration, + EffUsernameGenerationOptions, + NoPolicy, PassphraseGenerationOptions, PassphraseGeneratorPolicy, PasswordGenerationOptions, PasswordGeneratorPolicy, + SubaddressGenerationOptions, } from "../types"; -import { CredentialGeneratorConfiguration } from "../types/credential-generator-configuration"; +import { DefaultCatchallOptions } from "./default-catchall-options"; +import { DefaultEffUsernameOptions } from "./default-eff-username-options"; import { DefaultPassphraseBoundaries } from "./default-passphrase-boundaries"; import { DefaultPassphraseGenerationOptions } from "./default-passphrase-generation-options"; import { DefaultPasswordBoundaries } from "./default-password-boundaries"; import { DefaultPasswordGenerationOptions } from "./default-password-generation-options"; -import { Policies } from "./policies"; +import { DefaultSubaddressOptions } from "./default-subaddress-generator-options"; const PASSPHRASE = Object.freeze({ - category: "passphrase", + id: "passphrase", + category: "password", + nameKey: "passphrase", + onlyOnRequest: false, engine: { create(randomizer: Randomizer): CredentialGenerator { return new PasswordRandomizer(randomizer); @@ -34,14 +62,27 @@ const PASSPHRASE = Object.freeze({ }, account: PASSPHRASE_SETTINGS, }, - policy: Policies.Passphrase, + policy: { + type: PolicyType.PasswordGenerator, + disabledValue: Object.freeze({ + minNumberWords: 0, + capitalize: false, + includeNumber: false, + }), + combine: passphraseLeastPrivilege, + createEvaluator: (policy) => new PassphraseGeneratorOptionsEvaluator(policy), + toConstraints: (policy) => new PassphrasePolicyConstraints(policy), + }, } satisfies CredentialGeneratorConfiguration< PassphraseGenerationOptions, PassphraseGeneratorPolicy >); const PASSWORD = Object.freeze({ + id: "password", category: "password", + nameKey: "password", + onlyOnRequest: false, engine: { create(randomizer: Randomizer): CredentialGenerator { return new PasswordRandomizer(randomizer); @@ -65,14 +106,129 @@ const PASSWORD = Object.freeze({ }, account: PASSWORD_SETTINGS, }, - policy: Policies.Password, + policy: { + type: PolicyType.PasswordGenerator, + disabledValue: Object.freeze({ + minLength: 0, + useUppercase: false, + useLowercase: false, + useNumbers: false, + numberCount: 0, + useSpecial: false, + specialCount: 0, + }), + combine: passwordLeastPrivilege, + createEvaluator: (policy) => new PasswordGeneratorOptionsEvaluator(policy), + toConstraints: (policy) => new DynamicPasswordPolicyConstraints(policy), + }, } satisfies CredentialGeneratorConfiguration); +const USERNAME = Object.freeze({ + id: "username", + category: "username", + nameKey: "randomWord", + onlyOnRequest: false, + engine: { + create(randomizer: Randomizer): CredentialGenerator { + return new UsernameRandomizer(randomizer); + }, + }, + settings: { + initial: DefaultEffUsernameOptions, + constraints: {}, + account: EFF_USERNAME_SETTINGS, + }, + policy: { + type: PolicyType.PasswordGenerator, + disabledValue: {}, + combine(_acc: NoPolicy, _policy: Policy) { + return {}; + }, + createEvaluator(_policy: NoPolicy) { + return new DefaultPolicyEvaluator(); + }, + toConstraints(_policy: NoPolicy) { + return new IdentityConstraint(); + }, + }, +} satisfies CredentialGeneratorConfiguration); + +const CATCHALL = Object.freeze({ + id: "catchall", + category: "email", + nameKey: "catchallEmail", + descriptionKey: "catchallEmailDesc", + onlyOnRequest: false, + engine: { + create(randomizer: Randomizer): CredentialGenerator { + return new EmailRandomizer(randomizer); + }, + }, + settings: { + initial: DefaultCatchallOptions, + constraints: { catchallDomain: { minLength: 1 } }, + account: CATCHALL_SETTINGS, + }, + policy: { + type: PolicyType.PasswordGenerator, + disabledValue: {}, + combine(_acc: NoPolicy, _policy: Policy) { + return {}; + }, + createEvaluator(_policy: NoPolicy) { + return new DefaultPolicyEvaluator(); + }, + toConstraints(_policy: NoPolicy) { + return new IdentityConstraint(); + }, + }, +} satisfies CredentialGeneratorConfiguration); + +const SUBADDRESS = Object.freeze({ + id: "subaddress", + category: "email", + nameKey: "plusAddressedEmail", + descriptionKey: "plusAddressedEmailDesc", + onlyOnRequest: false, + engine: { + create(randomizer: Randomizer): CredentialGenerator { + return new EmailRandomizer(randomizer); + }, + }, + settings: { + initial: DefaultSubaddressOptions, + constraints: {}, + account: SUBADDRESS_SETTINGS, + }, + policy: { + type: PolicyType.PasswordGenerator, + disabledValue: {}, + combine(_acc: NoPolicy, _policy: Policy) { + return {}; + }, + createEvaluator(_policy: NoPolicy) { + return new DefaultPolicyEvaluator(); + }, + toConstraints(_policy: NoPolicy) { + return new IdentityConstraint(); + }, + }, +} satisfies CredentialGeneratorConfiguration); + /** Generator configurations */ export const Generators = Object.freeze({ /** Passphrase generator configuration */ - Passphrase: PASSPHRASE, + passphrase: PASSPHRASE, /** Password generator configuration */ - Password: PASSWORD, + password: PASSWORD, + + /** Username generator configuration */ + username: USERNAME, + + /** Catchall email generator configuration */ + catchall: CATCHALL, + + /** Email subaddress generator configuration */ + subaddress: SUBADDRESS, }); diff --git a/libs/tools/generator/core/src/data/index.ts b/libs/tools/generator/core/src/data/index.ts index eaaac757ff5..482703fd3c3 100644 --- a/libs/tools/generator/core/src/data/index.ts +++ b/libs/tools/generator/core/src/data/index.ts @@ -10,6 +10,7 @@ export * from "./default-eff-username-options"; export * from "./default-firefox-relay-options"; export * from "./default-passphrase-generation-options"; export * from "./default-password-generation-options"; +export * from "./default-credential-preferences"; export * from "./default-subaddress-generator-options"; export * from "./default-simple-login-options"; export * from "./forwarders"; diff --git a/libs/tools/generator/core/src/data/policies.ts b/libs/tools/generator/core/src/data/policies.ts index 4d758fc4653..4e46718a395 100644 --- a/libs/tools/generator/core/src/data/policies.ts +++ b/libs/tools/generator/core/src/data/policies.ts @@ -1,13 +1,3 @@ -import { PolicyType } from "@bitwarden/common/admin-console/enums"; - -import { - DynamicPasswordPolicyConstraints, - passphraseLeastPrivilege, - passwordLeastPrivilege, - PassphraseGeneratorOptionsEvaluator, - PassphrasePolicyConstraints, - PasswordGeneratorOptionsEvaluator, -} from "../policies"; import { PassphraseGenerationOptions, PassphraseGeneratorPolicy, @@ -16,39 +6,18 @@ import { PolicyConfiguration, } from "../types"; -const PASSPHRASE = Object.freeze({ - type: PolicyType.PasswordGenerator, - disabledValue: Object.freeze({ - minNumberWords: 0, - capitalize: false, - includeNumber: false, - }), - combine: passphraseLeastPrivilege, - createEvaluator: (policy) => new PassphraseGeneratorOptionsEvaluator(policy), - toConstraints: (policy) => new PassphrasePolicyConstraints(policy), -} as PolicyConfiguration); +import { Generators } from "./generators"; -const PASSWORD = Object.freeze({ - type: PolicyType.PasswordGenerator, - disabledValue: Object.freeze({ - minLength: 0, - useUppercase: false, - useLowercase: false, - useNumbers: false, - numberCount: 0, - useSpecial: false, - specialCount: 0, - }), - combine: passwordLeastPrivilege, - createEvaluator: (policy) => new PasswordGeneratorOptionsEvaluator(policy), - toConstraints: (policy) => new DynamicPasswordPolicyConstraints(policy), -} as PolicyConfiguration); - -/** Policy configurations */ +/** Policy configurations + * @deprecated use Generator.*.policy instead + */ export const Policies = Object.freeze({ + Passphrase: Generators.passphrase.policy, + Password: Generators.password.policy, +} satisfies { /** Passphrase policy configuration */ - Passphrase: PASSPHRASE, + Passphrase: PolicyConfiguration; - /** Passphrase policy configuration */ - Password: PASSWORD, + /** Password policy configuration */ + Password: PolicyConfiguration; }); diff --git a/libs/tools/generator/core/src/engine/email-randomizer.spec.ts b/libs/tools/generator/core/src/engine/email-randomizer.spec.ts index 8670b8c176f..fb953af1659 100644 --- a/libs/tools/generator/core/src/engine/email-randomizer.spec.ts +++ b/libs/tools/generator/core/src/engine/email-randomizer.spec.ts @@ -208,4 +208,40 @@ describe("EmailRandomizer", () => { expect(randomizer.pickWord).toHaveBeenCalledWith(expectedWordList, { titleCase: false }); }); }); + + describe("generate", () => { + it("processes catchall generation options", async () => { + const email = new EmailRandomizer(randomizer); + + const result = await email.generate( + {}, + { + catchallDomain: "example.com", + }, + ); + + expect(result.category).toEqual("catchall"); + }); + + it("processes subaddress generation options", async () => { + const email = new EmailRandomizer(randomizer); + + const result = await email.generate( + {}, + { + subaddressEmail: "foo@example.com", + }, + ); + + expect(result.category).toEqual("subaddress"); + }); + + it("throws when it cannot recognize the options type", async () => { + const email = new EmailRandomizer(randomizer); + + const result = email.generate({}, {}); + + await expect(result).rejects.toBeInstanceOf(Error); + }); + }); }); diff --git a/libs/tools/generator/core/src/engine/email-randomizer.ts b/libs/tools/generator/core/src/engine/email-randomizer.ts index 5029cdbc42b..f4a7e1304d4 100644 --- a/libs/tools/generator/core/src/engine/email-randomizer.ts +++ b/libs/tools/generator/core/src/engine/email-randomizer.ts @@ -1,10 +1,22 @@ import { EFFLongWordList } from "@bitwarden/common/platform/misc/wordlist"; +import { GenerationRequest } from "@bitwarden/common/tools/types"; + +import { + CatchallGenerationOptions, + CredentialGenerator, + GeneratedCredential, + SubaddressGenerationOptions, +} from "../types"; import { Randomizer } from "./abstractions"; import { SUBADDRESS_PARSER } from "./data"; /** Generation algorithms that produce randomized email addresses */ -export class EmailRandomizer { +export class EmailRandomizer + implements + CredentialGenerator, + CredentialGenerator +{ /** Instantiates the email randomizer * @param random data source for random data */ @@ -96,4 +108,37 @@ export class EmailRandomizer { return result; } + + generate( + request: GenerationRequest, + settings: CatchallGenerationOptions, + ): Promise; + generate( + request: GenerationRequest, + settings: SubaddressGenerationOptions, + ): Promise; + async generate( + _request: GenerationRequest, + settings: CatchallGenerationOptions | SubaddressGenerationOptions, + ) { + if (isCatchallGenerationOptions(settings)) { + const email = await this.randomAsciiCatchall(settings.catchallDomain); + + return new GeneratedCredential(email, "catchall", Date.now()); + } else if (isSubaddressGenerationOptions(settings)) { + const email = await this.randomAsciiSubaddress(settings.subaddressEmail); + + return new GeneratedCredential(email, "subaddress", Date.now()); + } + + throw new Error("Invalid settings received by generator."); + } +} + +function isCatchallGenerationOptions(settings: any): settings is CatchallGenerationOptions { + return "catchallDomain" in (settings ?? {}); +} + +function isSubaddressGenerationOptions(settings: any): settings is SubaddressGenerationOptions { + return "subaddressEmail" in (settings ?? {}); } diff --git a/libs/tools/generator/core/src/engine/username-randomizer.spec.ts b/libs/tools/generator/core/src/engine/username-randomizer.spec.ts index e30db286452..54d140e4469 100644 --- a/libs/tools/generator/core/src/engine/username-randomizer.spec.ts +++ b/libs/tools/generator/core/src/engine/username-randomizer.spec.ts @@ -102,4 +102,27 @@ describe("UsernameRandomizer", () => { expect(randomizer.pickWord).toHaveBeenNthCalledWith(2, EFFLongWordList, { titleCase: false }); }); }); + + describe("generate", () => { + it("processes username generation options", async () => { + const username = new UsernameRandomizer(randomizer); + + const result = await username.generate( + {}, + { + wordIncludeNumber: true, + }, + ); + + expect(result.category).toEqual("username"); + }); + + it("throws when it cannot recognize the options type", async () => { + const username = new UsernameRandomizer(randomizer); + + const result = username.generate({}, {}); + + await expect(result).rejects.toBeInstanceOf(Error); + }); + }); }); diff --git a/libs/tools/generator/core/src/engine/username-randomizer.ts b/libs/tools/generator/core/src/engine/username-randomizer.ts index 4a6aa43f604..d5872e21ce0 100644 --- a/libs/tools/generator/core/src/engine/username-randomizer.ts +++ b/libs/tools/generator/core/src/engine/username-randomizer.ts @@ -1,10 +1,13 @@ import { EFFLongWordList } from "@bitwarden/common/platform/misc/wordlist"; +import { GenerationRequest } from "@bitwarden/common/tools/types"; + +import { CredentialGenerator, EffUsernameGenerationOptions, GeneratedCredential } from "../types"; import { Randomizer } from "./abstractions"; import { WordsRequest } from "./types"; /** Generation algorithms that produce randomized usernames */ -export class UsernameRandomizer { +export class UsernameRandomizer implements CredentialGenerator { /** Instantiates the username randomizer * @param random data source for random data */ @@ -44,4 +47,21 @@ export class UsernameRandomizer { return result; } + + async generate(_request: GenerationRequest, settings: EffUsernameGenerationOptions) { + if (isEffUsernameGenerationOptions(settings)) { + const username = await this.randomWords({ + digits: settings.wordIncludeNumber ? 1 : 0, + casing: settings.wordCapitalize ? "TitleCase" : "lowercase", + }); + + return new GeneratedCredential(username, "username", Date.now()); + } + + throw new Error("Invalid settings received by generator."); + } +} + +function isEffUsernameGenerationOptions(settings: any): settings is EffUsernameGenerationOptions { + return "wordIncludeNumber" in (settings ?? {}); } diff --git a/libs/tools/generator/core/src/policies/available-algorithms-policy.spec.ts b/libs/tools/generator/core/src/policies/available-algorithms-policy.spec.ts new file mode 100644 index 00000000000..1ef0adc1af4 --- /dev/null +++ b/libs/tools/generator/core/src/policies/available-algorithms-policy.spec.ts @@ -0,0 +1,140 @@ +import { PolicyType } from "@bitwarden/common/admin-console/enums"; +import { Policy } from "@bitwarden/common/admin-console/models/domain/policy"; +import { PolicyId } from "@bitwarden/common/types/guid"; + +import { CredentialAlgorithms, PasswordAlgorithms } from "../data"; + +import { availableAlgorithms } from "./available-algorithms-policy"; + +describe("availableAlgorithmsPolicy", () => { + it("returns all algorithms", () => { + const result = availableAlgorithms([]); + + for (const expected of CredentialAlgorithms) { + expect(result).toContain(expected); + } + }); + + it.each([["password"], ["passphrase"]])("enforces a %p override", (override) => { + const policy = new Policy({ + id: "" as PolicyId, + organizationId: "", + type: PolicyType.PasswordGenerator, + data: { + overridePasswordType: override, + }, + enabled: true, + }); + + const result = availableAlgorithms([policy]); + + expect(result).toContain(override); + + for (const expected of PasswordAlgorithms.filter((a) => a !== override)) { + expect(result).not.toContain(expected); + } + }); + + it.each([["password"], ["passphrase"]])("combines %p overrides", (override) => { + const policy = new Policy({ + id: "" as PolicyId, + organizationId: "", + type: PolicyType.PasswordGenerator, + data: { + overridePasswordType: override, + }, + enabled: true, + }); + + const result = availableAlgorithms([policy, policy]); + + expect(result).toContain(override); + + for (const expected of PasswordAlgorithms.filter((a) => a !== override)) { + expect(result).not.toContain(expected); + } + }); + + it("overrides passphrase policies with password policies", () => { + const password = new Policy({ + id: "" as PolicyId, + organizationId: "", + type: PolicyType.PasswordGenerator, + data: { + overridePasswordType: "password", + }, + enabled: true, + }); + const passphrase = new Policy({ + id: "" as PolicyId, + organizationId: "", + type: PolicyType.PasswordGenerator, + data: { + overridePasswordType: "passphrase", + }, + enabled: true, + }); + + const result = availableAlgorithms([password, passphrase]); + + expect(result).toContain("password"); + + for (const expected of PasswordAlgorithms.filter((a) => a !== "password")) { + expect(result).not.toContain(expected); + } + }); + + it("ignores unrelated policies", () => { + const policy = new Policy({ + id: "" as PolicyId, + organizationId: "", + type: PolicyType.ActivateAutofill, + data: { + some: "policy", + }, + enabled: true, + }); + + const result = availableAlgorithms([policy]); + + for (const expected of CredentialAlgorithms) { + expect(result).toContain(expected); + } + }); + + it("ignores disabled policies", () => { + const policy = new Policy({ + id: "" as PolicyId, + organizationId: "", + type: PolicyType.PasswordGenerator, + data: { + some: "policy", + }, + enabled: false, + }); + + const result = availableAlgorithms([policy]); + + for (const expected of CredentialAlgorithms) { + expect(result).toContain(expected); + } + }); + + it("ignores policies without `overridePasswordType`", () => { + const policy = new Policy({ + id: "" as PolicyId, + organizationId: "", + type: PolicyType.PasswordGenerator, + data: { + some: "policy", + }, + enabled: true, + }); + + const result = availableAlgorithms([policy]); + + for (const expected of CredentialAlgorithms) { + expect(result).toContain(expected); + } + }); +}); diff --git a/libs/tools/generator/core/src/policies/available-algorithms-policy.ts b/libs/tools/generator/core/src/policies/available-algorithms-policy.ts new file mode 100644 index 00000000000..72eea382141 --- /dev/null +++ b/libs/tools/generator/core/src/policies/available-algorithms-policy.ts @@ -0,0 +1,32 @@ +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 { + CredentialAlgorithm, + EmailAlgorithms, + PasswordAlgorithms, + UsernameAlgorithms, +} from "@bitwarden/generator-core"; + +/** Reduces policies to a set of available algorithms + * @param policies the policies to reduce + * @returns the resulting `AlgorithmAvailabilityPolicy` + */ +export function availableAlgorithms(policies: Policy[]): CredentialAlgorithm[] { + const overridePassword = policies + .filter((policy) => policy.type === PolicyType.PasswordGenerator && policy.enabled) + .reduce( + (type, policy) => (type === "password" ? type : (policy.data.overridePasswordType ?? type)), + null as CredentialAlgorithm, + ); + + const policy: CredentialAlgorithm[] = [...EmailAlgorithms, ...UsernameAlgorithms]; + if (overridePassword) { + policy.push(overridePassword); + } else { + policy.push(...PasswordAlgorithms); + } + + return policy; +} diff --git a/libs/tools/generator/core/src/policies/passphrase-generator-options-evaluator.spec.ts b/libs/tools/generator/core/src/policies/passphrase-generator-options-evaluator.spec.ts index 811c4aa822c..688315e9297 100644 --- a/libs/tools/generator/core/src/policies/passphrase-generator-options-evaluator.spec.ts +++ b/libs/tools/generator/core/src/policies/passphrase-generator-options-evaluator.spec.ts @@ -6,7 +6,7 @@ import { PassphraseGeneratorOptionsEvaluator } from "./passphrase-generator-opti describe("Password generator options builder", () => { describe("constructor()", () => { it("should set the policy object to a copy of the input policy", () => { - const policy = Object.assign({}, Policies.Passphrase.disabledValue); + const policy: any = Object.assign({}, Policies.Passphrase.disabledValue); policy.minNumberWords = 10; // arbitrary change for deep equality check const builder = new PassphraseGeneratorOptionsEvaluator(policy); @@ -25,7 +25,7 @@ describe("Password generator options builder", () => { it.each([1, 2])( "should use the default word boundaries when they are greater than `policy.minNumberWords` (= %i)", (minNumberWords) => { - const policy = Object.assign({}, Policies.Passphrase.disabledValue); + const policy: any = Object.assign({}, Policies.Passphrase.disabledValue); policy.minNumberWords = minNumberWords; const builder = new PassphraseGeneratorOptionsEvaluator(policy); @@ -37,7 +37,7 @@ describe("Password generator options builder", () => { it.each([8, 12, 18])( "should use `policy.minNumberWords` (= %i) when it is greater than the default minimum words", (minNumberWords) => { - const policy = Object.assign({}, Policies.Passphrase.disabledValue); + const policy: any = Object.assign({}, Policies.Passphrase.disabledValue); policy.minNumberWords = minNumberWords; const builder = new PassphraseGeneratorOptionsEvaluator(policy); @@ -50,7 +50,7 @@ describe("Password generator options builder", () => { it.each([150, 300, 9000])( "should use `policy.minNumberWords` (= %i) when it is greater than the default boundaries", (minNumberWords) => { - const policy = Object.assign({}, Policies.Passphrase.disabledValue); + const policy: any = Object.assign({}, Policies.Passphrase.disabledValue); policy.minNumberWords = minNumberWords; const builder = new PassphraseGeneratorOptionsEvaluator(policy); @@ -70,7 +70,7 @@ describe("Password generator options builder", () => { }); it("should return true when the policy has a numWords greater than the default boundary", () => { - const policy = Object.assign({}, Policies.Passphrase.disabledValue); + const policy: any = Object.assign({}, Policies.Passphrase.disabledValue); policy.minNumberWords = DefaultPassphraseBoundaries.numWords.min + 1; const builder = new PassphraseGeneratorOptionsEvaluator(policy); @@ -78,7 +78,7 @@ describe("Password generator options builder", () => { }); it("should return true when the policy has capitalize enabled", () => { - const policy = Object.assign({}, Policies.Passphrase.disabledValue); + const policy: any = Object.assign({}, Policies.Passphrase.disabledValue); policy.capitalize = true; const builder = new PassphraseGeneratorOptionsEvaluator(policy); @@ -86,7 +86,7 @@ describe("Password generator options builder", () => { }); it("should return true when the policy has includeNumber enabled", () => { - const policy = Object.assign({}, Policies.Passphrase.disabledValue); + const policy: any = Object.assign({}, Policies.Passphrase.disabledValue); policy.includeNumber = true; const builder = new PassphraseGeneratorOptionsEvaluator(policy); @@ -108,7 +108,7 @@ describe("Password generator options builder", () => { }); it("should set `capitalize` to `true` when the policy overrides it", () => { - const policy = Object.assign({}, Policies.Passphrase.disabledValue); + const policy: any = Object.assign({}, Policies.Passphrase.disabledValue); policy.capitalize = true; const builder = new PassphraseGeneratorOptionsEvaluator(policy); const options = Object.freeze({ capitalize: false }); @@ -129,7 +129,7 @@ describe("Password generator options builder", () => { }); it("should set `includeNumber` to true when the policy overrides it", () => { - const policy = Object.assign({}, Policies.Passphrase.disabledValue); + const policy: any = Object.assign({}, Policies.Passphrase.disabledValue); policy.includeNumber = true; const builder = new PassphraseGeneratorOptionsEvaluator(policy); const options = Object.freeze({ includeNumber: false }); diff --git a/libs/tools/generator/core/src/policies/password-generator-options-evaluator.spec.ts b/libs/tools/generator/core/src/policies/password-generator-options-evaluator.spec.ts index c6cc96dd82c..91334f91f85 100644 --- a/libs/tools/generator/core/src/policies/password-generator-options-evaluator.spec.ts +++ b/libs/tools/generator/core/src/policies/password-generator-options-evaluator.spec.ts @@ -8,7 +8,7 @@ describe("Password generator options builder", () => { describe("constructor()", () => { it("should set the policy object to a copy of the input policy", () => { - const policy = Object.assign({}, Policies.Password.disabledValue); + const policy: any = Object.assign({}, Policies.Password.disabledValue); policy.minLength = 10; // arbitrary change for deep equality check const builder = new PasswordGeneratorOptionsEvaluator(policy); @@ -32,7 +32,7 @@ describe("Password generator options builder", () => { (minLength) => { expect(minLength).toBeLessThan(DefaultPasswordBoundaries.length.min); - const policy = Object.assign({}, Policies.Password.disabledValue); + const policy: any = Object.assign({}, Policies.Password.disabledValue); policy.minLength = minLength; const builder = new PasswordGeneratorOptionsEvaluator(policy); @@ -47,7 +47,7 @@ describe("Password generator options builder", () => { expect(expectedLength).toBeGreaterThan(DefaultPasswordBoundaries.length.min); expect(expectedLength).toBeLessThanOrEqual(DefaultPasswordBoundaries.length.max); - const policy = Object.assign({}, Policies.Password.disabledValue); + const policy: any = Object.assign({}, Policies.Password.disabledValue); policy.minLength = expectedLength; const builder = new PasswordGeneratorOptionsEvaluator(policy); @@ -62,7 +62,7 @@ describe("Password generator options builder", () => { (expectedLength) => { expect(expectedLength).toBeGreaterThan(DefaultPasswordBoundaries.length.max); - const policy = Object.assign({}, Policies.Password.disabledValue); + const policy: any = Object.assign({}, Policies.Password.disabledValue); policy.minLength = expectedLength; const builder = new PasswordGeneratorOptionsEvaluator(policy); @@ -78,7 +78,7 @@ describe("Password generator options builder", () => { expect(expectedMinDigits).toBeGreaterThan(DefaultPasswordBoundaries.minDigits.min); expect(expectedMinDigits).toBeLessThanOrEqual(DefaultPasswordBoundaries.minDigits.max); - const policy = Object.assign({}, Policies.Password.disabledValue); + const policy: any = Object.assign({}, Policies.Password.disabledValue); policy.numberCount = expectedMinDigits; const builder = new PasswordGeneratorOptionsEvaluator(policy); @@ -93,7 +93,7 @@ describe("Password generator options builder", () => { (expectedMinDigits) => { expect(expectedMinDigits).toBeGreaterThan(DefaultPasswordBoundaries.minDigits.max); - const policy = Object.assign({}, Policies.Password.disabledValue); + const policy: any = Object.assign({}, Policies.Password.disabledValue); policy.numberCount = expectedMinDigits; const builder = new PasswordGeneratorOptionsEvaluator(policy); @@ -113,7 +113,7 @@ describe("Password generator options builder", () => { DefaultPasswordBoundaries.minSpecialCharacters.max, ); - const policy = Object.assign({}, Policies.Password.disabledValue); + const policy: any = Object.assign({}, Policies.Password.disabledValue); policy.specialCount = expectedSpecialCharacters; const builder = new PasswordGeneratorOptionsEvaluator(policy); @@ -132,7 +132,7 @@ describe("Password generator options builder", () => { DefaultPasswordBoundaries.minSpecialCharacters.max, ); - const policy = Object.assign({}, Policies.Password.disabledValue); + const policy: any = Object.assign({}, Policies.Password.disabledValue); policy.specialCount = expectedSpecialCharacters; const builder = new PasswordGeneratorOptionsEvaluator(policy); @@ -151,7 +151,7 @@ describe("Password generator options builder", () => { (expectedLength, numberCount, specialCount) => { expect(expectedLength).toBeGreaterThanOrEqual(DefaultPasswordBoundaries.length.min); - const policy = Object.assign({}, Policies.Password.disabledValue); + const policy: any = Object.assign({}, Policies.Password.disabledValue); policy.numberCount = numberCount; policy.specialCount = specialCount; @@ -171,7 +171,7 @@ describe("Password generator options builder", () => { }); it("should return true when the policy has a minlength greater than the default boundary", () => { - const policy = Object.assign({}, Policies.Password.disabledValue); + const policy: any = Object.assign({}, Policies.Password.disabledValue); policy.minLength = DefaultPasswordBoundaries.length.min + 1; const builder = new PasswordGeneratorOptionsEvaluator(policy); @@ -179,7 +179,7 @@ describe("Password generator options builder", () => { }); it("should return true when the policy has a number count greater than the default boundary", () => { - const policy = Object.assign({}, Policies.Password.disabledValue); + const policy: any = Object.assign({}, Policies.Password.disabledValue); policy.numberCount = DefaultPasswordBoundaries.minDigits.min + 1; const builder = new PasswordGeneratorOptionsEvaluator(policy); @@ -187,7 +187,7 @@ describe("Password generator options builder", () => { }); it("should return true when the policy has a special character count greater than the default boundary", () => { - const policy = Object.assign({}, Policies.Password.disabledValue); + const policy: any = Object.assign({}, Policies.Password.disabledValue); policy.specialCount = DefaultPasswordBoundaries.minSpecialCharacters.min + 1; const builder = new PasswordGeneratorOptionsEvaluator(policy); @@ -195,7 +195,7 @@ describe("Password generator options builder", () => { }); it("should return true when the policy has uppercase enabled", () => { - const policy = Object.assign({}, Policies.Password.disabledValue); + const policy: any = Object.assign({}, Policies.Password.disabledValue); policy.useUppercase = true; const builder = new PasswordGeneratorOptionsEvaluator(policy); @@ -203,7 +203,7 @@ describe("Password generator options builder", () => { }); it("should return true when the policy has lowercase enabled", () => { - const policy = Object.assign({}, Policies.Password.disabledValue); + const policy: any = Object.assign({}, Policies.Password.disabledValue); policy.useLowercase = true; const builder = new PasswordGeneratorOptionsEvaluator(policy); @@ -211,7 +211,7 @@ describe("Password generator options builder", () => { }); it("should return true when the policy has numbers enabled", () => { - const policy = Object.assign({}, Policies.Password.disabledValue); + const policy: any = Object.assign({}, Policies.Password.disabledValue); policy.useNumbers = true; const builder = new PasswordGeneratorOptionsEvaluator(policy); @@ -219,7 +219,7 @@ describe("Password generator options builder", () => { }); it("should return true when the policy has special characters enabled", () => { - const policy = Object.assign({}, Policies.Password.disabledValue); + const policy: any = Object.assign({}, Policies.Password.disabledValue); policy.useSpecial = true; const builder = new PasswordGeneratorOptionsEvaluator(policy); @@ -237,7 +237,7 @@ describe("Password generator options builder", () => { ])( "should set `options.uppercase` to '%s' when `policy.useUppercase` is false and `options.uppercase` is '%s'", (expectedUppercase, uppercase) => { - const policy = Object.assign({}, Policies.Password.disabledValue); + const policy: any = Object.assign({}, Policies.Password.disabledValue); policy.useUppercase = false; const builder = new PasswordGeneratorOptionsEvaluator(policy); const options = Object.freeze({ ...defaultOptions, uppercase }); @@ -251,7 +251,7 @@ describe("Password generator options builder", () => { it.each([false, true, undefined])( "should set `options.uppercase` (= %s) to true when `policy.useUppercase` is true", (uppercase) => { - const policy = Object.assign({}, Policies.Password.disabledValue); + const policy: any = Object.assign({}, Policies.Password.disabledValue); policy.useUppercase = true; const builder = new PasswordGeneratorOptionsEvaluator(policy); const options = Object.freeze({ ...defaultOptions, uppercase }); @@ -269,7 +269,7 @@ describe("Password generator options builder", () => { ])( "should set `options.lowercase` to '%s' when `policy.useLowercase` is false and `options.lowercase` is '%s'", (expectedLowercase, lowercase) => { - const policy = Object.assign({}, Policies.Password.disabledValue); + const policy: any = Object.assign({}, Policies.Password.disabledValue); policy.useLowercase = false; const builder = new PasswordGeneratorOptionsEvaluator(policy); const options = Object.freeze({ ...defaultOptions, lowercase }); @@ -283,7 +283,7 @@ describe("Password generator options builder", () => { it.each([false, true, undefined])( "should set `options.lowercase` (= %s) to true when `policy.useLowercase` is true", (lowercase) => { - const policy = Object.assign({}, Policies.Password.disabledValue); + const policy: any = Object.assign({}, Policies.Password.disabledValue); policy.useLowercase = true; const builder = new PasswordGeneratorOptionsEvaluator(policy); const options = Object.freeze({ ...defaultOptions, lowercase }); @@ -301,7 +301,7 @@ describe("Password generator options builder", () => { ])( "should set `options.number` to '%s' when `policy.useNumbers` is false and `options.number` is '%s'", (expectedNumber, number) => { - const policy = Object.assign({}, Policies.Password.disabledValue); + const policy: any = Object.assign({}, Policies.Password.disabledValue); policy.useNumbers = false; const builder = new PasswordGeneratorOptionsEvaluator(policy); const options = Object.freeze({ ...defaultOptions, number }); @@ -315,7 +315,7 @@ describe("Password generator options builder", () => { it.each([false, true, undefined])( "should set `options.number` (= %s) to true when `policy.useNumbers` is true", (number) => { - const policy = Object.assign({}, Policies.Password.disabledValue); + const policy: any = Object.assign({}, Policies.Password.disabledValue); policy.useNumbers = true; const builder = new PasswordGeneratorOptionsEvaluator(policy); const options = Object.freeze({ ...defaultOptions, number }); @@ -333,7 +333,7 @@ describe("Password generator options builder", () => { ])( "should set `options.special` to '%s' when `policy.useSpecial` is false and `options.special` is '%s'", (expectedSpecial, special) => { - const policy = Object.assign({}, Policies.Password.disabledValue); + const policy: any = Object.assign({}, Policies.Password.disabledValue); policy.useSpecial = false; const builder = new PasswordGeneratorOptionsEvaluator(policy); const options = Object.freeze({ ...defaultOptions, special }); @@ -347,7 +347,7 @@ describe("Password generator options builder", () => { it.each([false, true, undefined])( "should set `options.special` (= %s) to true when `policy.useSpecial` is true", (special) => { - const policy = Object.assign({}, Policies.Password.disabledValue); + const policy: any = Object.assign({}, Policies.Password.disabledValue); policy.useSpecial = true; const builder = new PasswordGeneratorOptionsEvaluator(policy); const options = Object.freeze({ ...defaultOptions, special }); @@ -447,7 +447,7 @@ describe("Password generator options builder", () => { it.each([1, 2, 3, 4])( "should set `options.minNumber` (= %i) to the minimum it is less than the minimum number", (minNumber) => { - const policy = Object.assign({}, Policies.Password.disabledValue); + const policy: any = Object.assign({}, Policies.Password.disabledValue); policy.numberCount = 5; // arbitrary value greater than minNumber expect(minNumber).toBeLessThan(policy.numberCount); @@ -534,7 +534,7 @@ describe("Password generator options builder", () => { it.each([1, 2, 3, 4])( "should set `options.minSpecial` (= %i) to the minimum it is less than the minimum special characters", (minSpecial) => { - const policy = Object.assign({}, Policies.Password.disabledValue); + const policy: any = Object.assign({}, Policies.Password.disabledValue); policy.specialCount = 5; // arbitrary value greater than minSpecial expect(minSpecial).toBeLessThan(policy.specialCount); diff --git a/libs/tools/generator/core/src/services/credential-generator.service.spec.ts b/libs/tools/generator/core/src/services/credential-generator.service.spec.ts index 7e249bc135d..88f1447e98d 100644 --- a/libs/tools/generator/core/src/services/credential-generator.service.spec.ts +++ b/libs/tools/generator/core/src/services/credential-generator.service.spec.ts @@ -15,6 +15,7 @@ import { ObservableTracker, } from "../../../../../common/spec"; import { Randomizer } from "../abstractions"; +import { Generators } from "../data"; import { CredentialGeneratorConfiguration, GeneratedCredential, @@ -33,7 +34,7 @@ const SettingsKey = new UserKeyDefinition(GENERATOR_DISK, "SomeSet clearOn: [], }); -// fake policy +// fake policies const policyService = mock(); const somePolicy = new Policy({ data: { fooPolicy: true }, @@ -42,19 +43,43 @@ const somePolicy = new Policy({ organizationId: "" as OrganizationId, enabled: true, }); +const passwordOverridePolicy = new Policy({ + id: "" as PolicyId, + organizationId: "", + type: PolicyType.PasswordGenerator, + data: { + overridePasswordType: "password", + }, + enabled: true, +}); + +const passphraseOverridePolicy = new Policy({ + id: "" as PolicyId, + organizationId: "", + type: PolicyType.PasswordGenerator, + data: { + overridePasswordType: "passphrase", + }, + enabled: true, +}); const SomeTime = new Date(1); -const SomeCategory = "passphrase"; +const SomeAlgorithm = "passphrase"; +const SomeCategory = "password"; +const SomeNameKey = "passphraseKey"; // fake the configuration const SomeConfiguration: CredentialGeneratorConfiguration = { + id: SomeAlgorithm, category: SomeCategory, + nameKey: SomeNameKey, + onlyOnRequest: false, engine: { create: (randomizer) => { return { generate: (request, settings) => { const credential = request.website ? `${request.website}|${settings.foo}` : settings.foo; - const result = new GeneratedCredential(credential, SomeCategory, SomeTime); + const result = new GeneratedCredential(credential, SomeAlgorithm, SomeTime); return Promise.resolve(result); }, }; @@ -114,7 +139,7 @@ const SomeConfiguration: CredentialGeneratorConfiguration { const result = await generated.expectEmission(); - expect(result).toEqual(new GeneratedCredential("value", SomeCategory, SomeTime)); + expect(result).toEqual(new GeneratedCredential("value", SomeAlgorithm, SomeTime)); }); it("follows the active user", async () => { @@ -165,8 +191,8 @@ describe("CredentialGeneratorService", () => { generated.unsubscribe(); expect(generated.emissions).toEqual([ - new GeneratedCredential("some value", SomeCategory, SomeTime), - new GeneratedCredential("another value", SomeCategory, SomeTime), + new GeneratedCredential("some value", SomeAlgorithm, SomeTime), + new GeneratedCredential("another value", SomeAlgorithm, SomeTime), ]); }); @@ -182,8 +208,8 @@ describe("CredentialGeneratorService", () => { generated.unsubscribe(); expect(generated.emissions).toEqual([ - new GeneratedCredential("some value", SomeCategory, SomeTime), - new GeneratedCredential("another value", SomeCategory, SomeTime), + new GeneratedCredential("some value", SomeAlgorithm, SomeTime), + new GeneratedCredential("another value", SomeAlgorithm, SomeTime), ]); }); @@ -200,7 +226,9 @@ describe("CredentialGeneratorService", () => { const result = await generated.expectEmission(); - expect(result).toEqual(new GeneratedCredential("some website|value", SomeCategory, SomeTime)); + expect(result).toEqual( + new GeneratedCredential("some website|value", SomeAlgorithm, SomeTime), + ); }); it("errors when `website$` errors", async () => { @@ -246,7 +274,7 @@ describe("CredentialGeneratorService", () => { const result = await generated.expectEmission(); - expect(result).toEqual(new GeneratedCredential("another", SomeCategory, SomeTime)); + expect(result).toEqual(new GeneratedCredential("another", SomeAlgorithm, SomeTime)); }); it("emits a generation for a specific user when `user$` emits", async () => { @@ -261,8 +289,8 @@ describe("CredentialGeneratorService", () => { const result = await generated.pauseUntilReceived(2); expect(result).toEqual([ - new GeneratedCredential("value", SomeCategory, SomeTime), - new GeneratedCredential("another", SomeCategory, SomeTime), + new GeneratedCredential("value", SomeAlgorithm, SomeTime), + new GeneratedCredential("another", SomeAlgorithm, SomeTime), ]); }); @@ -317,7 +345,7 @@ describe("CredentialGeneratorService", () => { // confirm forwarded emission on$.next(); await awaitAsync(); - expect(results).toEqual([new GeneratedCredential("value", SomeCategory, SomeTime)]); + expect(results).toEqual([new GeneratedCredential("value", SomeAlgorithm, SomeTime)]); // confirm updating settings does not cause an emission await stateProvider.setUserState(SettingsKey, { foo: "next" }, SomeUser); @@ -330,8 +358,8 @@ describe("CredentialGeneratorService", () => { sub.unsubscribe(); expect(results).toEqual([ - new GeneratedCredential("value", SomeCategory, SomeTime), - new GeneratedCredential("next", SomeCategory, SomeTime), + new GeneratedCredential("value", SomeAlgorithm, SomeTime), + new GeneratedCredential("next", SomeAlgorithm, SomeTime), ]); }); @@ -370,6 +398,245 @@ describe("CredentialGeneratorService", () => { expect(complete).toBeTruthy(); }); + + // FIXME: test these when the fake state provider can delay its first emission + it.todo("emits when settings$ become available if on$ is called before they're ready."); + it.todo("emits when website$ become available if on$ is called before they're ready."); + }); + + describe("algorithms", () => { + it("outputs password generation metadata", () => { + const generator = new CredentialGeneratorService(randomizer, stateProvider, policyService); + + const result = generator.algorithms("password"); + + expect(result).toContain(Generators.password); + expect(result).toContain(Generators.passphrase); + + // this test shouldn't contain entries outside of the current category + expect(result).not.toContain(Generators.username); + expect(result).not.toContain(Generators.catchall); + }); + + it("outputs username generation metadata", () => { + const generator = new CredentialGeneratorService(randomizer, stateProvider, policyService); + + const result = generator.algorithms("username"); + + expect(result).toContain(Generators.username); + + // this test shouldn't contain entries outside of the current category + expect(result).not.toContain(Generators.catchall); + expect(result).not.toContain(Generators.password); + }); + + it("outputs email generation metadata", () => { + const generator = new CredentialGeneratorService(randomizer, stateProvider, policyService); + + const result = generator.algorithms("email"); + + expect(result).toContain(Generators.catchall); + expect(result).toContain(Generators.subaddress); + + // this test shouldn't contain entries outside of the current category + expect(result).not.toContain(Generators.username); + expect(result).not.toContain(Generators.password); + }); + + it("combines metadata across categories", () => { + const generator = new CredentialGeneratorService(randomizer, stateProvider, policyService); + + const result = generator.algorithms(["username", "email"]); + + expect(result).toContain(Generators.username); + expect(result).toContain(Generators.catchall); + expect(result).toContain(Generators.subaddress); + + // this test shouldn't contain entries outside of the current categories + expect(result).not.toContain(Generators.password); + }); + }); + + describe("algorithms$", () => { + // these tests cannot use the observable tracker because they return + // data that cannot be cloned + it("returns password metadata", async () => { + const generator = new CredentialGeneratorService(randomizer, stateProvider, policyService); + + const result = await firstValueFrom(generator.algorithms$("password")); + + expect(result).toContain(Generators.password); + expect(result).toContain(Generators.passphrase); + }); + + it("returns username metadata", async () => { + const generator = new CredentialGeneratorService(randomizer, stateProvider, policyService); + + const result = await firstValueFrom(generator.algorithms$("username")); + + expect(result).toContain(Generators.username); + }); + + it("returns email metadata", async () => { + const generator = new CredentialGeneratorService(randomizer, stateProvider, policyService); + + const result = await firstValueFrom(generator.algorithms$("email")); + + expect(result).toContain(Generators.catchall); + expect(result).toContain(Generators.subaddress); + }); + + it("returns username and email metadata", async () => { + const generator = new CredentialGeneratorService(randomizer, stateProvider, policyService); + + const result = await firstValueFrom(generator.algorithms$(["username", "email"])); + + expect(result).toContain(Generators.username); + expect(result).toContain(Generators.catchall); + expect(result).toContain(Generators.subaddress); + }); + + // Subsequent tests focus on passwords and passphrases as an example of policy + // awareness; they exercise the logic without being comprehensive + it("enforces the active user's policy", async () => { + const policy$ = new BehaviorSubject([passwordOverridePolicy]); + policyService.getAll$.mockReturnValue(policy$); + const generator = new CredentialGeneratorService(randomizer, stateProvider, policyService); + + const result = await firstValueFrom(generator.algorithms$(["password"])); + + expect(policyService.getAll$).toHaveBeenCalledWith(PolicyType.PasswordGenerator, SomeUser); + expect(result).toContain(Generators.password); + expect(result).not.toContain(Generators.passphrase); + }); + + it("follows changes to the active user", async () => { + // initialize local account service and state provider because this test is sensitive + // to some shared data in `FakeAccountService`. + const accountService = new FakeAccountService(accounts); + const stateProvider = new FakeStateProvider(accountService); + await accountService.switchAccount(SomeUser); + policyService.getAll$.mockReturnValueOnce(new BehaviorSubject([passwordOverridePolicy])); + policyService.getAll$.mockReturnValueOnce(new BehaviorSubject([passphraseOverridePolicy])); + const generator = new CredentialGeneratorService(randomizer, stateProvider, policyService); + const results: any = []; + const sub = generator.algorithms$("password").subscribe((r) => results.push(r)); + + await accountService.switchAccount(AnotherUser); + await awaitAsync(); + sub.unsubscribe(); + + const [someResult, anotherResult] = results; + + expect(policyService.getAll$).toHaveBeenNthCalledWith( + 1, + PolicyType.PasswordGenerator, + SomeUser, + ); + expect(someResult).toContain(Generators.password); + expect(someResult).not.toContain(Generators.passphrase); + + expect(policyService.getAll$).toHaveBeenNthCalledWith( + 2, + PolicyType.PasswordGenerator, + AnotherUser, + ); + expect(anotherResult).toContain(Generators.passphrase); + expect(anotherResult).not.toContain(Generators.password); + }); + + it("reads an arbitrary user's settings", async () => { + policyService.getAll$.mockReturnValueOnce(new BehaviorSubject([passwordOverridePolicy])); + const generator = new CredentialGeneratorService(randomizer, stateProvider, policyService); + const userId$ = new BehaviorSubject(AnotherUser).asObservable(); + + const result = await firstValueFrom(generator.algorithms$("password", { userId$ })); + + expect(policyService.getAll$).toHaveBeenCalledWith(PolicyType.PasswordGenerator, AnotherUser); + expect(result).toContain(Generators.password); + expect(result).not.toContain(Generators.passphrase); + }); + + it("follows changes to the arbitrary user", async () => { + policyService.getAll$.mockReturnValueOnce(new BehaviorSubject([passwordOverridePolicy])); + policyService.getAll$.mockReturnValueOnce(new BehaviorSubject([passphraseOverridePolicy])); + const generator = new CredentialGeneratorService(randomizer, stateProvider, policyService); + const userId = new BehaviorSubject(SomeUser); + const userId$ = userId.asObservable(); + const results: any = []; + const sub = generator.algorithms$("password", { userId$ }).subscribe((r) => results.push(r)); + + userId.next(AnotherUser); + await awaitAsync(); + sub.unsubscribe(); + + const [someResult, anotherResult] = results; + expect(policyService.getAll$).toHaveBeenCalledWith(PolicyType.PasswordGenerator, SomeUser); + expect(someResult).toContain(Generators.password); + expect(someResult).not.toContain(Generators.passphrase); + + expect(policyService.getAll$).toHaveBeenCalledWith(PolicyType.PasswordGenerator, AnotherUser); + expect(anotherResult).toContain(Generators.passphrase); + expect(anotherResult).not.toContain(Generators.password); + }); + + it("errors when the arbitrary user's stream errors", async () => { + policyService.getAll$.mockReturnValueOnce(new BehaviorSubject([passwordOverridePolicy])); + const generator = new CredentialGeneratorService(randomizer, stateProvider, policyService); + const userId = new BehaviorSubject(SomeUser); + const userId$ = userId.asObservable(); + let error = null; + + generator.algorithms$("password", { userId$ }).subscribe({ + error: (e: unknown) => { + error = e; + }, + }); + userId.error({ some: "error" }); + await awaitAsync(); + + expect(error).toEqual({ some: "error" }); + }); + + it("completes when the arbitrary user's stream completes", async () => { + policyService.getAll$.mockReturnValueOnce(new BehaviorSubject([passwordOverridePolicy])); + const generator = new CredentialGeneratorService(randomizer, stateProvider, policyService); + const userId = new BehaviorSubject(SomeUser); + const userId$ = userId.asObservable(); + let completed = false; + + generator.algorithms$("password", { userId$ }).subscribe({ + complete: () => { + completed = true; + }, + }); + userId.complete(); + await awaitAsync(); + + expect(completed).toBeTruthy(); + }); + + it("ignores repeated arbitrary user emissions", async () => { + policyService.getAll$.mockReturnValueOnce(new BehaviorSubject([passwordOverridePolicy])); + const generator = new CredentialGeneratorService(randomizer, stateProvider, policyService); + const userId = new BehaviorSubject(SomeUser); + const userId$ = userId.asObservable(); + let count = 0; + + const sub = generator.algorithms$("password", { userId$ }).subscribe({ + next: () => { + count++; + }, + }); + await awaitAsync(); + userId.next(SomeUser); + await awaitAsync(); + userId.next(SomeUser); + await awaitAsync(); + sub.unsubscribe(); + + expect(count).toEqual(1); + }); }); describe("settings$", () => { @@ -405,6 +672,11 @@ describe("CredentialGeneratorService", () => { }); it("follows changes to the active user", async () => { + // initialize local accound service and state provider because this test is sensitive + // to some shared data in `FakeAccountService`. + const accountService = new FakeAccountService(accounts); + const stateProvider = new FakeStateProvider(accountService); + await accountService.switchAccount(SomeUser); const someSettings = { foo: "value" }; const anotherSettings = { foo: "another" }; await stateProvider.setUserState(SettingsKey, someSettings, SomeUser); diff --git a/libs/tools/generator/core/src/services/credential-generator.service.ts b/libs/tools/generator/core/src/services/credential-generator.service.ts index dc6b8619407..693ffd654dc 100644 --- a/libs/tools/generator/core/src/services/credential-generator.service.ts +++ b/libs/tools/generator/core/src/services/credential-generator.service.ts @@ -1,16 +1,19 @@ import { BehaviorSubject, combineLatest, + concat, concatMap, distinctUntilChanged, endWith, filter, + first, firstValueFrom, ignoreElements, map, - mergeMap, Observable, race, + share, + skipUntil, switchMap, takeUntil, withLatestFrom, @@ -18,6 +21,7 @@ import { import { Simplify } from "type-fest"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; +import { PolicyType } from "@bitwarden/common/admin-console/enums"; import { StateProvider } from "@bitwarden/common/platform/state"; import { OnDependency, @@ -28,10 +32,21 @@ import { isDynamic } from "@bitwarden/common/tools/state/state-constraints-depen import { UserStateSubject } from "@bitwarden/common/tools/state/user-state-subject"; import { Randomizer } from "../abstractions"; +import { Generators } from "../data"; +import { availableAlgorithms } from "../policies/available-algorithms-policy"; import { mapPolicyToConstraints } from "../rx"; +import { + CredentialAlgorithm, + CredentialCategories, + CredentialCategory, + CredentialGeneratorInfo, + CredentialPreference, +} from "../types"; import { CredentialGeneratorConfiguration as Configuration } from "../types/credential-generator-configuration"; import { GeneratorConstraints } from "../types/generator-constraints"; +import { PREFERENCES } from "./credential-preferences"; + type Policy$Dependencies = UserDependency; type Settings$Dependencies = Partial; type Generate$Dependencies = Simplify & Partial> & { @@ -46,6 +61,8 @@ type Generate$Dependencies = Simplify & Partial; }; +type Algorithms$Dependencies = Partial; + export class CredentialGeneratorService { constructor( private randomizer: Randomizer, @@ -53,6 +70,9 @@ export class CredentialGeneratorService { private policyService: PolicyService, ) {} + // FIXME: the rxjs methods of this service can be a lot more resilient if + // `Subjects` are introduced where sharing occurs + /** Generates a stream of credentials * @param configuration determines which generator's settings are loaded * @param dependencies.on$ when specified, a new credential is emitted when @@ -76,8 +96,24 @@ export class CredentialGeneratorService { const settingsComplete$ = request$.pipe(ignoreElements(), endWith(true)); const complete$ = race(requestComplete$, settingsComplete$); + // if on$ triggers before settings are loaded, trigger as soon + // as they become available. + let readyOn$: Observable = null; + if (dependencies?.on$) { + const NO_EMISSIONS = {}; + const ready$ = combineLatest([settings$, request$]).pipe( + first(null, NO_EMISSIONS), + filter((value) => value !== NO_EMISSIONS), + share(), + ); + readyOn$ = concat( + dependencies.on$?.pipe(switchMap(() => ready$)), + dependencies.on$.pipe(skipUntil(ready$)), + ); + } + // generation proper - const generate$ = (dependencies?.on$ ?? settings$).pipe( + const generate$ = (readyOn$ ?? settings$).pipe( withLatestFrom(request$, settings$), concatMap(([, request, settings]) => engine.generate(request, settings)), takeUntil(complete$), @@ -86,6 +122,79 @@ export class CredentialGeneratorService { return generate$; } + /** Emits metadata concerning the provided generation algorithms + * @param category the category or categories of interest + * @param dependences.userId$ when provided, the algorithms are filter to only + * those matching the provided user's policy. Otherwise, emits the algorithms + * available to the active user. + * @returns An observable that emits algorithm metadata. + */ + algorithms$( + category: CredentialCategory, + dependencies?: Algorithms$Dependencies, + ): Observable; + algorithms$( + category: CredentialCategory[], + dependencies?: Algorithms$Dependencies, + ): Observable; + algorithms$( + category: CredentialCategory | CredentialCategory[], + dependencies?: Algorithms$Dependencies, + ) { + // any cast required here because TypeScript fails to bind `category` + // to the union-typed overload of `algorithms`. + const algorithms = this.algorithms(category as any); + + // fall back to default bindings + const userId$ = dependencies?.userId$ ?? this.stateProvider.activeUserId$; + + // monitor completion + const completion$ = userId$.pipe(ignoreElements(), endWith(true)); + + // apply policy + const algorithms$ = userId$.pipe( + distinctUntilChanged(), + switchMap((userId) => { + // complete policy emissions otherwise `switchMap` holds `algorithms$` open indefinitely + const policies$ = this.policyService.getAll$(PolicyType.PasswordGenerator, userId).pipe( + map((p) => new Set(availableAlgorithms(p))), + takeUntil(completion$), + ); + return policies$; + }), + map((available) => { + const filtered = algorithms.filter((c) => available.has(c.id)); + return filtered; + }), + ); + + return algorithms$; + } + + /** Lists metadata for the algorithms in a credential category + * @param category the category or categories of interest + * @returns A list containing the requested metadata. + */ + algorithms(category: CredentialCategory): CredentialGeneratorInfo[]; + algorithms(category: CredentialCategory[]): CredentialGeneratorInfo[]; + algorithms(category: CredentialCategory | CredentialCategory[]): CredentialGeneratorInfo[] { + const categories = Array.isArray(category) ? category : [category]; + const algorithms = categories + .flatMap((c) => CredentialCategories[c]) + .map((c) => (c === "forwarder" ? null : Generators[c])) + .filter((info) => info !== null); + + return algorithms; + } + + /** Look up the metadata for a specific generator algorithm + * @param id identifies the algorithm + * @returns the requested metadata, or `null` if the metadata wasn't found. + */ + algorithm(id: CredentialAlgorithm): CredentialGeneratorInfo { + return (id === "forwarder" ? null : Generators[id]) ?? null; + } + /** Get the settings for the provided configuration * @param configuration determines which generator's settings are loaded * @param dependencies.userId$ identifies the user to which the settings are bound. @@ -125,6 +234,29 @@ export class CredentialGeneratorService { return settings$; } + /** Get a subject bound to credential generator preferences. + * @param dependencies.singleUserId$ identifies the user to which the preferences are bound + * @returns a promise that resolves with the subject once `dependencies.singleUserId$` + * becomes available. + * @remarks Preferences determine which algorithms are used when generating a + * credential from a credential category (e.g. `PassX` or `Username`). Preferences + * should not be used to hold navigation history. Use @bitwarden/generator-navigation + * instead. + */ + async preferences( + dependencies: SingleUserDependency, + ): Promise> { + const userId = await firstValueFrom( + dependencies.singleUserId$.pipe(filter((userId) => !!userId)), + ); + + // FIXME: enforce policy + const state = this.stateProvider.getUser(userId, PREFERENCES); + const subject = new UserStateSubject(state, { ...dependencies }); + + return subject; + } + /** Get a subject bound to a specific user's settings * @param configuration determines which generator's settings are loaded * @param dependencies.singleUserId$ identifies the user to which the settings are bound @@ -159,7 +291,7 @@ export class CredentialGeneratorService { const completion$ = dependencies.userId$.pipe(ignoreElements(), endWith(true)); const constraints$ = dependencies.userId$.pipe( - mergeMap((userId) => { + switchMap((userId) => { // complete policy emissions otherwise `mergeMap` holds `policies$` open indefinitely const policies$ = this.policyService .getAll$(configuration.policy.type, userId) diff --git a/libs/tools/generator/core/src/services/credential-preferences.spec.ts b/libs/tools/generator/core/src/services/credential-preferences.spec.ts new file mode 100644 index 00000000000..fc7c3e1bbc6 --- /dev/null +++ b/libs/tools/generator/core/src/services/credential-preferences.spec.ts @@ -0,0 +1,53 @@ +import { DefaultCredentialPreferences } from "../data"; + +import { PREFERENCES } from "./credential-preferences"; + +describe("PREFERENCES", () => { + describe("deserializer", () => { + it.each([[null], [undefined]])("creates new preferences (= %p)", (value) => { + const result = PREFERENCES.deserializer(value); + + expect(result).toEqual(DefaultCredentialPreferences); + }); + + it("fills missing password preferences", () => { + const input = { ...DefaultCredentialPreferences }; + delete input.password; + + const result = PREFERENCES.deserializer(input as any); + + expect(result).toEqual(DefaultCredentialPreferences); + }); + + it("fills missing email preferences", () => { + const input = { ...DefaultCredentialPreferences }; + delete input.email; + + const result = PREFERENCES.deserializer(input as any); + + expect(result).toEqual(DefaultCredentialPreferences); + }); + + it("fills missing username preferences", () => { + const input = { ...DefaultCredentialPreferences }; + delete input.username; + + const result = PREFERENCES.deserializer(input as any); + + expect(result).toEqual(DefaultCredentialPreferences); + }); + + it("converts updated fields to Dates", () => { + const input = structuredClone(DefaultCredentialPreferences); + input.email.updated = "1970-01-01T00:00:00.100Z" as any; + input.password.updated = "1970-01-01T00:00:00.200Z" as any; + input.username.updated = "1970-01-01T00:00:00.300Z" as any; + + const result = PREFERENCES.deserializer(input as any); + + expect(result.email.updated).toEqual(new Date(100)); + expect(result.password.updated).toEqual(new Date(200)); + expect(result.username.updated).toEqual(new Date(300)); + }); + }); +}); diff --git a/libs/tools/generator/core/src/services/credential-preferences.ts b/libs/tools/generator/core/src/services/credential-preferences.ts new file mode 100644 index 00000000000..3f6a6c1e1bd --- /dev/null +++ b/libs/tools/generator/core/src/services/credential-preferences.ts @@ -0,0 +1,30 @@ +import { GENERATOR_DISK, UserKeyDefinition } from "@bitwarden/common/platform/state"; + +import { DefaultCredentialPreferences } from "../data"; +import { CredentialPreference } from "../types"; + +/** plaintext password generation options */ +export const PREFERENCES = new UserKeyDefinition( + GENERATOR_DISK, + "credentialPreferences", + { + deserializer: (value) => { + const result = (value as any) ?? {}; + + for (const key in DefaultCredentialPreferences) { + // bind `key` to `category` to transmute the type + const category: keyof typeof DefaultCredentialPreferences = key as any; + + const preference = result[category] ?? { ...DefaultCredentialPreferences[category] }; + if (typeof preference.updated === "string") { + preference.updated = new Date(preference.updated); + } + + result[category] = preference; + } + + return result; + }, + clearOn: ["logout"], + }, +); diff --git a/libs/tools/generator/core/src/types/credential-category.ts b/libs/tools/generator/core/src/types/credential-category.ts deleted file mode 100644 index 54c8c5ed8e9..00000000000 --- a/libs/tools/generator/core/src/types/credential-category.ts +++ /dev/null @@ -1,5 +0,0 @@ -/** Kinds of credentials that can be stored by the history service - * password - a secret consisting of arbitrary characters used to authenticate a user - * passphrase - a secret consisting of words used to authenticate a user - */ -export type CredentialCategory = "password" | "passphrase"; diff --git a/libs/tools/generator/core/src/types/credential-generator-configuration.ts b/libs/tools/generator/core/src/types/credential-generator-configuration.ts index 80d977a73c8..8302450d443 100644 --- a/libs/tools/generator/core/src/types/credential-generator-configuration.ts +++ b/libs/tools/generator/core/src/types/credential-generator-configuration.ts @@ -2,16 +2,35 @@ import { UserKeyDefinition } from "@bitwarden/common/platform/state"; import { Constraints } from "@bitwarden/common/tools/types"; import { Randomizer } from "../abstractions"; -import { PolicyConfiguration } from "../types"; +import { CredentialAlgorithm, CredentialCategory, PolicyConfiguration } from "../types"; -import { CredentialCategory } from "./credential-category"; import { CredentialGenerator } from "./credential-generator"; -export type CredentialGeneratorConfiguration = { - /** Category describing usage of the credential generated by this configuration +/** Credential generator metadata common across credential generators */ +export type CredentialGeneratorInfo = { + /** Uniquely identifies the credential configuration */ + id: CredentialAlgorithm; + + /** The kind of credential generated by this configuration */ category: CredentialCategory; + /** Key used to localize the credential name in the I18nService */ + nameKey: string; + + /** Key used to localize the credential description in the I18nService */ + descriptionKey?: string; + + /** When true, credential generation must be explicitly requested. + * @remarks this property is useful when credential generation + * carries side effects, such as configuring a service external + * to Bitwarden. + */ + onlyOnRequest: boolean; +}; + +/** Credential generator metadata that relies upon typed setting and policy definitions. */ +export type CredentialGeneratorConfiguration = CredentialGeneratorInfo & { /** An algorithm that generates credentials when ran. */ engine: { /** Factory for the generator @@ -28,6 +47,7 @@ export type CredentialGeneratorConfiguration = { /** value used when an account's settings haven't been initialized */ initial: Readonly>; + /** Application-global constraints that apply to account settings */ constraints: Constraints; /** storage location for account-global settings */ diff --git a/libs/tools/generator/core/src/types/generated-credential.spec.ts b/libs/tools/generator/core/src/types/generated-credential.spec.ts index a687676576b..6a498282fe3 100644 --- a/libs/tools/generator/core/src/types/generated-credential.spec.ts +++ b/libs/tools/generator/core/src/types/generated-credential.spec.ts @@ -1,4 +1,4 @@ -import { CredentialCategory, GeneratedCredential } from "."; +import { CredentialAlgorithm, GeneratedCredential } from "."; describe("GeneratedCredential", () => { describe("constructor", () => { @@ -34,7 +34,7 @@ describe("GeneratedCredential", () => { expect(result).toEqual({ credential: "example", - category: "password" as CredentialCategory, + category: "password" as CredentialAlgorithm, generationDate: 100, }); }); @@ -42,7 +42,7 @@ describe("GeneratedCredential", () => { it("fromJSON converts Json objects into credentials", () => { const jsonValue = { credential: "example", - category: "password" as CredentialCategory, + category: "password" as CredentialAlgorithm, generationDate: 100, }; diff --git a/libs/tools/generator/core/src/types/generated-credential.ts b/libs/tools/generator/core/src/types/generated-credential.ts index ff174b04a58..6d18a1c7892 100644 --- a/libs/tools/generator/core/src/types/generated-credential.ts +++ b/libs/tools/generator/core/src/types/generated-credential.ts @@ -1,6 +1,6 @@ import { Jsonify } from "type-fest"; -import { CredentialCategory } from "./credential-category"; +import { CredentialAlgorithm } from "./generator-type"; /** A credential generation result */ export class GeneratedCredential { @@ -14,7 +14,7 @@ export class GeneratedCredential { */ constructor( readonly credential: string, - readonly category: CredentialCategory, + readonly category: CredentialAlgorithm, generationDate: Date | number, ) { if (typeof generationDate === "number") { diff --git a/libs/tools/generator/core/src/types/generator-type.ts b/libs/tools/generator/core/src/types/generator-type.ts index 717b0e994e1..59727fb98f2 100644 --- a/libs/tools/generator/core/src/types/generator-type.ts +++ b/libs/tools/generator/core/src/types/generator-type.ts @@ -1,7 +1,56 @@ -import { GeneratorTypes, PasswordTypes } from "../data/generator-types"; +import { EmailAlgorithms, PasswordAlgorithms, UsernameAlgorithms } from "../data/generator-types"; -/** The kind of credential being generated. */ -export type GeneratorType = (typeof GeneratorTypes)[number]; +/** A type of password that may be generated by the credential generator. */ +export type PasswordAlgorithm = (typeof PasswordAlgorithms)[number]; -/** The kinds of passwords that can be generated. */ -export type PasswordType = (typeof PasswordTypes)[number]; +/** A type of username that may be generated by the credential generator. */ +export type UsernameAlgorithm = (typeof UsernameAlgorithms)[number]; + +/** A type of email address that may be generated by the credential generator. */ +export type EmailAlgorithm = (typeof EmailAlgorithms)[number]; + +/** A type of credential that may be generated by the credential generator. */ +export type CredentialAlgorithm = PasswordAlgorithm | UsernameAlgorithm | EmailAlgorithm; + +/** Compound credential types supported by the credential generator. */ +export const CredentialCategories = Object.freeze({ + /** Lists algorithms in the "password" credential category */ + password: PasswordAlgorithms as Readonly, + + /** Lists algorithms in the "username" credential category */ + username: UsernameAlgorithms as Readonly, + + /** Lists algorithms in the "email" credential category */ + email: EmailAlgorithms as Readonly, +}); + +/** Returns true when the input algorithm is a password algorithm. */ +export function isPasswordAlgorithm( + algorithm: CredentialAlgorithm, +): algorithm is PasswordAlgorithm { + return PasswordAlgorithms.includes(algorithm as any); +} + +/** Returns true when the input algorithm is a username algorithm. */ +export function isUsernameAlgorithm( + algorithm: CredentialAlgorithm, +): algorithm is UsernameAlgorithm { + return UsernameAlgorithms.includes(algorithm as any); +} + +/** Returns true when the input algorithm is an email algorithm. */ +export function isEmailAlgorithm(algorithm: CredentialAlgorithm): algorithm is EmailAlgorithm { + return EmailAlgorithms.includes(algorithm as any); +} + +/** A type of compound credential that may be generated by the credential generator. */ +export type CredentialCategory = keyof typeof CredentialCategories; + +/** The kind of credential to generate using a compound configuration. */ +// FIXME: extend the preferences to include a preferred forwarder +export type CredentialPreference = { + [Key in CredentialCategory]: { + algorithm: (typeof CredentialCategories)[Key][number]; + updated: Date; + }; +}; diff --git a/libs/tools/generator/core/src/types/index.ts b/libs/tools/generator/core/src/types/index.ts index 4f74c487f23..884d9760078 100644 --- a/libs/tools/generator/core/src/types/index.ts +++ b/libs/tools/generator/core/src/types/index.ts @@ -1,6 +1,7 @@ +import { CredentialAlgorithm, PasswordAlgorithm } from "./generator-type"; + export * from "./boundary"; export * from "./catchall-generator-options"; -export * from "./credential-category"; export * from "./credential-generator"; export * from "./credential-generator-configuration"; export * from "./eff-username-generator-options"; @@ -17,3 +18,13 @@ export * from "./password-generator-policy"; export * from "./policy-configuration"; export * from "./subaddress-generator-options"; export * from "./word-options"; + +/** Provided for backwards compatibility only. + * @deprecated Use one of the Algorithm types instead. + */ +export type GeneratorType = CredentialAlgorithm; + +/** Provided for backwards compatibility only. + * @deprecated Use one of the Algorithm types instead. + */ +export type PasswordType = PasswordAlgorithm; diff --git a/libs/tools/generator/extensions/navigation/src/generator-navigation-evaluator.ts b/libs/tools/generator/extensions/navigation/src/generator-navigation-evaluator.ts index 75871e056c4..51049fa56b9 100644 --- a/libs/tools/generator/extensions/navigation/src/generator-navigation-evaluator.ts +++ b/libs/tools/generator/extensions/navigation/src/generator-navigation-evaluator.ts @@ -1,4 +1,4 @@ -import { PasswordTypes, PolicyEvaluator } from "@bitwarden/generator-core"; +import { PasswordAlgorithms, PolicyEvaluator } from "@bitwarden/generator-core"; import { DefaultGeneratorNavigation } from "./default-generator-navigation"; import { GeneratorNavigation } from "./generator-navigation"; @@ -17,7 +17,7 @@ export class GeneratorNavigationEvaluator /** {@link PolicyEvaluator.policyInEffect} */ get policyInEffect(): boolean { - return PasswordTypes.includes(this.policy?.overridePasswordType); + return PasswordAlgorithms.includes(this.policy?.overridePasswordType); } /** Apply policy to the input options. diff --git a/libs/tools/send/send-ui/src/send-form/components/options/send-options.component.html b/libs/tools/send/send-ui/src/send-form/components/options/send-options.component.html index 01b96e3bc5a..dbd86d7f5b7 100644 --- a/libs/tools/send/send-ui/src/send-form/components/options/send-options.component.html +++ b/libs/tools/send/send-ui/src/send-form/components/options/send-options.component.html @@ -27,8 +27,18 @@ bitIconButton="bwi-generate" bitSuffix [appA11yTitle]="'generatePassword' | i18n" + (click)="generatePassword()" data-testid="generate-password" > + {{ "sendPasswordDescV2" | i18n }} diff --git a/libs/tools/send/send-ui/src/send-form/components/options/send-options.component.ts b/libs/tools/send/send-ui/src/send-form/components/options/send-options.component.ts index a73a3a6ad88..2261ca7e1fa 100644 --- a/libs/tools/send/send-ui/src/send-form/components/options/send-options.component.ts +++ b/libs/tools/send/send-ui/src/send-form/components/options/send-options.component.ts @@ -2,7 +2,7 @@ import { CommonModule } from "@angular/common"; import { Component, Input, OnInit } from "@angular/core"; import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; import { FormBuilder, ReactiveFormsModule } from "@angular/forms"; -import { map } from "rxjs"; +import { firstValueFrom, map } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; @@ -17,6 +17,7 @@ import { SectionHeaderComponent, TypographyModule, } from "@bitwarden/components"; +import { CredentialGeneratorService, Generators } from "@bitwarden/generator-core"; import { SendFormConfig } from "../../abstractions/send-form-config.service"; import { SendFormContainer } from "../../send-form-container"; @@ -72,6 +73,7 @@ export class SendOptionsComponent implements OnInit { private sendFormContainer: SendFormContainer, private formBuilder: FormBuilder, private policyService: PolicyService, + private generatorService: CredentialGeneratorService, ) { this.sendFormContainer.registerChildForm("sendOptionsForm", this.sendOptionsForm); this.policyService @@ -98,6 +100,16 @@ export class SendOptionsComponent implements OnInit { }); } + generatePassword = async () => { + const generatedCredential = await firstValueFrom( + this.generatorService.generate$(Generators.password), + ); + + this.sendOptionsForm.patchValue({ + password: generatedCredential.credential, + }); + }; + ngOnInit() { if (this.sendFormContainer.originalSendView) { this.sendOptionsForm.patchValue({ diff --git a/libs/tools/send/send-ui/src/send-form/send-form.module.ts b/libs/tools/send/send-ui/src/send-form/send-form.module.ts index 8b004207c1b..99db65807ac 100644 --- a/libs/tools/send/send-ui/src/send-form/send-form.module.ts +++ b/libs/tools/send/send-ui/src/send-form/send-form.module.ts @@ -1,9 +1,22 @@ import { NgModule } from "@angular/core"; +import { safeProvider } from "@bitwarden/angular/platform/utils/safe-provider"; +import { SafeInjectionToken } from "@bitwarden/angular/services/injection-tokens"; +import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; +import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; +import { StateProvider } from "@bitwarden/common/platform/state"; +import { + createRandomizer, + CredentialGeneratorService, + Randomizer, +} from "@bitwarden/generator-core"; + import { SendFormService } from "./abstractions/send-form.service"; import { SendFormComponent } from "./components/send-form.component"; import { DefaultSendFormService } from "./services/default-send-form.service"; +const RANDOMIZER = new SafeInjectionToken("Randomizer"); + @NgModule({ imports: [SendFormComponent], providers: [ @@ -11,6 +24,16 @@ import { DefaultSendFormService } from "./services/default-send-form.service"; provide: SendFormService, useClass: DefaultSendFormService, }, + safeProvider({ + provide: RANDOMIZER, + useFactory: createRandomizer, + deps: [CryptoService], + }), + safeProvider({ + useClass: CredentialGeneratorService, + provide: CredentialGeneratorService, + deps: [RANDOMIZER, StateProvider, PolicyService], + }), ], exports: [SendFormComponent], }) diff --git a/libs/tools/send/send-ui/src/services/send-items.service.spec.ts b/libs/tools/send/send-ui/src/services/send-items.service.spec.ts index 92a48df40a1..7a7c86df922 100644 --- a/libs/tools/send/send-ui/src/services/send-items.service.spec.ts +++ b/libs/tools/send/send-ui/src/services/send-items.service.spec.ts @@ -62,9 +62,15 @@ describe("SendItemsService", () => { it("should update loading$ when sends are loading", (done) => { const sendsLoading$ = new Subject(); (service as any)._sendsLoading$ = sendsLoading$; + let sendLoadingIndex = 0; service.loading$.subscribe((loading) => { - expect(loading).toBe(true); - done(); + if (sendLoadingIndex === 0) { + expect(loading).toBe(true); + sendLoadingIndex++; + } else { + expect(loading).toBe(false); + done(); + } }); sendsLoading$.next(); diff --git a/libs/tools/send/send-ui/src/services/send-items.service.ts b/libs/tools/send/send-ui/src/services/send-items.service.ts index 107749b1e63..66ad5b67864 100644 --- a/libs/tools/send/send-ui/src/services/send-items.service.ts +++ b/libs/tools/send/send-ui/src/services/send-items.service.ts @@ -5,6 +5,7 @@ import { distinctUntilChanged, from, map, + merge, Observable, shareReplay, startWith, @@ -47,7 +48,9 @@ export class SendItemsService { this._searchText$, this.sendListFiltersService.filterFunction$, ]).pipe( - tap(() => this._sendsLoading$.next()), + tap(() => { + this._sendsLoading$.next(); + }), map(([sends, searchText, filterFunction]): [SendView[], string] => [ filterFunction(sends), searchText, @@ -60,9 +63,10 @@ export class SendItemsService { /** * Observable that indicates whether the service is currently loading sends. */ - loading$: Observable = this._sendsLoading$ - .pipe(map(() => true)) - .pipe(startWith(true), distinctUntilChanged(), shareReplay({ refCount: false, bufferSize: 1 })); + loading$: Observable = merge( + this._sendsLoading$.pipe(map(() => true)), + this.filteredAndSortedSends$.pipe(map(() => false)), + ).pipe(startWith(true), distinctUntilChanged(), shareReplay({ refCount: false, bufferSize: 1 })); /** * Observable that indicates whether a filter is currently applied to the sends. diff --git a/package-lock.json b/package-lock.json index 97dee9ef983..39cfb49a545 100644 --- a/package-lock.json +++ b/package-lock.json @@ -358,14 +358,14 @@ } }, "node_modules/@angular-devkit/architect": { - "version": "0.1802.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.2.tgz", - "integrity": "sha512-LPRl9jhcf0NgshaL6RoUy1uL/cAyNt7oxctoZ9EHUu8eh5E9W/jZGhVowjOLpirwqYhmEzKJJIeS49Ssqs3RQg==", + "version": "0.1802.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.5.tgz", + "integrity": "sha512-c7sVoW85Yqj7IYvNKxtNSGS5I7gWpORorg/xxLZX3OkHWXDrwYbb5LN/2p5/Aytxyb0aXl4o5fFOu6CUwcaLUw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@angular-devkit/core": "18.2.2", + "@angular-devkit/core": "18.2.5", "rxjs": "7.8.1" }, "engines": { @@ -1439,9 +1439,9 @@ } }, "node_modules/@angular-devkit/core": { - "version": "18.2.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.2.tgz", - "integrity": "sha512-Zz0tGptI/QQnUBDdp+1G5wGwQWMjpfe2oO+UohkrDVgFS71yVj4VDnOy51kMTxBvzw+36evTgthPpmzqPIfxBw==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.5.tgz", + "integrity": "sha512-r9TumPlJ8PvA2+yz4sp+bUHgtznaVKzhvXTN5qL1k4YP8LJ7iZWMR2FOP+HjukHZOTsenzmV9pszbogabqwoZQ==", "dev": true, "license": "MIT", "peer": true, @@ -5027,12 +5027,13 @@ } }, "node_modules/@electron/asar": { - "version": "3.2.10", - "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.2.10.tgz", - "integrity": "sha512-mvBSwIBUeiRscrCeJE1LwctAriBj65eUDm0Pc11iE5gRwzkmsdbS7FnZ1XUWjpSeQWL1L5g12Fc/SchPM9DUOw==", + "version": "3.2.13", + "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.2.13.tgz", + "integrity": "sha512-pY5z2qQSwbFzJsBdgfJIzXf5ElHTVMutC2dxh0FD60njknMu3n1NnTABOcQwbb5/v5soqE79m9UjaJryBf3epg==", "dev": true, "license": "MIT", "dependencies": { + "@types/glob": "^7.1.0", "commander": "^5.0.0", "glob": "^7.1.6", "minimatch": "^3.0.4" @@ -5374,57 +5375,6 @@ "node": "*" } }, - "node_modules/@esbuild/android-arm": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.17.tgz", - "integrity": "sha512-wHsmJG/dnL3OkpAcwbgoBTTMHVi4Uyou3F5mf58ZtmUyIKfcdA7TROav/6tCzET4A3QW2Q2FC+eFneMU+iyOxg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.17.tgz", - "integrity": "sha512-9np+YYdNDed5+Jgr1TdWBsozZ85U1Oa3xW0c7TWqH0y2aGghXtZsuT8nYRbzOMcl0bXZXjOGbksoTtVOlWrRZg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.17.tgz", - "integrity": "sha512-O+FeWB/+xya0aLg23hHEM2E3hbfwZzjqumKMSIqcHbNvDa+dza2D0yLuymRBQQnC34CWrsJUXyH2MG5VnLd6uw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@esbuild/darwin-arm64": { "version": "0.18.17", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.17.tgz", @@ -5442,312 +5392,6 @@ "node": ">=12" } }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.17.tgz", - "integrity": "sha512-XDre+J5YeIJDMfp3n0279DFNrGCXlxOuGsWIkRb1NThMZ0BsrWXoTg23Jer7fEXQ9Ye5QjrvXpxnhzl3bHtk0g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.17.tgz", - "integrity": "sha512-cjTzGa3QlNfERa0+ptykyxs5A6FEUQQF0MuilYXYBGdBxD3vxJcKnzDlhDCa1VAJCmAxed6mYhA2KaJIbtiNuQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.17.tgz", - "integrity": "sha512-sOxEvR8d7V7Kw8QqzxWc7bFfnWnGdaFBut1dRUYtu+EIRXefBc/eIsiUiShnW0hM3FmQ5Zf27suDuHsKgZ5QrA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.17.tgz", - "integrity": "sha512-2d3Lw6wkwgSLC2fIvXKoMNGVaeY8qdN0IC3rfuVxJp89CRfA3e3VqWifGDfuakPmp90+ZirmTfye1n4ncjv2lg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.17.tgz", - "integrity": "sha512-c9w3tE7qA3CYWjT+M3BMbwMt+0JYOp3vCMKgVBrCl1nwjAlOMYzEo+gG7QaZ9AtqZFj5MbUc885wuBBmu6aADQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.17.tgz", - "integrity": "sha512-1DS9F966pn5pPnqXYz16dQqWIB0dmDfAQZd6jSSpiT9eX1NzKh07J6VKR3AoXXXEk6CqZMojiVDSZi1SlmKVdg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.17.tgz", - "integrity": "sha512-EvLsxCk6ZF0fpCB6w6eOI2Fc8KW5N6sHlIovNe8uOFObL2O+Mr0bflPHyHwLT6rwMg9r77WOAWb2FqCQrVnwFg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.17.tgz", - "integrity": "sha512-e0bIdHA5p6l+lwqTE36NAW5hHtw2tNRmHlGBygZC14QObsA3bD4C6sXLJjvnDIjSKhW1/0S3eDy+QmX/uZWEYQ==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.17.tgz", - "integrity": "sha512-BAAilJ0M5O2uMxHYGjFKn4nJKF6fNCdP1E0o5t5fvMYYzeIqy2JdAP88Az5LHt9qBoUa4tDaRpfWt21ep5/WqQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.17.tgz", - "integrity": "sha512-Wh/HW2MPnC3b8BqRSIme/9Zhab36PPH+3zam5pqGRH4pE+4xTrVLx2+XdGp6fVS3L2x+DrsIcsbMleex8fbE6g==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.17.tgz", - "integrity": "sha512-j/34jAl3ul3PNcK3pfI0NSlBANduT2UO5kZ7FCaK33XFv3chDhICLY8wJJWIhiQ+YNdQ9dxqQctRg2bvrMlYgg==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.17.tgz", - "integrity": "sha512-QM50vJ/y+8I60qEmFxMoxIx4de03pGo2HwxdBeFd4nMh364X6TIBZ6VQ5UQmPbQWUVWHWws5MmJXlHAXvJEmpQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.17.tgz", - "integrity": "sha512-/jGlhWR7Sj9JPZHzXyyMZ1RFMkNPjC6QIAan0sDOtIo2TYk3tZn5UDrkE0XgsTQCxWTTOcMPf9p6Rh2hXtl5TQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.17.tgz", - "integrity": "sha512-rSEeYaGgyGGf4qZM2NonMhMOP/5EHp4u9ehFiBrg7stH6BYEEjlkVREuDEcQ0LfIl53OXLxNbfuIj7mr5m29TA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.17.tgz", - "integrity": "sha512-Y7ZBbkLqlSgn4+zot4KUNYst0bFoO68tRgI6mY2FIM+b7ZbyNVtNbDP5y8qlu4/knZZ73fgJDlXID+ohY5zt5g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.17.tgz", - "integrity": "sha512-bwPmTJsEQcbZk26oYpc4c/8PvTY3J5/QK8jM19DVlEsAB41M39aWovWoHtNm78sd6ip6prilxeHosPADXtEJFw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.17.tgz", - "integrity": "sha512-H/XaPtPKli2MhW+3CQueo6Ni3Avggi6hP/YvgkEe1aSaxw+AeO8MFjq8DlgfTd9Iz4Yih3QCZI6YLMoyccnPRg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.17.tgz", - "integrity": "sha512-fGEb8f2BSA3CW7riJVurug65ACLuQAzKq0SSqkY2b2yHHH0MzDfbLyKIGzHwOI/gkHcxM/leuSW6D5w/LMNitA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -5765,9 +5409,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", - "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", + "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", "dev": true, "license": "MIT", "engines": { @@ -6095,9 +5739,9 @@ } }, "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "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": { @@ -6811,6 +6455,7 @@ "version": "12.0.1", "resolved": "https://registry.npmjs.org/@koa/router/-/router-12.0.1.tgz", "integrity": "sha512-ribfPYfHb+Uw3b27Eiw6NPqjhIhTpVFzEWLwyc/1Xp+DCdwRRyIlAUODX+9bPARF6aQtUu1+/PHzdNvRzcs/+Q==", + "deprecated": "Use v12.0.2 or higher to fix the vulnerability issue", "license": "MIT", "dependencies": { "debug": "^4.3.4", @@ -8080,10 +7725,38 @@ } } }, + "node_modules/@storybook/angular/node_modules/@storybook/components": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/@storybook/components/-/components-8.3.3.tgz", + "integrity": "sha512-i2JYtesFGkdu+Hwuj+o9fLuO3yo+LPT1/8o5xBVYtEqsgDtEAyuRUWjSz8d8NPtzloGPOv5kvR6MokWDfbeMfw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.3.3" + } + }, + "node_modules/@storybook/angular/node_modules/@storybook/preview-api": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.3.3.tgz", + "integrity": "sha512-GP2QlaF3BBQGAyo248N7549YkTQjCentsc1hUvqPnFWU4xfjkejbnFk8yLaIw0VbYbL7jfd7npBtjZ+6AnphMQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.3.3" + } + }, "node_modules/@storybook/angular/node_modules/@types/node": { - "version": "18.19.48", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.48.tgz", - "integrity": "sha512-7WevbG4ekUcRQSZzOwxWgi5dZmTak7FaxXDoW7xVxPBmKx1rTzfmRLkeCgJzcbBnOV2dkhAPc8cCeT6agocpjg==", + "version": "18.19.50", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.50.tgz", + "integrity": "sha512-xonK+NRrMBRtkL1hVCc3G+uXtjh1Al4opBLjqVmipe5ZAaBYWW6cNAiBVZ1BvmkBhep698rP3UM3aRAdSALuhg==", "dev": true, "license": "MIT", "dependencies": { @@ -8186,9 +7859,9 @@ } }, "node_modules/@storybook/builder-webpack5/node_modules/@types/node": { - "version": "18.19.48", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.48.tgz", - "integrity": "sha512-7WevbG4ekUcRQSZzOwxWgi5dZmTak7FaxXDoW7xVxPBmKx1rTzfmRLkeCgJzcbBnOV2dkhAPc8cCeT6agocpjg==", + "version": "18.19.50", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.50.tgz", + "integrity": "sha512-xonK+NRrMBRtkL1hVCc3G+uXtjh1Al4opBLjqVmipe5ZAaBYWW6cNAiBVZ1BvmkBhep698rP3UM3aRAdSALuhg==", "dev": true, "license": "MIT", "dependencies": { @@ -8338,20 +8011,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@storybook/components": { - "version": "8.2.9", - "resolved": "https://registry.npmjs.org/@storybook/components/-/components-8.2.9.tgz", - "integrity": "sha512-OkkcZ/f/6o3GdFEEK9ZHKIGHWUHmavZUYs5xaSgU64bOrA2aqEFtfeWWitZYTv3Euhk8MVLWfyEMDfez0AlvDg==", - "dev": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "storybook": "^8.2.9" - } - }, "node_modules/@storybook/core": { "version": "8.2.9", "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.2.9.tgz", @@ -8395,9 +8054,9 @@ } }, "node_modules/@storybook/core-webpack/node_modules/@types/node": { - "version": "18.19.48", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.48.tgz", - "integrity": "sha512-7WevbG4ekUcRQSZzOwxWgi5dZmTak7FaxXDoW7xVxPBmKx1rTzfmRLkeCgJzcbBnOV2dkhAPc8cCeT6agocpjg==", + "version": "18.19.50", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.50.tgz", + "integrity": "sha512-xonK+NRrMBRtkL1hVCc3G+uXtjh1Al4opBLjqVmipe5ZAaBYWW6cNAiBVZ1BvmkBhep698rP3UM3aRAdSALuhg==", "dev": true, "license": "MIT", "dependencies": { @@ -8412,9 +8071,9 @@ "license": "MIT" }, "node_modules/@storybook/core/node_modules/@types/node": { - "version": "18.19.48", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.48.tgz", - "integrity": "sha512-7WevbG4ekUcRQSZzOwxWgi5dZmTak7FaxXDoW7xVxPBmKx1rTzfmRLkeCgJzcbBnOV2dkhAPc8cCeT6agocpjg==", + "version": "18.19.50", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.50.tgz", + "integrity": "sha512-xonK+NRrMBRtkL1hVCc3G+uXtjh1Al4opBLjqVmipe5ZAaBYWW6cNAiBVZ1BvmkBhep698rP3UM3aRAdSALuhg==", "dev": true, "license": "MIT", "dependencies": { @@ -8463,9 +8122,9 @@ "license": "MIT" }, "node_modules/@storybook/icons": { - "version": "1.2.10", - "resolved": "https://registry.npmjs.org/@storybook/icons/-/icons-1.2.10.tgz", - "integrity": "sha512-310apKdDcjbbX2VSLWPwhEwAgjxTzVagrwucVZIdGPErwiAppX8KvBuWZgPo+rQLVrtH8S+pw1dbUwjcE6d7og==", + "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": { @@ -8509,20 +8168,6 @@ "storybook": "^8.2.9" } }, - "node_modules/@storybook/preview-api": { - "version": "8.2.9", - "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.2.9.tgz", - "integrity": "sha512-D8/t+a78OJqQAcT/ABa1C4YM/OaLGQ9IvCsp3Q9ruUqDCwuZBj8bG3D4477dlY4owX2ycC0rWYu3VvuK0EmJjA==", - "dev": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "storybook": "^8.2.9" - } - }, "node_modules/@storybook/react-dom-shim": { "version": "8.2.9", "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-8.2.9.tgz", @@ -8692,9 +8337,9 @@ } }, "node_modules/@thednp/event-listener": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@thednp/event-listener/-/event-listener-2.0.5.tgz", - "integrity": "sha512-Zns+CFEAIKIEyqmuBZ3K2DSvk5IppaWcioghxLZPMrzkV034aOA38lP7NIKSxkeu0Eqd4UPxC06FksO6Pb/tmA==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@thednp/event-listener/-/event-listener-2.0.6.tgz", + "integrity": "sha512-6u55ydv4+2VHwHU8EJaJXa40QzZ7XOXVo74MMPnGCSzbl0q3yqHfQh8r0Sw/50rutHxecLVQBM/C9Fr0c+m+ew==", "dev": true, "license": "MIT", "engines": { @@ -8703,9 +8348,9 @@ } }, "node_modules/@thednp/shorty": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@thednp/shorty/-/shorty-2.0.3.tgz", - "integrity": "sha512-ngKP9/wQxM6JPDFjO6ak8lSz38ZA6cIFQy3gZbZM3xgUqArBr+VG9aoSoLHHEuaObyd9q9Jq/T0Wez7qrck0Gw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@thednp/shorty/-/shorty-2.0.4.tgz", + "integrity": "sha512-7iMeqgiHOTjAWLcl/rbWHgquHnvfawT2gExdAa1TLjZMGcFjx00FZkg6CHuMjLh9ayBnlgabC4Dsx0DV+h9yqQ==", "dev": true, "license": "MIT", "engines": { @@ -9002,9 +8647,9 @@ } }, "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" }, @@ -9075,6 +8720,24 @@ "@types/node": "*" } }, + "node_modules/@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/glob/node_modules/@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/graceful-fs": { "version": "4.1.9", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", @@ -9346,9 +9009,9 @@ } }, "node_modules/@types/lodash": { - "version": "4.17.7", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.7.tgz", - "integrity": "sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==", + "version": "4.17.9", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.9.tgz", + "integrity": "sha512-w9iWudx1XWOHW5lQRS9iKpK/XuRhnN+0T7HvdCCd802FYkT1AMTnxndJHGrNJwRoRHkslGr4S29tjm1cT7x/7w==", "dev": true, "license": "MIT" }, @@ -9486,9 +9149,9 @@ } }, "node_modules/@types/prop-types": { - "version": "15.7.12", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", - "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", + "version": "15.7.13", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", + "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==", "dev": true, "license": "MIT" }, @@ -9503,9 +9166,9 @@ } }, "node_modules/@types/qs": { - "version": "6.9.15", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", - "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", + "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" }, @@ -9517,9 +9180,9 @@ "license": "MIT" }, "node_modules/@types/react": { - "version": "18.3.5", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.5.tgz", - "integrity": "sha512-WeqMfGJLGuLCqHGYRGHxnKrXcTitc6L/nBUWfWPcTarG3t9PsquqUMuVeXZeca+mglY4Vo5GZjCi0A3Or2lnxA==", + "version": "18.3.9", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.9.tgz", + "integrity": "sha512-+BpAVyTpJkNWWSSnaLBk6ePpHLOGJKnEQNbINNovPWzvEUyAe3e+/d494QdEh71RekM/qV7lw6jzf1HGrJyAtQ==", "dev": true, "license": "MIT", "dependencies": { @@ -12664,9 +12327,9 @@ "license": "MIT" }, "node_modules/bare-events": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.4.2.tgz", - "integrity": "sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.0.tgz", + "integrity": "sha512-/E8dDe9dsbLyh2qrZ64PEPadOQ0F4gbl1sUJOrmph7xOiIxfY8vwab/4bFLh4Y88/Hk/ujKcrQKc+ps0mv873A==", "dev": true, "license": "Apache-2.0", "optional": true @@ -12885,9 +12548,9 @@ } }, "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", "dev": true, "license": "MIT", "dependencies": { @@ -12899,7 +12562,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.11.0", + "qs": "6.13.0", "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -13624,9 +13287,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001655", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001655.tgz", - "integrity": "sha512-jRGVy3iSGO5Uutn2owlb5gR6qsGngTw9ZTb4ali9f3glshcNmJ2noam4Mo9zia5P9Dk3jNNydy7vQjuE5dQmfg==", + "version": "1.0.30001663", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001663.tgz", + "integrity": "sha512-o9C3X27GLKbLeTYZ6HBOLU1tsAcBZsLis28wrVzddShCS16RujjHp9GDHKZqrB3meE0YjhawvMFsGb/igqiPzA==", "funding": [ { "type": "opencollective", @@ -13911,9 +13574,9 @@ } }, "node_modules/cjs-module-lexer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.0.tgz", - "integrity": "sha512-N1NGmowPlGBLsOZLPvm48StN04V4YvQRL0i6b7ctrVY3epjP/ct7hFLOItz6pDIvRjwpfPxi52a2UWV2ziir8g==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz", + "integrity": "sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==", "dev": true, "license": "MIT" }, @@ -14658,9 +14321,9 @@ } }, "node_modules/config-file-ts/node_modules/typescript": { - "version": "5.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", - "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", + "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -15369,23 +15032,17 @@ "license": "MIT" }, "node_modules/cssstyle": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.0.1.tgz", - "integrity": "sha512-8ZYiJ3A/3OkDd093CBT/0UKDWry7ak4BdPTFP2+QEP7cmhouyq/Up709ASSj2cK02BbZiMgk7kYjZNS4QP5qrQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.1.0.tgz", + "integrity": "sha512-h66W1URKpBS5YMI/V8PyXvTMFT8SupJ1IzoIV8IeBC/ji8WVmrO8dGlTi+2dh6whmdk6BiKJLD/ZBkhWbcg6nA==", "license": "MIT", "dependencies": { - "rrweb-cssom": "^0.6.0" + "rrweb-cssom": "^0.7.1" }, "engines": { "node": ">=18" } }, - "node_modules/cssstyle/node_modules/rrweb-cssom": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", - "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", - "license": "MIT" - }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", @@ -15491,12 +15148,12 @@ } }, "node_modules/debug": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", - "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -16570,9 +16227,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.13", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz", - "integrity": "sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==", + "version": "1.5.28", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.28.tgz", + "integrity": "sha512-VufdJl+rzaKZoYVUijN13QcXVF5dWPZANeFTLNy+OSpHdDL5ynXTF35+60RSBbaQYB1ae723lQXHCrf4pyLsMw==", "license": "ISC" }, "node_modules/electron-updater": { @@ -16694,9 +16351,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" @@ -16773,9 +16431,9 @@ } }, "node_modules/envinfo": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz", - "integrity": "sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.14.0.tgz", + "integrity": "sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg==", "dev": true, "license": "MIT", "bin": { @@ -17322,9 +16980,9 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.2.tgz", - "integrity": "sha512-3XnC5fDyc8M4J2E8pt8pmSVRX2M+5yWMCfI/kDZwauQeFgzQOuhcRBFKjTeJagqgk4sFKxe1mvNVnaWwImx/Tg==", + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.11.1.tgz", + "integrity": "sha512-EwcbfLOhwVMAfatfqLecR2yv3dE5+kQ8kx+Rrt0DvDXEVwW86KQ/xbMDQhtp5l42VXukD5SOF8mQQHbaNtO0CQ==", "dev": true, "license": "MIT", "dependencies": { @@ -18045,38 +17703,38 @@ "license": "Apache-2.0" }, "node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz", + "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==", "dev": true, "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.2", + "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.2.0", + "finalhandler": "1.3.1", "fresh": "0.5.2", "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", + "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", + "path-to-regexp": "0.1.10", "proxy-addr": "~2.0.7", - "qs": "6.11.0", + "qs": "6.13.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", + "send": "0.19.0", + "serve-static": "1.16.2", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "~1.6.18", @@ -18098,14 +17756,14 @@ } }, "node_modules/express/node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", "dev": true, "license": "MIT", "dependencies": { "debug": "2.6.9", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "on-finished": "2.4.1", "parseurl": "~1.3.3", @@ -18124,9 +17782,9 @@ "license": "MIT" }, "node_modules/express/node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", + "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", "dev": true, "license": "MIT" }, @@ -18523,6 +18181,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", @@ -18898,9 +18566,9 @@ "license": "ISC" }, "node_modules/flow-parser": { - "version": "0.245.0", - "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.245.0.tgz", - "integrity": "sha512-xUBkkpIDfDZHAebnDEX65FCVitJUctab82KFmtP5SY4cGly1vbuYNe6Muyp0NLXrgmBChVdoC2T+3/RUHi4Mww==", + "version": "0.246.0", + "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.246.0.tgz", + "integrity": "sha512-WHRizzSrWFTcKo7cVcbP3wzZVhzsoYxoWqbnH4z+JXGqrjVmnsld6kBZWVlB200PwD5ur8r+HV3KUDxv3cHhOQ==", "dev": true, "license": "MIT", "engines": { @@ -18959,9 +18627,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", "dev": true, "funding": [ { @@ -19637,9 +19305,9 @@ } }, "node_modules/get-tsconfig": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.0.tgz", - "integrity": "sha512-Pgba6TExTZ0FJAn1qkJAjIeKoDJ3CsI2ChuLohJnZl/tTU8MVrq3b+2t5UOPfRa4RMsorClBjJALkJUMjG1PAw==", + "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": { @@ -19972,7 +19640,6 @@ "version": "2.1.8", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "deprecated": "Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies", "dev": true, "license": "MIT", "dependencies": { @@ -20025,7 +19692,7 @@ "version": "1.2.13", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "deprecated": "The v1 package contains DANGEROUS / INSECURE binaries. Upgrade to safe fsevents v2", + "deprecated": "Upgrade to fsevents v2 to mitigate potential security issues", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -21689,9 +21356,9 @@ } }, "node_modules/i18next": { - "version": "23.14.0", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.14.0.tgz", - "integrity": "sha512-Y5GL4OdA8IU2geRrt2+Uc1iIhsjICdHZzT9tNwQ3TVqdNzgxHToGCKf/TPRP80vTCAP6svg2WbbJL+Gx5MFQVA==", + "version": "23.15.1", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.15.1.tgz", + "integrity": "sha512-wB4abZ3uK7EWodYisHl/asf8UYEhrI/vj/8aoSsrj/ZDxj4/UXPOa1KvFt1Fq5hkUHquNqwFlDprmjZ8iySgYA==", "dev": true, "funding": [ { @@ -23506,9 +23173,9 @@ } }, "node_modules/jest-environment-jsdom/node_modules/acorn-walk": { - "version": "8.3.3", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", - "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", "dev": true, "license": "MIT", "dependencies": { @@ -25062,6 +24729,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", @@ -25111,9 +24787,9 @@ } }, "node_modules/launch-editor": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.8.1.tgz", - "integrity": "sha512-elBx2l/tp9z99X5H/qev8uyDywVh0VXAwEbjk8kJhnc5grOFkGh7aW6q55me9xnYbss261XtnUrysZ+XvGbhQA==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.9.1.tgz", + "integrity": "sha512-Gcnl4Bd+hRO9P9icCP/RVVT2o8SFlPXofuCxvA2SaZuH45whSvf5p8x5oih5ftLiVhEI4sp5xDY+R+b3zJBh5w==", "dev": true, "license": "MIT", "dependencies": { @@ -25622,9 +25298,9 @@ } }, "node_modules/listr2/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "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": { @@ -26010,9 +25686,9 @@ } }, "node_modules/log-update/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "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": { @@ -26177,9 +25853,9 @@ } }, "node_modules/loglevel": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.1.tgz", - "integrity": "sha512-hP3I3kCrDIMuRwAwHltphhDM1r8i55H33GgqjXbrisuJhF4kRhW1dNuxsRklp4bXl8DSdLaNLuiL4A/LWRfxvg==", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.2.tgz", + "integrity": "sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==", "dev": true, "license": "MIT", "engines": { @@ -26975,11 +26651,14 @@ } }, "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/merge-stream": { "version": "2.0.0", @@ -28101,9 +27780,9 @@ } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, "node_modules/multer": { @@ -28412,9 +28091,9 @@ } }, "node_modules/node-abi": { - "version": "3.67.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.67.0.tgz", - "integrity": "sha512-bLn/fU/ALVBE9wj+p4Y21ZJWYFjUXLXPi/IewyLZkx3ApxKDNBWCKdReeKOtD8dWpOdDCeMyLh6ZewzcLsG2Nw==", + "version": "3.68.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.68.0.tgz", + "integrity": "sha512-7vbj10trelExNjFSBm5kTvZXXa7pZyKWx9RCKIyqe6I9Ev3IzGpQoqBP3a+cOdxY+pWj6VkP28n/2wWysBHD/A==", "dev": true, "license": "MIT", "dependencies": { @@ -29597,9 +29276,9 @@ "license": "MIT" }, "node_modules/ohash": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/ohash/-/ohash-1.1.3.tgz", - "integrity": "sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/ohash/-/ohash-1.1.4.tgz", + "integrity": "sha512-FlDryZAahJmEF3VR3w1KogSEdWX3WhA5GPakFx4J81kEAiHyLMpdLLElS8n8dfNadMgAne/MywcvmogzscVt4g==", "dev": true, "license": "MIT" }, @@ -30535,9 +30214,9 @@ "license": "ISC" }, "node_modules/path-to-regexp": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", - "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", "license": "MIT" }, "node_modules/path-type": { @@ -30581,9 +30260,9 @@ } }, "node_modules/pdfmake": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/pdfmake/-/pdfmake-0.2.12.tgz", - "integrity": "sha512-TFsqaG6KVtk+TWermmJNNwom3wmB/xiz07prM74KBhdM+7pz3Uwq2b0uoqhhQRn6cYUTpL8lXZY6xF011o1YcQ==", + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/pdfmake/-/pdfmake-0.2.13.tgz", + "integrity": "sha512-qeVE9Bzjm0oPCitH4/HYM/XCGTwoeOAOVAXPnV3s0kpPvTLkTF/bAF4jzorjkaIhXGQhzYk6Xclt0hMDYLY93w==", "dev": true, "license": "MIT", "dependencies": { @@ -30593,7 +30272,7 @@ "xmldoc": "^1.1.2" }, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/pend": { @@ -30604,9 +30283,9 @@ "license": "MIT" }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", "license": "ISC" }, "node_modules/picomatch": { @@ -31583,9 +31262,9 @@ "license": "MIT" }, "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", "dev": true, "license": "MIT", "dependencies": { @@ -31712,12 +31391,12 @@ "license": "GPL-3.0" }, "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "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.0.4" + "side-channel": "^1.0.6" }, "engines": { "node": ">=0.6" @@ -32302,9 +31981,9 @@ "license": "MIT" }, "node_modules/regenerate-unicode-properties": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", - "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", + "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", "dev": true, "license": "MIT", "dependencies": { @@ -33129,9 +32808,9 @@ } }, "node_modules/rimraf/node_modules/jackspeak": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.1.tgz", - "integrity": "sha512-cub8rahkh0Q/bw1+GxP7aeSe29hHHn2V4m29nnDlvCdlgU+3UGxkZp7Z53jLUdpX3jdTO0nJZUDl3xvbWc2Xog==", + "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": { @@ -33142,15 +32821,12 @@ }, "funding": { "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" } }, "node_modules/rimraf/node_modules/lru-cache": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.0.tgz", - "integrity": "sha512-Qv32eSV1RSCfhY3fpPE2GNZ8jgM9X7rdAfemLWqTUxwiyIC4jJ6Sy0fZ8H+oLWevO6i4/bizg7c8d8i6bxrzbA==", + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.1.tgz", + "integrity": "sha512-CgeuL5uom6j/ZVrg7G/+1IXqRY8JXX4Hghfy5YE0EhoYQWvndP1kufu58cmZLNIDKnRhZrXfdS9urVWx98AipQ==", "dev": true, "license": "ISC", "engines": { @@ -33218,9 +32894,9 @@ "optional": true }, "node_modules/rollup": { - "version": "3.29.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", - "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", + "version": "3.29.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.5.tgz", + "integrity": "sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==", "dev": true, "license": "MIT", "bin": { @@ -33645,9 +33321,9 @@ "license": "ISC" }, "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", "dev": true, "license": "MIT", "dependencies": { @@ -33686,6 +33362,16 @@ "dev": true, "license": "MIT" }, + "node_modules/send/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/send/node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -33699,13 +33385,6 @@ "node": ">=4" } }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, "node_modules/serialize-error": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", @@ -33834,16 +33513,16 @@ } }, "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", "dev": true, "license": "MIT", "dependencies": { - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.18.0" + "send": "0.19.0" }, "engines": { "node": ">= 0.8.0" @@ -34550,9 +34229,9 @@ } }, "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -35152,9 +34831,9 @@ } }, "node_modules/streamx": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.0.tgz", - "integrity": "sha512-ZGd1LhDeGFucr1CUCTBOS58ZhEendd0ttpGT3usTvosS4ntIwKN9LJFp+OeCSprsCPL14BXVRZlHGRY1V9PVzQ==", + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.1.tgz", + "integrity": "sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA==", "dev": true, "license": "MIT", "dependencies": { @@ -35953,9 +35632,9 @@ } }, "node_modules/terser-webpack-plugin/node_modules/terser": { - "version": "5.31.6", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz", - "integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==", + "version": "5.33.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.33.0.tgz", + "integrity": "sha512-JuPVaB7s1gdFKPKTelwUyRq5Sid2A3Gko2S0PncwdBq7kN9Ti9HPWDQ06MPsEDGsZeVESjKEnyGy68quBk1w6g==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -36040,9 +35719,9 @@ } }, "node_modules/text-decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.1.tgz", - "integrity": "sha512-8zll7REEv4GDD3x4/0pW+ppIxSNs7H1J10IKFZsuOMscumCdM2a+toDGLPA3T+1+fLBql4zbt5z83GEQGGV5VA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.0.tgz", + "integrity": "sha512-n1yg1mOj9DNpk3NeZOx7T6jchTbyJS3i3cucbNN6FcdPriMZx7NsgrGpWWdWZZGxD7ES1XB+3uoqHMgOKaN+fg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -36245,9 +35924,9 @@ } }, "node_modules/tldts-core": { - "version": "6.1.46", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.46.tgz", - "integrity": "sha512-zA3ai/j4aFcmbqTvTONkSBuWs0Q4X4tJxa0gV9sp6kDbq5dAhQDSg0WUkReEm0fBAKAGNj+wPKCCsR8MYOYmwA==", + "version": "6.1.47", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.47.tgz", + "integrity": "sha512-6SWyFMnlst1fEt7GQVAAu16EGgFK0cLouH/2Mk6Ftlwhv3Ol40L0dlpGMcnnNiiOMyD2EV/aF3S+U2nKvvLvrA==", "license": "MIT" }, "node_modules/tmp": { @@ -36477,9 +36156,9 @@ } }, "node_modules/traverse": { - "version": "0.6.9", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.9.tgz", - "integrity": "sha512-7bBrcF+/LQzSgFmT0X5YclVqQxtv7TDJ1f8Wj7ibBu/U6BMLeOpUxuZjV7rMc44UtKxlnMFigdhFAIszSX1DMg==", + "version": "0.6.10", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.10.tgz", + "integrity": "sha512-hN4uFRxbK+PX56DxYiGHsTn2dME3TVr9vbNqlQGcGcPhJAn+tdP126iA+TArMpI4YSgnTkMWyoLl5bf81Hi5TA==", "dev": true, "license": "MIT", "dependencies": { @@ -37282,9 +36961,9 @@ "license": "MIT" }, "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", "dev": true, "license": "MIT", "engines": { @@ -37306,9 +36985,9 @@ } }, "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", + "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", "dev": true, "license": "MIT", "engines": { @@ -37551,18 +37230,25 @@ } }, "node_modules/unplugin": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.12.3.tgz", - "integrity": "sha512-my8DH0/T/Kx33KO+6QXAqdeMYgyy0GktlOpdQjpagfHKw5DrD0ctPr7SHUyOT3g4ZVpzCQGt/qcpuoKJ/pniHA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.14.1.tgz", + "integrity": "sha512-lBlHbfSFPToDYp9pjXlUEFVxYLaue9f9T1HC+4OHlmj+HnMDdz9oZY+erXfoCe/5V/7gKUSY2jpXPb9S7f0f/w==", "dev": true, "license": "MIT", "dependencies": { "acorn": "^8.12.1", - "webpack-sources": "^3.2.3", "webpack-virtual-modules": "^0.6.2" }, "engines": { "node": ">=14.0.0" + }, + "peerDependencies": { + "webpack-sources": "^3" + }, + "peerDependenciesMeta": { + "webpack-sources": { + "optional": true + } } }, "node_modules/unset-value": { @@ -37711,22 +37397,6 @@ "dev": true, "license": "MIT" }, - "node_modules/url/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/use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", @@ -38600,9 +38270,9 @@ } }, "node_modules/webpack-dev-server/node_modules/memfs": { - "version": "4.11.1", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.11.1.tgz", - "integrity": "sha512-LZcMTBAgqUUKNXZagcZxvXXfgF1bHX7Y7nQ0QyEiNbRJgE29GhgPd8Yna1VQcLlPiHt/5RFJMWYN9Uv/VPNvjQ==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.12.0.tgz", + "integrity": "sha512-74wDsex5tQDSClVkeK1vtxqYCAgCoXxx+K4NSHzgU/muYVYByFqa+0RnrPO9NM6naWm1+G9JmZ0p6QHhXmeYfA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -39196,9 +38866,9 @@ "license": "ISC" }, "node_modules/yaml": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz", - "integrity": "sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz", + "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==", "license": "ISC", "bin": { "yaml": "bin.mjs" diff --git a/package.json b/package.json index 71fb63c37d6..a9d4f18e2fd 100644 --- a/package.json +++ b/package.json @@ -209,7 +209,8 @@ "@storybook/angular": { "zone.js": "$zone.js" }, - "replacestream": "4.0.3" + "replacestream": "4.0.3", + "@types/minimatch": "3.0.5" }, "lint-staged": { "*": "prettier --cache --ignore-unknown --write",