diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 9665d40b07..7a7bb31ea5 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -19,9 +19,6 @@ apps/web/src/connectors @bitwarden/team-auth-dev bitwarden_license/bit-web/src/app/auth @bitwarden/team-auth-dev libs/angular/src/auth @bitwarden/team-auth-dev libs/common/src/auth @bitwarden/team-auth-dev -# biometrics -apps/desktop/src/services/native-messaging.service.ts @bitwarden/team-auth-dev -app/browser/src/background/nativeMessaging.background.ts @bitwarden/team-auth-dev ## Tools team files ## apps/browser/src/tools @bitwarden/team-tools-dev @@ -111,7 +108,11 @@ apps/desktop/src/key-management @bitwarden/team-key-management-dev apps/web/src/key-management @bitwarden/team-key-management-dev apps/browser/src/key-management @bitwarden/team-key-management-dev apps/cli/src/key-management @bitwarden/team-key-management-dev -libs/common/src/key-management @bitwarden/team-key-management-dev +libs/key-management @bitwarden/team-key-management-dev + +apps/desktop/destkop_native/core/src/biometric/ @bitwarden/team-key-management-dev +apps/desktop/src/services/native-messaging.service.ts @bitwarden/team-key-management-dev +apps/browser/src/background/nativeMessaging.background.ts @bitwarden/team-key-management-dev ## DevOps team files ## /.github/workflows @bitwarden/dept-devops diff --git a/.github/whitelist-capital-letters.txt b/.github/whitelist-capital-letters.txt index b09829f7f4..c38e0241f7 100644 --- a/.github/whitelist-capital-letters.txt +++ b/.github/whitelist-capital-letters.txt @@ -20,6 +20,7 @@ ./libs/billing/README.md ./libs/common/src/tools/integration/README.md ./libs/platform/README.md +./libs/key-management/README.md ./libs/tools/README.md ./libs/tools/export/vault-export/README.md ./libs/tools/send/README.md diff --git a/.github/workflows/auto-branch-updater.yml b/.github/workflows/auto-branch-updater.yml index e2f181680d..372aa92eba 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 562567ffe7..4b25c58809 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 bccfc6d57c..b5b212423a 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 05039c3982..17748fa6a0 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 54e993edb3..4551a7baac 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 272b68139a..b52ecc1c40 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 527dedb5a8..b319e5365f 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 7551538b3a..d0f791aa00 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 3f72d62214..ad8c5dd40d 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 6581e26090..f9c4b85e8a 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 d12072c7e6..0816a86b1b 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 4409da9356..02a60ee422 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 2811b23af9..f190889414 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 cd450b2cd7..8f5123b50b 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 80b1ae092c..23b06d71dd 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 5b75460ef9..d69c15559b 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 982e386758..92f5701889 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 2320bae72f..f15a14dd11 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 fbe0c0a798..fd378213c9 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 fea68161ba..d18097ee1c 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 1b59a7805e..95b3922d34 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 795cd37123..98bcff7e82 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 384036840d..19f87b92fa 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 df91be9ff4..281819988a 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 5d8ea4ee40..a56b791e32 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 6f2a9be618..7293b697ee 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 7c1cc4b336..94fd992a01 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 cee00a55ff..1ddb21122e 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 476319b370..b9cb28d4b8 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 e5c2c38c07..1fec98793d 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 dc027fd44a..cf634a14bf 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 7d0054267b..ece0a8badf 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 c506cc4985..2b6c949479 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -2527,7 +2527,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendFilePopoutDialogDesc": { - "message": "To create a file Send, you need to pop out te extension to a new window.", + "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": { diff --git a/apps/browser/src/_locales/en_GB/messages.json b/apps/browser/src/_locales/en_GB/messages.json index e8fcd3de2c..cf37e70fb8 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 c4d7128eaf..e87d5a83e8 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 800f7baab0..bc9ed5547d 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 d9f64ecc04..0b87fbdd4a 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 88f2348d5f..7591a4b5d3 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 a152c8edd5..fa0c9ff0c1 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 9d152bc53a..aca9c6738a 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 f69cbf7197..04a30a0d0e 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 42b60a5f43..8eb51c6eaf 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 93b6391931..f51068e822 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 9b5ce585e4..5643edfc3c 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 3e00e16273..df53d65a00 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 1d999a0f9b..1dcc4861b7 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 41da93a06c..742938e154 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 a5aa720c0b..e05fb18d86 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 46bf1fe6c9..83abf961c2 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 adc9242050..708b2d039a 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 6525dcc9c0..c122548748 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 8eae45e6b3..f7db6d78f2 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 c022c77288..3ec5ff04f9 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 138a4548f8..3844548e24 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 6e583c88c1..21eabe2ade 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 8382fdcdc7..ae2a9bf679 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 e78edf841e..38d86e2f77 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 3601047788..35e55a1cf0 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 8eae45e6b3..f7db6d78f2 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 75188875b5..987ef6e811 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 8eae45e6b3..f7db6d78f2 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 3426fa1c62..0f4787eb9c 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 8eae45e6b3..f7db6d78f2 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 8eae45e6b3..f7db6d78f2 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 0452d2d5db..f667d71b91 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 27f41c9ef2..110bd1556f 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 4c5c63a343..9162937f2c 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 6d5dfa9e24..e349872614 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 829cd56b6f..b65860e397 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 36094f5510..a20bdf1ce0 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 3faaa06693..b7ac5aa748 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 11205385d2..4f3a5b4f0d 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 f36038e051..394eff867d 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 4f0a1cb1ff..c021a34c83 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 8eae45e6b3..f7db6d78f2 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 baa8babb5e..fef7511616 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 55286fccc9..0bfa7b56a5 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 e063af8c7f..a9090f5140 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 363065e442..a3e4adbc7e 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 e86e14c1a6..baf21d30a2 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 49a407d51d..d973910c66 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/auth/popup/lock.component.ts b/apps/browser/src/auth/popup/lock.component.ts index f5413e4bea..96bda7012d 100644 --- a/apps/browser/src/auth/popup/lock.component.ts +++ b/apps/browser/src/auth/popup/lock.component.ts @@ -23,11 +23,10 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; -import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service"; -import { BiometricsService } from "@bitwarden/common/platform/biometrics/biometric.service"; import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { DialogService, ToastService } from "@bitwarden/components"; +import { BiometricsService, BiometricStateService } from "@bitwarden/key-management"; import { BiometricErrors, BiometricErrorTypes } from "../../models/biometricErrors"; import { BrowserRouterService } from "../../platform/popup/services/browser-router.service"; diff --git a/apps/browser/src/auth/popup/settings/account-security-v1.component.ts b/apps/browser/src/auth/popup/settings/account-security-v1.component.ts index 4975ba5f7a..d2a515b259 100644 --- a/apps/browser/src/auth/popup/settings/account-security-v1.component.ts +++ b/apps/browser/src/auth/popup/settings/account-security-v1.component.ts @@ -31,14 +31,13 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; -import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service"; -import { BiometricsService } from "@bitwarden/common/platform/biometrics/biometric.service"; import { VaultTimeout, VaultTimeoutOption, VaultTimeoutStringType, } from "@bitwarden/common/types/vault-timeout.type"; import { DialogService } from "@bitwarden/components"; +import { BiometricStateService, BiometricsService } from "@bitwarden/key-management"; import { BiometricErrors, BiometricErrorTypes } from "../../../models/biometricErrors"; import { BrowserApi } from "../../../platform/browser/browser-api"; diff --git a/apps/browser/src/auth/popup/settings/account-security.component.ts b/apps/browser/src/auth/popup/settings/account-security.component.ts index 8e0acc7d64..c546db3c97 100644 --- a/apps/browser/src/auth/popup/settings/account-security.component.ts +++ b/apps/browser/src/auth/popup/settings/account-security.component.ts @@ -33,8 +33,6 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; -import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service"; -import { BiometricsService } from "@bitwarden/common/platform/biometrics/biometric.service"; import { VaultTimeout, VaultTimeoutOption, @@ -54,6 +52,7 @@ import { TypographyModule, ToastService, } from "@bitwarden/components"; +import { BiometricsService, BiometricStateService } from "@bitwarden/key-management"; import { BiometricErrors, BiometricErrorTypes } from "../../../models/biometricErrors"; import { BrowserApi } from "../../../platform/browser/browser-api"; diff --git a/apps/browser/src/autofill/services/autofill.service.ts b/apps/browser/src/autofill/services/autofill.service.ts index cd49da7219..de79fd974e 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( diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index 43a6d5968e..7e9da00aba 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -95,11 +95,6 @@ import { ObservableStorageService, } from "@bitwarden/common/platform/abstractions/storage.service"; import { SystemService as SystemServiceAbstraction } from "@bitwarden/common/platform/abstractions/system.service"; -import { - BiometricStateService, - DefaultBiometricStateService, -} from "@bitwarden/common/platform/biometrics/biometric-state.service"; -import { BiometricsService } from "@bitwarden/common/platform/biometrics/biometric.service"; import { StateFactory } from "@bitwarden/common/platform/factories/state-factory"; import { Message, MessageListener, MessageSender } from "@bitwarden/common/platform/messaging"; // eslint-disable-next-line no-restricted-imports -- Used for dependency creation @@ -197,6 +192,11 @@ import { ImportService, ImportServiceAbstraction, } from "@bitwarden/importer/core"; +import { + BiometricStateService, + DefaultBiometricStateService, + BiometricsService, +} from "@bitwarden/key-management"; import { IndividualVaultExportService, IndividualVaultExportServiceAbstraction, @@ -225,6 +225,7 @@ import { BrowserFido2UserInterfaceService } from "../autofill/fido2/services/bro import { AutofillService as AutofillServiceAbstraction } from "../autofill/services/abstractions/autofill.service"; import AutofillService from "../autofill/services/autofill.service"; import { SafariApp } from "../browser/safariApp"; +import { BackgroundBrowserBiometricsService } from "../key-management/biometrics/background-browser-biometrics.service"; import { BrowserApi } from "../platform/browser/browser-api"; import { UpdateBadge } from "../platform/listeners/update-badge"; /* eslint-disable no-restricted-imports */ @@ -233,7 +234,6 @@ import { ChromeMessageSender } from "../platform/messaging/chrome-message.sender import { OffscreenDocumentService } from "../platform/offscreen-document/abstractions/offscreen-document"; import { DefaultOffscreenDocumentService } from "../platform/offscreen-document/offscreen-document.service"; import { BrowserTaskSchedulerService } from "../platform/services/abstractions/browser-task-scheduler.service"; -import { BackgroundBrowserBiometricsService } from "../platform/services/background-browser-biometrics.service"; import { BrowserCryptoService } from "../platform/services/browser-crypto.service"; import { BrowserEnvironmentService } from "../platform/services/browser-environment.service"; import BrowserLocalStorageService from "../platform/services/browser-local-storage.service"; diff --git a/apps/browser/src/background/nativeMessaging.background.ts b/apps/browser/src/background/nativeMessaging.background.ts index 68a43fbdfe..d483b10bc3 100644 --- a/apps/browser/src/background/nativeMessaging.background.ts +++ b/apps/browser/src/background/nativeMessaging.background.ts @@ -10,11 +10,11 @@ import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt. import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { UserKey } from "@bitwarden/common/types/key"; +import { BiometricStateService } from "@bitwarden/key-management"; import { BrowserApi } from "../platform/browser/browser-api"; diff --git a/apps/browser/src/platform/services/background-browser-biometrics.service.ts b/apps/browser/src/key-management/biometrics/background-browser-biometrics.service.ts similarity index 100% rename from apps/browser/src/platform/services/background-browser-biometrics.service.ts rename to apps/browser/src/key-management/biometrics/background-browser-biometrics.service.ts diff --git a/apps/browser/src/platform/services/browser-biometrics.service.ts b/apps/browser/src/key-management/biometrics/browser-biometrics.service.ts similarity index 76% rename from apps/browser/src/platform/services/browser-biometrics.service.ts rename to apps/browser/src/key-management/biometrics/browser-biometrics.service.ts index 84734fb492..7ffbed4541 100644 --- a/apps/browser/src/platform/services/browser-biometrics.service.ts +++ b/apps/browser/src/key-management/biometrics/browser-biometrics.service.ts @@ -1,8 +1,8 @@ import { Injectable } from "@angular/core"; -import { BiometricsService } from "@bitwarden/common/platform/biometrics/biometric.service"; +import { BiometricsService } from "@bitwarden/key-management"; -import { BrowserApi } from "../browser/browser-api"; +import { BrowserApi } from "../../platform/browser/browser-api"; @Injectable() export abstract class BrowserBiometricsService extends BiometricsService { diff --git a/apps/browser/src/platform/services/foreground-browser-biometrics.ts b/apps/browser/src/key-management/biometrics/foreground-browser-biometrics.ts similarity index 93% rename from apps/browser/src/platform/services/foreground-browser-biometrics.ts rename to apps/browser/src/key-management/biometrics/foreground-browser-biometrics.ts index ee55de2010..f50468c8b7 100644 --- a/apps/browser/src/platform/services/foreground-browser-biometrics.ts +++ b/apps/browser/src/key-management/biometrics/foreground-browser-biometrics.ts @@ -1,4 +1,4 @@ -import { BrowserApi } from "../browser/browser-api"; +import { BrowserApi } from "../../platform/browser/browser-api"; import { BrowserBiometricsService } from "./browser-biometrics.service"; diff --git a/apps/browser/src/platform/services/browser-crypto.service.ts b/apps/browser/src/platform/services/browser-crypto.service.ts index 1d61fb4c8e..d0b4e3add7 100644 --- a/apps/browser/src/platform/services/browser-crypto.service.ts +++ b/apps/browser/src/platform/services/browser-crypto.service.ts @@ -10,14 +10,13 @@ import { KeyGenerationService } from "@bitwarden/common/platform/abstractions/ke import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; -import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service"; -import { BiometricsService } from "@bitwarden/common/platform/biometrics/biometric.service"; import { KeySuffixOptions } from "@bitwarden/common/platform/enums"; import { CryptoService } from "@bitwarden/common/platform/services/crypto.service"; import { USER_KEY } from "@bitwarden/common/platform/services/key-state/user-key.state"; import { StateProvider } from "@bitwarden/common/platform/state"; import { UserId } from "@bitwarden/common/types/guid"; import { UserKey } from "@bitwarden/common/types/key"; +import { BiometricsService, BiometricStateService } from "@bitwarden/key-management"; export class BrowserCryptoService extends CryptoService { constructor( diff --git a/apps/browser/src/popup/services/services.module.ts b/apps/browser/src/popup/services/services.module.ts index cca5651eeb..1b7550bc9a 100644 --- a/apps/browser/src/popup/services/services.module.ts +++ b/apps/browser/src/popup/services/services.module.ts @@ -72,8 +72,6 @@ import { AbstractStorageService, ObservableStorageService, } from "@bitwarden/common/platform/abstractions/storage.service"; -import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service"; -import { BiometricsService } from "@bitwarden/common/platform/biometrics/biometric.service"; import { Message, MessageListener, MessageSender } from "@bitwarden/common/platform/messaging"; // eslint-disable-next-line no-restricted-imports -- Used for dependency injection import { SubjectMessageSender } from "@bitwarden/common/platform/messaging/internal"; @@ -100,6 +98,7 @@ import { TotpService as TotpServiceAbstraction } from "@bitwarden/common/vault/a import { TotpService } from "@bitwarden/common/vault/services/totp.service"; import { DialogService, ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; +import { BiometricsService, BiometricStateService } from "@bitwarden/key-management"; import { PasswordRepromptService } from "@bitwarden/vault"; import { ForegroundLockService } from "../../auth/popup/accounts/foreground-lock.service"; @@ -108,6 +107,7 @@ import { ExtensionLoginComponentService } from "../../auth/popup/login/extension import { AutofillService as AutofillServiceAbstraction } from "../../autofill/services/abstractions/autofill.service"; import AutofillService from "../../autofill/services/autofill.service"; import MainBackground from "../../background/main.background"; +import { ForegroundBrowserBiometricsService } from "../../key-management/biometrics/foreground-browser-biometrics"; import { BrowserApi } from "../../platform/browser/browser-api"; import { runInsideAngular } from "../../platform/browser/run-inside-angular.operator"; /* eslint-disable no-restricted-imports */ @@ -123,7 +123,6 @@ import { BrowserCryptoService } from "../../platform/services/browser-crypto.ser import { BrowserEnvironmentService } from "../../platform/services/browser-environment.service"; import BrowserLocalStorageService from "../../platform/services/browser-local-storage.service"; import { BrowserScriptInjectorService } from "../../platform/services/browser-script-injector.service"; -import { ForegroundBrowserBiometricsService } from "../../platform/services/foreground-browser-biometrics"; import I18nService from "../../platform/services/i18n.service"; import { ForegroundPlatformUtilsService } from "../../platform/services/platform-utils/foreground-platform-utils.service"; import { ForegroundTaskSchedulerService } from "../../platform/services/task-scheduler/foreground-task-scheduler.service"; 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 45a6c67f78..932816ba7a 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 16938fbe79..760f0627ab 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 e96a0742a0..b3783bfed3 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 @@ -19,7 +19,7 @@ *ngIf="config?.mode !== 'add'" type="button" buttonType="danger" - class="tw-ml-auto bwi-lg" + slot="end" bitIconButton="bwi-trash" [bitAction]="deleteSend" appA11yTitle="{{ 'delete' | i18n }}" diff --git a/apps/browser/src/tools/popup/send-v2/send-file-popout-dialog/send-file-popout-dialog-container.component.ts b/apps/browser/src/tools/popup/send-v2/send-file-popout-dialog/send-file-popout-dialog-container.component.ts index 33f121431f..d3d481063e 100644 --- a/apps/browser/src/tools/popup/send-v2/send-file-popout-dialog/send-file-popout-dialog-container.component.ts +++ b/apps/browser/src/tools/popup/send-v2/send-file-popout-dialog/send-file-popout-dialog-container.component.ts @@ -2,6 +2,7 @@ import { CommonModule } from "@angular/common"; import { Component, Input, OnInit } from "@angular/core"; import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { SendType } from "@bitwarden/common/tools/send/enums/send-type"; import { DialogService } from "@bitwarden/components"; import { SendFormConfig } from "@bitwarden/send-ui"; @@ -24,7 +25,11 @@ export class SendFilePopoutDialogContainerComponent implements OnInit { ) {} ngOnInit() { - if (this.config.mode === "add" && this.filePopoutUtilsService.showFilePopoutMessage(window)) { + if ( + this.config.sendType === SendType.File && + this.config.mode === "add" && + this.filePopoutUtilsService.showFilePopoutMessage(window) + ) { this.dialogService.open(SendFilePopoutDialogComponent); } } diff --git a/apps/browser/src/tools/popup/send-v2/send-v2.component.html b/apps/browser/src/tools/popup/send-v2/send-v2.component.html index 698901d846..23582f1911 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 63e3c2d2fc..506d7146dd 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 26a995e8c4..2766ba56c9 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 @@ -55,6 +55,7 @@ export class SendV2Component implements OnInit, OnDestroy { 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; diff --git a/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.html b/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.html index 6b2d8eaa03..6345c3ea4e 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.html +++ b/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.html @@ -1,11 +1,9 @@ - {{ - 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 cf66dac2f7..4f6d30530c 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 27d51af92b..e6ed6475c4 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 42a987664f..c7cd7e45a9 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 5992af5f54..e6e2610d67 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 b966729c1d..57491a73e6 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 0000000000..01605eae7d --- /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 0000000000..0d7698e00f --- /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 0000000000..42ce1be2ea --- /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 0000000000..79c3cb83a4 --- /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 0000000000..2238c10dd4 --- /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/core/core.module.ts b/apps/web/src/app/core/core.module.ts index 4531cd4451..b7be767982 100644 --- a/apps/web/src/app/core/core.module.ts +++ b/apps/web/src/app/core/core.module.ts @@ -4,24 +4,24 @@ import { APP_INITIALIZER, NgModule, Optional, SkipSelf } from "@angular/core"; import { OrganizationUserApiService } from "@bitwarden/admin-console/common"; import { SafeProvider, safeProvider } from "@bitwarden/angular/platform/utils/safe-provider"; import { - SECURE_STORAGE, - LOCALES_DIRECTORY, - SYSTEM_LANGUAGE, - MEMORY_STORAGE, - OBSERVABLE_MEMORY_STORAGE, - OBSERVABLE_DISK_STORAGE, - OBSERVABLE_DISK_LOCAL_STORAGE, - WINDOW, - SafeInjectionToken, - DEFAULT_VAULT_TIMEOUT, CLIENT_TYPE, + DEFAULT_VAULT_TIMEOUT, + LOCALES_DIRECTORY, + MEMORY_STORAGE, + OBSERVABLE_DISK_LOCAL_STORAGE, + OBSERVABLE_DISK_STORAGE, + OBSERVABLE_MEMORY_STORAGE, + SECURE_STORAGE, + SYSTEM_LANGUAGE, + SafeInjectionToken, + WINDOW, } from "@bitwarden/angular/services/injection-tokens"; import { JslibServicesModule } from "@bitwarden/angular/services/jslib-services.module"; import { ModalService as ModalServiceAbstraction } from "@bitwarden/angular/services/modal.service"; import { - SetPasswordJitService, RegistrationFinishService as RegistrationFinishServiceAbstraction, LoginComponentService, + SetPasswordJitService, } from "@bitwarden/auth/angular"; import { InternalUserDecryptionOptionsServiceAbstraction, @@ -48,7 +48,6 @@ import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/platfor import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { AbstractStorageService } from "@bitwarden/common/platform/abstractions/storage.service"; -import { BiometricsService } from "@bitwarden/common/platform/biometrics/biometric.service"; import { ThemeType } from "@bitwarden/common/platform/enums"; import { AppIdService as DefaultAppIdService } from "@bitwarden/common/platform/services/app-id.service"; import { MemoryStorageService } from "@bitwarden/common/platform/services/memory-storage.service"; @@ -67,6 +66,7 @@ import { } from "@bitwarden/common/platform/theming/theme-state.service"; import { VaultTimeout, VaultTimeoutStringType } from "@bitwarden/common/types/vault-timeout.type"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; +import { BiometricsService } from "@bitwarden/key-management"; import { PolicyListService } from "../admin-console/core/policy-list.service"; import { @@ -77,7 +77,7 @@ import { import { AcceptOrganizationInviteService } from "../auth/organization-invite/accept-organization.service"; import { HtmlStorageService } from "../core/html-storage.service"; import { I18nService } from "../core/i18n.service"; -import { WebBiometricsService } from "../platform/web-biometric.service"; +import { WebBiometricsService } from "../key-management/web-biometric.service"; import { WebEnvironmentService } from "../platform/web-environment.service"; import { WebMigrationRunner } from "../platform/web-migration-runner"; import { WebStorageServiceProvider } from "../platform/web-storage-service.provider"; diff --git a/apps/web/src/app/platform/web-biometric.service.ts b/apps/web/src/app/key-management/web-biometric.service.ts similarity index 87% rename from apps/web/src/app/platform/web-biometric.service.ts rename to apps/web/src/app/key-management/web-biometric.service.ts index 3fb817ec5b..4681eb6fa4 100644 --- a/apps/web/src/app/platform/web-biometric.service.ts +++ b/apps/web/src/app/key-management/web-biometric.service.ts @@ -1,4 +1,4 @@ -import { BiometricsService } from "@bitwarden/common/platform/biometrics/biometric.service"; +import { BiometricsService } from "@bitwarden/key-management"; export class WebBiometricsService extends BiometricsService { async supportsBiometric(): Promise { 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 7d4309b7bc..cfefbbe4d7 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 bcd5a28812..b3f2ae581b 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 e836c14996..af336c9485 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 0ebecab9f1..4ee0e2986b 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 f33e0626ab..7782e96e97 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/individual-vault/add-edit-v2.component.html b/apps/web/src/app/vault/individual-vault/add-edit-v2.component.html index 6aa3e61064..9a430b0aaa 100644 --- a/apps/web/src/app/vault/individual-vault/add-edit-v2.component.html +++ b/apps/web/src/app/vault/individual-vault/add-edit-v2.component.html @@ -12,12 +12,10 @@ > 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 31f981b489..2976bfc8c2 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 { @@ -476,15 +477,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, allCollections]) => { const cipherId = getCipherIdFromParams(qParams); if (!cipherId) { return; } - const cipher = allCiphersMap[cipherId]; const cipherCollections = allCollections.filter((c) => cipher.collectionIds.includes(c.id), diff --git a/apps/web/src/locales/af/messages.json b/apps/web/src/locales/af/messages.json index 31b2e1ecdc..e4896b63a8 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 bfa8c4e38b..25f7ccd8f1 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 10e84f1e95..b745617eba 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 71ac5920a0..26fcce71fa 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 bec147c11e..3869f44f41 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 276dd76024..2fcc9c9e29 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 82e3979880..8b9fd8a161 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 1f8d01e354..e6e11e50a8 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 3c605153fa..dc2076b2c4 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 dc59ad0079..7a24f52cde 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 be07e684cc..a15d161ba8 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 c7961eba8f..77e21a6965 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 bc70723da7..bf1fa4d080 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 d0bebaf0bb..6d90187c78 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -2211,6 +2211,9 @@ "checkExposedPasswords": { "message": "Check exposed passwords" }, + "timesExposed": { + "message": "Times exposed" + }, "exposedXTimes": { "message": "Exposed $COUNT$ time(s)", "placeholders": { @@ -2245,6 +2248,9 @@ "noWeakPasswords": { "message": "No items in your vault have weak passwords." }, + "weakness": { + "message": "Weakness" + }, "reusedPasswordsReport": { "message": "Reused passwords" }, @@ -2270,6 +2276,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 2f54c36769..72462e3786 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 a32fe1a382..0d07672632 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 955a362b5f..3052b4f520 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 751dd63f8f..f665756842 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 b69360d089..8acf520cb6 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 aab9e193ad..930b83584b 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 c1f9660643..fe70735404 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 2be651f3b6..15923a3c85 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 c907b7fc2a..b24dc06d18 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 c1c669acc7..c41479177c 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 d41fbb4ff4..e8ed2bc600 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 2dd52d914b..72c0840832 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 0f08cf9ad5..2af048332b 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 82afe5fe3a..055592ca38 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 7db2c68e09..65dd6330a7 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 8fb655a4ad..910d9a4762 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 7628e19211..86d68b29f9 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 a6bdd82e13..3694666f24 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 d24cef82ec..c19eba3cf9 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 de896a154c..b00f71df72 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 cf6597a3b1..35227fb425 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 51e53d0ec2..7803f09d52 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 7c79cb9e98..4a0039cb06 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 e3f9c72ea0..5053266687 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 de896a154c..b00f71df72 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 de896a154c..b00f71df72 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 ca478c0e5d..b228e618bb 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 dd0b9042e7..56d3cc013b 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 9564258a68..0213fcec64 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 1ccc3b7700..662db9c165 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 de896a154c..b00f71df72 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 fbc7ccbe78..f41c635c76 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 35e0c664f6..557510b78d 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 0455402a94..9770a57403 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 b60c3a5bb6..7c2fcbeef9 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 a771d49ab2..1ad7a81088 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 f0f2fdb14d..9b4a66346f 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 b5cdd9781b..8fdb9c65cb 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 b5b2a74453..b292e7a357 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 588cce614b..7f464f49e4 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 c9eb9391c1..0fa58e64ac 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 43817b3f76..9a7a5870f6 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 de896a154c..b00f71df72 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 e9160221b0..b1b61a9adc 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 03a18764bf..b3783fb249 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 745ca2379c..3041c4220c 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 529c08a56f..56e9f879f6 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 28bb2f8618..0e842c24ba 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 12ff2018a2..bba5457f55 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/apps/web/tsconfig.json b/apps/web/tsconfig.json index 5829e2f6ab..1e17de148f 100644 --- a/apps/web/tsconfig.json +++ b/apps/web/tsconfig.json @@ -23,6 +23,7 @@ "@bitwarden/vault-export-ui": ["../../libs/tools/export/vault-export/vault-export-ui/src"], "@bitwarden/importer/core": ["../../libs/importer/src"], "@bitwarden/importer/ui": ["../../libs/importer/src/components"], + "@bitwarden/key-management": ["../../libs/key-management/src"], "@bitwarden/platform": ["../../libs/platform/src"], "@bitwarden/send-ui": ["../../libs/tools/send/send-ui/src"], "@bitwarden/vault": ["../../libs/vault/src"], diff --git a/bitwarden_license/bit-cli/tsconfig.json b/bitwarden_license/bit-cli/tsconfig.json index 4012daac54..bb9986e6c9 100644 --- a/bitwarden_license/bit-cli/tsconfig.json +++ b/bitwarden_license/bit-cli/tsconfig.json @@ -23,6 +23,7 @@ "@bitwarden/generator-legacy": ["../../libs/tools/generator/extensions/legacy/src"], "@bitwarden/generator-history": ["../../libs/tools/generator/extensions/history/src"], "@bitwarden/generator-navigation": ["../../libs/tools/generator/extensions/navigation/src"], + "@bitwarden/key-management": ["../../libs/key-management/src"], "@bitwarden/vault-export-core": [ "../../libs/tools/export/vault-export/vault-export-core/src" ], diff --git a/bitwarden_license/bit-common/tsconfig.json b/bitwarden_license/bit-common/tsconfig.json index 21f57001ed..85ba8cbf60 100644 --- a/bitwarden_license/bit-common/tsconfig.json +++ b/bitwarden_license/bit-common/tsconfig.json @@ -21,6 +21,7 @@ ], "@bitwarden/vault-export-ui": ["../../libs/tools/export/vault-export/vault-export-core/src"], "@bitwarden/send-ui": ["../../libs/tools/send/send-ui/src"], + "@bitwarden/key-management": ["../../libs/key-management/src"], "@bitwarden/platform": ["../../libs/platform/src"], "@bitwarden/vault": ["../../libs/vault/src"], "@bitwarden/web-vault/*": ["../../apps/web/src/*"], diff --git a/bitwarden_license/bit-web/tsconfig.json b/bitwarden_license/bit-web/tsconfig.json index e05ae8018f..968744d796 100644 --- a/bitwarden_license/bit-web/tsconfig.json +++ b/bitwarden_license/bit-web/tsconfig.json @@ -23,6 +23,7 @@ "@bitwarden/vault-export-ui": ["../../libs/tools/export/vault-export/vault-export-ui/src"], "@bitwarden/importer/core": ["../../libs/importer/src"], "@bitwarden/importer/ui": ["../../libs/importer/src/components"], + "@bitwarden/key-management": ["../../libs/key-management/src"], "@bitwarden/platform": ["../../libs/platform/src"], "@bitwarden/send-ui": ["../../libs/tools/send/send-ui/src"], "@bitwarden/vault": ["../../libs/vault/src"], diff --git a/libs/angular/src/auth/components/lock.component.ts b/libs/angular/src/auth/components/lock.component.ts index 484e1c6346..5fc8f51d57 100644 --- a/libs/angular/src/auth/components/lock.component.ts +++ b/libs/angular/src/auth/components/lock.component.ts @@ -29,14 +29,13 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; -import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service"; -import { BiometricsService } from "@bitwarden/common/platform/biometrics/biometric.service"; import { KeySuffixOptions } from "@bitwarden/common/platform/enums"; import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength"; import { UserId } from "@bitwarden/common/types/guid"; import { UserKey } from "@bitwarden/common/types/key"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { DialogService, ToastService } from "@bitwarden/components"; +import { BiometricStateService, BiometricsService } from "@bitwarden/key-management"; @Directive() export class LockComponent implements OnInit, OnDestroy { diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index e6b489f8db..338113d572 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -153,10 +153,6 @@ import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from "@bitwar import { StateService as StateServiceAbstraction } from "@bitwarden/common/platform/abstractions/state.service"; import { AbstractStorageService } from "@bitwarden/common/platform/abstractions/storage.service"; import { ValidationService as ValidationServiceAbstraction } from "@bitwarden/common/platform/abstractions/validation.service"; -import { - BiometricStateService, - DefaultBiometricStateService, -} from "@bitwarden/common/platform/biometrics/biometric-state.service"; import { StateFactory } from "@bitwarden/common/platform/factories/state-factory"; import { Message, MessageListener, MessageSender } from "@bitwarden/common/platform/messaging"; // eslint-disable-next-line no-restricted-imports -- Used for dependency injection @@ -265,6 +261,7 @@ import { ImportService, ImportServiceAbstraction, } from "@bitwarden/importer/core"; +import { BiometricStateService, DefaultBiometricStateService } from "@bitwarden/key-management"; import { PasswordRepromptService } from "@bitwarden/vault"; import { VaultExportService, 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 0aecb6e378..dbacf28054 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/autofill/utils.ts b/libs/common/src/autofill/utils.ts index 86411691ea..0b127e4b9d 100644 --- a/libs/common/src/autofill/utils.ts +++ b/libs/common/src/autofill/utils.ts @@ -82,10 +82,10 @@ export function isCardExpired(cipherCard: CardView): boolean { const parsedYear = parseInt(normalizedYear, 10); - // First day of the next month minus one, to get last day of the card month - const cardExpiry = new Date(parsedYear, parsedMonth + 1, 0); + // First day of the next month + const cardExpiry = new Date(parsedYear, parsedMonth + 1, 1); - return cardExpiry < now; + return cardExpiry <= now; } } diff --git a/libs/common/src/enums/feature-flag.enum.ts b/libs/common/src/enums/feature-flag.enum.ts index 7ac473ff6a..505fe33e82 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 6b6555fc56..24aeb11cdb 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 0000000000..0bdee21e3c --- /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 f7273d2435..1cfcfac02f 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 7583c37e1e..39d5883177 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 1f4c8caf39..0b0a597acd 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/platform/services/system.service.ts b/libs/common/src/platform/services/system.service.ts index 382b3bf8e8..357737391c 100644 --- a/libs/common/src/platform/services/system.service.ts +++ b/libs/common/src/platform/services/system.service.ts @@ -1,5 +1,7 @@ import { firstValueFrom, map, Subscription, timeout } from "rxjs"; +import { BiometricStateService } from "@bitwarden/key-management"; + import { PinServiceAbstraction } from "../../../../auth/src/common/abstractions"; import { VaultTimeoutSettingsService } from "../../abstractions/vault-timeout/vault-timeout-settings.service"; import { AccountService } from "../../auth/abstractions/account.service"; @@ -11,7 +13,6 @@ import { UserId } from "../../types/guid"; import { MessagingService } from "../abstractions/messaging.service"; import { PlatformUtilsService } from "../abstractions/platform-utils.service"; import { SystemService as SystemServiceAbstraction } from "../abstractions/system.service"; -import { BiometricStateService } from "../biometrics/biometric-state.service"; import { Utils } from "../misc/utils"; import { ScheduledTaskNames } from "../scheduling/scheduled-task-name.enum"; import { TaskSchedulerService } from "../scheduling/task-scheduler.service"; diff --git a/libs/common/src/services/vault-timeout/vault-timeout-settings.service.spec.ts b/libs/common/src/services/vault-timeout/vault-timeout-settings.service.spec.ts index 177c75ed5b..d90388f866 100644 --- a/libs/common/src/services/vault-timeout/vault-timeout-settings.service.spec.ts +++ b/libs/common/src/services/vault-timeout/vault-timeout-settings.service.spec.ts @@ -8,6 +8,7 @@ import { } from "@bitwarden/auth/common"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { UserId } from "@bitwarden/common/types/guid"; +import { BiometricStateService } from "@bitwarden/key-management"; import { FakeAccountService, mockAccountServiceWith, FakeStateProvider } from "../../../spec"; import { VaultTimeoutSettingsService as VaultTimeoutSettingsServiceAbstraction } from "../../abstractions/vault-timeout/vault-timeout-settings.service"; @@ -17,7 +18,6 @@ import { TokenService } from "../../auth/abstractions/token.service"; import { VaultTimeoutAction } from "../../enums/vault-timeout-action.enum"; import { CryptoService } from "../../platform/abstractions/crypto.service"; import { LogService } from "../../platform/abstractions/log.service"; -import { BiometricStateService } from "../../platform/biometrics/biometric-state.service"; import { VAULT_TIMEOUT, VAULT_TIMEOUT_ACTION, diff --git a/libs/common/src/services/vault-timeout/vault-timeout-settings.service.ts b/libs/common/src/services/vault-timeout/vault-timeout-settings.service.ts index e6587ade70..a90842b208 100644 --- a/libs/common/src/services/vault-timeout/vault-timeout-settings.service.ts +++ b/libs/common/src/services/vault-timeout/vault-timeout-settings.service.ts @@ -17,6 +17,7 @@ import { PinServiceAbstraction, UserDecryptionOptionsServiceAbstraction, } from "@bitwarden/auth/common"; +import { BiometricStateService } from "@bitwarden/key-management"; import { VaultTimeoutSettingsService as VaultTimeoutSettingsServiceAbstraction } from "../../abstractions/vault-timeout/vault-timeout-settings.service"; import { PolicyService } from "../../admin-console/abstractions/policy/policy.service.abstraction"; @@ -27,7 +28,6 @@ import { TokenService } from "../../auth/abstractions/token.service"; import { VaultTimeoutAction } from "../../enums/vault-timeout-action.enum"; import { CryptoService } from "../../platform/abstractions/crypto.service"; import { LogService } from "../../platform/abstractions/log.service"; -import { BiometricStateService } from "../../platform/biometrics/biometric-state.service"; import { StateProvider } from "../../platform/state"; import { UserId } from "../../types/guid"; import { VaultTimeout, VaultTimeoutStringType } from "../../types/vault-timeout.type"; diff --git a/libs/common/src/vault/models/domain/folder.spec.ts b/libs/common/src/vault/models/domain/folder.spec.ts index 69134d19cf..785852b884 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 9505bad705..da9e9811d4 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 7e5c51bc30..47659c2739 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/components/src/item/item-content.component.html b/libs/components/src/item/item-content.component.html index bed8b2f5b7..d8e7b31c83 100644 --- a/libs/components/src/item/item-content.component.html +++ b/libs/components/src/item/item-content.component.html @@ -2,8 +2,16 @@
-
- +
+
+ +
+
+ +
diff --git a/libs/components/src/item/item.mdx b/libs/components/src/item/item.mdx index 507d7d56a2..b5c7da80ba 100644 --- a/libs/components/src/item/item.mdx +++ b/libs/components/src/item/item.mdx @@ -55,12 +55,13 @@ The content can be a button, anchor, or static container. `bit-item-content` contains the following slots to help position the content: -| Slot | Description | -| ------------------ | --------------------------------------------------- | -| default | primary text or arbitrary content; fan favorite | -| `slot="secondary"` | supporting text; under the default slot | -| `slot="start"` | commonly an icon or avatar; before the default slot | -| `slot="end"` | commonly an icon; after the default slot | +| Slot | Description | +| ------------------------- | --------------------------------------------------------------------------------------------------------- | +| default | primary text or arbitrary content; fan favorite | +| `slot="secondary"` | supporting text; under the default slot | +| `slot="start"` | commonly an icon or avatar; before the default slot | +| `slot="default-trailing"` | commonly a badge; default content that should not be truncated and is placed right after the default slot | +| `slot="end"` | commonly an icon; placed at the far end after the default slot | - Note: There is also an `end` slot within `bit-item` itself. Place [interactive secondary actions](#secondary-actions) there, and place non-interactive content (such @@ -71,6 +72,7 @@ The content can be a button, anchor, or static container. + +
+ + + +
{{ "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 0000000000..e5327cc66e --- /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 0000000000..4a4f8cd9fe --- /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 0000000000..978bd05ca7 --- /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 0000000000..c26d44b3b7 --- /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 c68131f604..6c351b82e3 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 f71d484f9c..2c96b0c2d3 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 eaaac757ff..482703fd3c 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 4d758fc465..4e46718a39 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 8670b8c176..fb953af165 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 5029cdbc42..f4a7e1304d 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 e30db28645..54d140e446 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 4a6aa43f60..d5872e21ce 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 0000000000..1ef0adc1af --- /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 0000000000..72eea38214 --- /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 811c4aa822..688315e929 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 c6cc96dd82..91334f91f8 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 7e249bc135..88f1447e98 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 dc6b861940..693ffd654d 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 0000000000..fc7c3e1bbc --- /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 0000000000..3f6a6c1e1b --- /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 54c8c5ed8e..0000000000 --- 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 80d977a73c..8302450d44 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 a687676576..6a498282fe 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 ff174b04a5..6d18a1c789 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 717b0e994e..59727fb98f 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 4f74c487f2..884d976007 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 75871e056c..51049fa56b 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 01b96e3bc5..dbd86d7f5b 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 a73a3a6ad8..2261ca7e1f 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 8b004207c1..99db65807a 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 92a48df40a..7a7c86df92 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 107749b1e6..66ad5b6786 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/libs/vault/src/cipher-form/components/attachments/delete-attachment/delete-attachment.component.html b/libs/vault/src/cipher-form/components/attachments/delete-attachment/delete-attachment.component.html index 38ece650b7..efbc1a0503 100644 --- a/libs/vault/src/cipher-form/components/attachments/delete-attachment/delete-attachment.component.html +++ b/libs/vault/src/cipher-form/components/attachments/delete-attachment/delete-attachment.component.html @@ -3,7 +3,7 @@ buttonType="danger" size="small" type="button" - class="tw-border-none" + class="tw-border-transparent" [appA11yTitle]="'deleteAttachmentName' | i18n: attachment.fileName" [bitAction]="delete" > diff --git a/package-lock.json b/package-lock.json index 97dee9ef98..c12dd4c154 100644 --- a/package-lock.json +++ b/package-lock.json @@ -66,7 +66,7 @@ "qrious": "4.0.2", "rxjs": "7.8.1", "tabbable": "6.2.0", - "tldts": "6.1.46", + "tldts": "6.1.48", "utf-8-validate": "6.0.4", "zone.js": "0.13.3", "zxcvbn": "4.4.2" @@ -108,7 +108,7 @@ "@types/koa-json": "2.0.23", "@types/lowdb": "1.0.15", "@types/lunr": "2.3.7", - "@types/node": "20.16.5", + "@types/node": "20.16.10", "@types/node-fetch": "2.6.4", "@types/node-forge": "1.3.11", "@types/node-ipc": "9.2.3", @@ -162,7 +162,7 @@ "postcss": "8.4.38", "postcss-loader": "8.1.1", "prettier": "3.3.3", - "prettier-plugin-tailwindcss": "0.6.6", + "prettier-plugin-tailwindcss": "0.6.8", "process": "0.11.10", "regedit": "3.0.3", "remark-gfm": "4.0.0", @@ -223,7 +223,7 @@ "papaparse": "5.4.1", "proper-lockfile": "4.1.2", "rxjs": "7.8.1", - "tldts": "6.1.46", + "tldts": "6.1.48", "zxcvbn": "4.4.2" }, "bin": { @@ -291,6 +291,16 @@ "@bitwarden/vault-export-core": "file:../tools/export/vault-export/vault-export-core" } }, + "libs/key-management": { + "name": "@bitwarden/key-management", + "version": "0.0.0", + "license": "GPL-3.0", + "dependencies": { + "@bitwarden/angular": "file:../angular", + "@bitwarden/common": "file:../common", + "@bitwarden/components": "file:../components" + } + }, "libs/node": { "name": "@bitwarden/node", "version": "0.0.0", @@ -358,14 +368,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 +1449,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, @@ -4602,6 +4612,10 @@ "resolved": "libs/importer", "link": true }, + "node_modules/@bitwarden/key-management": { + "resolved": "libs/key-management", + "link": true + }, "node_modules/@bitwarden/node": { "resolved": "libs/node", "link": true @@ -5027,12 +5041,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 +5389,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 +5406,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 +5423,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 +5753,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 +6469,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 +7739,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 +7873,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 +8025,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 +8068,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 +8085,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 +8136,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 +8182,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 +8351,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 +8362,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 +8661,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 +8734,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 +9023,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" }, @@ -9401,9 +9078,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.16.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.5.tgz", - "integrity": "sha512-VwYCweNo3ERajwy0IUlqqcyZ8/A7Zwa9ZP3MnENWcB11AejO+tLy3pu850goUW2FC/IJMdZUfKpX/yxL1gymCA==", + "version": "20.16.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.10.tgz", + "integrity": "sha512-vQUKgWTjEIRFCvK6CyriPH3MZYiYlNy0fKiEYHWbcoWLEgs4opurGGKlebrTLqdSMIbXImH6XExNiIyNUv3WpA==", "dev": true, "license": "MIT", "dependencies": { @@ -9486,9 +9163,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 +9180,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 +9194,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 +12341,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 +12562,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 +12576,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 +13301,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 +13588,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 +14335,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 +15046,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 +15162,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 +16241,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 +16365,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 +16445,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 +16994,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 +17717,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 +17770,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 +17796,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 +18195,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 +18580,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 +18641,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 +19319,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 +19654,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 +19706,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 +21370,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 +23187,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 +24743,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 +24801,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 +25312,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 +25700,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 +25867,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 +26665,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 +27794,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 +28105,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 +29290,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 +30228,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 +30274,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 +30286,7 @@ "xmldoc": "^1.1.2" }, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/pend": { @@ -30604,9 +30297,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": { @@ -31276,9 +30969,9 @@ } }, "node_modules/prettier-plugin-tailwindcss": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.6.6.tgz", - "integrity": "sha512-OPva5S7WAsPLEsOuOWXATi13QrCKACCiIonFgIR6V4lYv4QLp++UXVhZSzRbZxXGimkQtQT86CC6fQqTOybGng==", + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.6.8.tgz", + "integrity": "sha512-dGu3kdm7SXPkiW4nzeWKCl3uoImdd5CTZEJGxyypEPL37Wj0HT2pLqjrvSei1nTeuQfO4PUfjeW5cTUNRLZ4sA==", "dev": true, "license": "MIT", "engines": { @@ -31583,9 +31276,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 +31405,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 +31995,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 +32822,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 +32835,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 +32908,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 +33335,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 +33376,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 +33399,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 +33527,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 +34243,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 +34845,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 +35646,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 +35733,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": { @@ -36233,21 +35926,21 @@ } }, "node_modules/tldts": { - "version": "6.1.46", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.46.tgz", - "integrity": "sha512-fw81lXV2CijkNrZAZvee7wegs+EOlTyIuVl/z4q6OUzZHQ1jGL2xQzKXq9geYf/1tzo9LZQLrkcko2m8HLh+rg==", + "version": "6.1.48", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.48.tgz", + "integrity": "sha512-SPbnh1zaSzi/OsmHb1vrPNnYuwJbdWjwo5TbBYYMlTtH3/1DSb41t8bcSxkwDmmbG2q6VLPVvQc7Yf23T+1EEw==", "license": "MIT", "dependencies": { - "tldts-core": "^6.1.46" + "tldts-core": "^6.1.48" }, "bin": { "tldts": "bin/cli.js" } }, "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.48", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.48.tgz", + "integrity": "sha512-3gD9iKn/n2UuFH1uilBviK9gvTNT6iYwdqrj1Vr5mh8FuelvpRNaYVH4pNYqUgOGU4aAdL9X35eLuuj0gRsx+A==", "license": "MIT" }, "node_modules/tmp": { @@ -36477,9 +36170,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 +36975,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 +36999,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 +37244,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 +37411,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 +38284,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 +38880,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 71fb63c37d..ff7292a567 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "@types/koa-json": "2.0.23", "@types/lowdb": "1.0.15", "@types/lunr": "2.3.7", - "@types/node": "20.16.5", + "@types/node": "20.16.10", "@types/node-fetch": "2.6.4", "@types/node-forge": "1.3.11", "@types/node-ipc": "9.2.3", @@ -124,7 +124,7 @@ "postcss": "8.4.38", "postcss-loader": "8.1.1", "prettier": "3.3.3", - "prettier-plugin-tailwindcss": "0.6.6", + "prettier-plugin-tailwindcss": "0.6.8", "process": "0.11.10", "regedit": "3.0.3", "remark-gfm": "4.0.0", @@ -199,7 +199,7 @@ "qrious": "4.0.2", "rxjs": "7.8.1", "tabbable": "6.2.0", - "tldts": "6.1.46", + "tldts": "6.1.48", "utf-8-validate": "6.0.4", "zone.js": "0.13.3", "zxcvbn": "4.4.2" @@ -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", diff --git a/tsconfig.json b/tsconfig.json index 46829a9c30..6764610d2f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -31,6 +31,7 @@ "@bitwarden/vault-export-ui": ["./libs/tools/export/vault-export/vault-export-ui/src"], "@bitwarden/importer/core": ["./libs/importer/src"], "@bitwarden/importer/ui": ["./libs/importer/src/components"], + "@bitwarden/key-management": ["./libs/key-management/src"], "@bitwarden/platform": ["./libs/platform/src"], "@bitwarden/send-ui": ["./libs/tools/send/send-ui/src"], "@bitwarden/node/*": ["./libs/node/src/*"],