Merge branch 'main' into auth/pm-8111/browser-refresh-login-component
This commit is contained in:
commit
3cb428c606
|
@ -114,18 +114,33 @@ apps/desktop/destkop_native/core/src/biometric/ @bitwarden/team-key-management-d
|
||||||
apps/desktop/src/services/native-messaging.service.ts @bitwarden/team-key-management-dev
|
apps/desktop/src/services/native-messaging.service.ts @bitwarden/team-key-management-dev
|
||||||
apps/browser/src/background/nativeMessaging.background.ts @bitwarden/team-key-management-dev
|
apps/browser/src/background/nativeMessaging.background.ts @bitwarden/team-key-management-dev
|
||||||
|
|
||||||
## DevOps team files ##
|
|
||||||
/.github/workflows @bitwarden/dept-devops
|
|
||||||
|
|
||||||
# DevOps for Docker changes.
|
|
||||||
**/Dockerfile @bitwarden/dept-devops
|
|
||||||
**/*.Dockerfile @bitwarden/dept-devops
|
|
||||||
**/.dockerignore @bitwarden/dept-devops
|
|
||||||
**/entrypoint.sh @bitwarden/dept-devops
|
|
||||||
|
|
||||||
## Locales ##
|
## Locales ##
|
||||||
apps/browser/src/_locales/en/messages.json
|
apps/browser/src/_locales/en/messages.json
|
||||||
apps/browser/store/locales/en
|
apps/browser/store/locales/en
|
||||||
apps/cli/src/locales/en/messages.json
|
apps/cli/src/locales/en/messages.json
|
||||||
apps/desktop/src/locales/en/messages.json
|
apps/desktop/src/locales/en/messages.json
|
||||||
apps/web/src/locales/en/messages.json
|
apps/web/src/locales/en/messages.json
|
||||||
|
|
||||||
|
## BRE team owns these workflows ##
|
||||||
|
.github/workflows/brew-bump-desktop.yml @bitwarden/dept-bre
|
||||||
|
.github/workflows/deploy-web.yml @bitwarden/dept-bre
|
||||||
|
.github/workflows/publish-cli.yml @bitwarden/dept-bre
|
||||||
|
.github/workflows/publish-desktop.yml @bitwarden/dept-bre
|
||||||
|
.github/workflows/publish-web.yml @bitwarden/dept-bre
|
||||||
|
.github/workflows/retrieve-current-desktop-rollout.yml @bitwarden/dept-bre
|
||||||
|
.github/workflows/staged-rollout-desktop.yml @bitwarden/dept-bre
|
||||||
|
|
||||||
|
## Shared ownership workflows ##
|
||||||
|
.github/workflows/release-browser.yml
|
||||||
|
.github/workflows/release-cli.yml
|
||||||
|
.github/workflows/release-desktop-beta.yml
|
||||||
|
.github/workflows/release-desktop.yml
|
||||||
|
.github/workflows/release-web.yml
|
||||||
|
.github/workflows/version-auto-bump.yml
|
||||||
|
.github/workflows/version-bump.yml
|
||||||
|
|
||||||
|
## Docker files have shared ownership ##
|
||||||
|
**/Dockerfile
|
||||||
|
**/*.Dockerfile
|
||||||
|
**/.dockerignore
|
||||||
|
**/entrypoint.sh
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
---
|
|
||||||
name: Auto Update Branch
|
name: Auto Update Branch
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
@ -29,7 +28,7 @@ jobs:
|
||||||
run: echo "branch=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT
|
run: echo "branch=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
with:
|
with:
|
||||||
ref: 'eu-web-${{ steps.setup.outputs.branch }}'
|
ref: 'eu-web-${{ steps.setup.outputs.branch }}'
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
---
|
|
||||||
name: Automatic issue responses
|
name: Automatic issue responses
|
||||||
on:
|
on:
|
||||||
issues:
|
issues:
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
---
|
|
||||||
name: Automatic pull request responses
|
name: Automatic pull request responses
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
---
|
|
||||||
name: Bump Desktop Cask
|
name: Bump Desktop Cask
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
---
|
|
||||||
name: Build Browser
|
name: Build Browser
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
@ -43,7 +42,7 @@ jobs:
|
||||||
node_version: ${{ steps.retrieve-node-version.outputs.node_version }}
|
node_version: ${{ steps.retrieve-node-version.outputs.node_version }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Get Package Version
|
- name: Get Package Version
|
||||||
id: gen_vars
|
id: gen_vars
|
||||||
|
@ -73,7 +72,7 @@ jobs:
|
||||||
working-directory: apps/browser
|
working-directory: apps/browser
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Testing locales - extName length
|
- name: Testing locales - extName length
|
||||||
run: |
|
run: |
|
||||||
|
@ -111,7 +110,7 @@ jobs:
|
||||||
_NODE_VERSION: ${{ needs.setup.outputs.node_version }}
|
_NODE_VERSION: ${{ needs.setup.outputs.node_version }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Set up Node
|
- name: Set up Node
|
||||||
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
||||||
|
@ -169,63 +168,63 @@ jobs:
|
||||||
working-directory: browser-source/apps/browser
|
working-directory: browser-source/apps/browser
|
||||||
|
|
||||||
- name: Upload Opera artifact
|
- name: Upload Opera artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: dist-opera-${{ env._BUILD_NUMBER }}.zip
|
name: dist-opera-${{ env._BUILD_NUMBER }}.zip
|
||||||
path: browser-source/apps/browser/dist/dist-opera.zip
|
path: browser-source/apps/browser/dist/dist-opera.zip
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload Opera MV3 artifact (DO NOT USE FOR PROD)
|
- name: Upload Opera MV3 artifact (DO NOT USE FOR PROD)
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: DO-NOT-USE-FOR-PROD-dist-opera-MV3-${{ env._BUILD_NUMBER }}.zip
|
name: DO-NOT-USE-FOR-PROD-dist-opera-MV3-${{ env._BUILD_NUMBER }}.zip
|
||||||
path: browser-source/apps/browser/dist/dist-opera-mv3.zip
|
path: browser-source/apps/browser/dist/dist-opera-mv3.zip
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload Chrome MV3 artifact
|
- name: Upload Chrome MV3 artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: dist-chrome-MV3-${{ env._BUILD_NUMBER }}.zip
|
name: dist-chrome-MV3-${{ env._BUILD_NUMBER }}.zip
|
||||||
path: browser-source/apps/browser/dist/dist-chrome-mv3.zip
|
path: browser-source/apps/browser/dist/dist-chrome-mv3.zip
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload Chrome MV3 Beta artifact (DO NOT USE FOR PROD)
|
- name: Upload Chrome MV3 Beta artifact (DO NOT USE FOR PROD)
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: DO-NOT-USE-FOR-PROD-dist-chrome-MV3-beta-${{ env._BUILD_NUMBER }}.zip
|
name: DO-NOT-USE-FOR-PROD-dist-chrome-MV3-beta-${{ env._BUILD_NUMBER }}.zip
|
||||||
path: browser-source/apps/browser/dist/dist-chrome-mv3-beta.zip
|
path: browser-source/apps/browser/dist/dist-chrome-mv3-beta.zip
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload Firefox artifact
|
- name: Upload Firefox artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: dist-firefox-${{ env._BUILD_NUMBER }}.zip
|
name: dist-firefox-${{ env._BUILD_NUMBER }}.zip
|
||||||
path: browser-source/apps/browser/dist/dist-firefox.zip
|
path: browser-source/apps/browser/dist/dist-firefox.zip
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload Firefox MV3 artifact (DO NOT USE FOR PROD)
|
- name: Upload Firefox MV3 artifact (DO NOT USE FOR PROD)
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: DO-NOT-USE-FOR-PROD-dist-firefox-MV3-${{ env._BUILD_NUMBER }}.zip
|
name: DO-NOT-USE-FOR-PROD-dist-firefox-MV3-${{ env._BUILD_NUMBER }}.zip
|
||||||
path: browser-source/apps/browser/dist/dist-firefox-mv3.zip
|
path: browser-source/apps/browser/dist/dist-firefox-mv3.zip
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload Edge artifact
|
- name: Upload Edge artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: dist-edge-${{ env._BUILD_NUMBER }}.zip
|
name: dist-edge-${{ env._BUILD_NUMBER }}.zip
|
||||||
path: browser-source/apps/browser/dist/dist-edge.zip
|
path: browser-source/apps/browser/dist/dist-edge.zip
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload Edge MV3 artifact (DO NOT USE FOR PROD)
|
- name: Upload Edge MV3 artifact (DO NOT USE FOR PROD)
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: DO-NOT-USE-FOR-PROD-dist-edge-MV3-${{ env._BUILD_NUMBER }}.zip
|
name: DO-NOT-USE-FOR-PROD-dist-edge-MV3-${{ env._BUILD_NUMBER }}.zip
|
||||||
path: browser-source/apps/browser/dist/dist-edge-mv3.zip
|
path: browser-source/apps/browser/dist/dist-edge-mv3.zip
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload browser source
|
- name: Upload browser source
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: browser-source-${{ env._BUILD_NUMBER }}.zip
|
name: browser-source-${{ env._BUILD_NUMBER }}.zip
|
||||||
path: browser-source.zip
|
path: browser-source.zip
|
||||||
|
@ -242,7 +241,7 @@ jobs:
|
||||||
_NODE_VERSION: ${{ needs.setup.outputs.node_version }}
|
_NODE_VERSION: ${{ needs.setup.outputs.node_version }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Set up Node
|
- name: Set up Node
|
||||||
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
||||||
|
@ -340,7 +339,7 @@ jobs:
|
||||||
ls -la
|
ls -la
|
||||||
|
|
||||||
- name: Upload Safari artifact
|
- name: Upload Safari artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: dist-safari-${{ env._BUILD_NUMBER }}.zip
|
name: dist-safari-${{ env._BUILD_NUMBER }}.zip
|
||||||
path: apps/browser/dist/dist-safari.zip
|
path: apps/browser/dist/dist-safari.zip
|
||||||
|
@ -355,7 +354,7 @@ jobs:
|
||||||
- build-safari
|
- build-safari
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Login to Azure
|
- name: Login to Azure
|
||||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
---
|
|
||||||
name: Build CLI
|
name: Build CLI
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
@ -43,7 +42,7 @@ jobs:
|
||||||
node_version: ${{ steps.retrieve-node-version.outputs.node_version }}
|
node_version: ${{ steps.retrieve-node-version.outputs.node_version }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Get Package Version
|
- name: Get Package Version
|
||||||
id: retrieve-package-version
|
id: retrieve-package-version
|
||||||
|
@ -84,7 +83,7 @@ jobs:
|
||||||
_WIN_PKG_VERSION: 3.5
|
_WIN_PKG_VERSION: 3.5
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Setup Unix Vars
|
- name: Setup Unix Vars
|
||||||
run: |
|
run: |
|
||||||
|
@ -130,14 +129,14 @@ jobs:
|
||||||
matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}-sha256-${{ env._PACKAGE_VERSION }}.txt
|
matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}-sha256-${{ env._PACKAGE_VERSION }}.txt
|
||||||
|
|
||||||
- name: Upload unix zip asset
|
- name: Upload unix zip asset
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: bw${{ matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}-${{ env._PACKAGE_VERSION }}.zip
|
name: bw${{ matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}-${{ env._PACKAGE_VERSION }}.zip
|
||||||
path: apps/cli/dist/bw${{ matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}-${{ env._PACKAGE_VERSION }}.zip
|
path: apps/cli/dist/bw${{ matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}-${{ env._PACKAGE_VERSION }}.zip
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload unix checksum asset
|
- name: Upload unix checksum asset
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: bw${{ matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}-sha256-${{ env._PACKAGE_VERSION }}.txt
|
name: bw${{ matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}-sha256-${{ env._PACKAGE_VERSION }}.txt
|
||||||
path: apps/cli/dist/bw${{ matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}-sha256-${{ env._PACKAGE_VERSION }}.txt
|
path: apps/cli/dist/bw${{ matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}-sha256-${{ env._PACKAGE_VERSION }}.txt
|
||||||
|
@ -162,7 +161,7 @@ jobs:
|
||||||
_WIN_PKG_VERSION: 3.5
|
_WIN_PKG_VERSION: 3.5
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Setup Windows builder
|
- name: Setup Windows builder
|
||||||
run: |
|
run: |
|
||||||
|
@ -269,14 +268,14 @@ jobs:
|
||||||
-t sha256 | Out-File -Encoding ASCII ./dist/bw${{ matrix.license_type.artifact_prefix }}-windows-sha256-${env:_PACKAGE_VERSION}.txt
|
-t sha256 | Out-File -Encoding ASCII ./dist/bw${{ matrix.license_type.artifact_prefix }}-windows-sha256-${env:_PACKAGE_VERSION}.txt
|
||||||
|
|
||||||
- name: Upload windows zip asset
|
- name: Upload windows zip asset
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: bw${{ matrix.license_type.artifact_prefix }}-windows-${{ env._PACKAGE_VERSION }}.zip
|
name: bw${{ matrix.license_type.artifact_prefix }}-windows-${{ env._PACKAGE_VERSION }}.zip
|
||||||
path: apps/cli/dist/bw${{ matrix.license_type.artifact_prefix }}-windows-${{ env._PACKAGE_VERSION }}.zip
|
path: apps/cli/dist/bw${{ matrix.license_type.artifact_prefix }}-windows-${{ env._PACKAGE_VERSION }}.zip
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload windows checksum asset
|
- name: Upload windows checksum asset
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: bw${{ matrix.license_type.artifact_prefix }}-windows-sha256-${{ env._PACKAGE_VERSION }}.txt
|
name: bw${{ matrix.license_type.artifact_prefix }}-windows-sha256-${{ env._PACKAGE_VERSION }}.txt
|
||||||
path: apps/cli/dist/bw${{ matrix.license_type.artifact_prefix }}-windows-sha256-${{ env._PACKAGE_VERSION }}.txt
|
path: apps/cli/dist/bw${{ matrix.license_type.artifact_prefix }}-windows-sha256-${{ env._PACKAGE_VERSION }}.txt
|
||||||
|
@ -284,7 +283,7 @@ jobs:
|
||||||
|
|
||||||
- name: Upload Chocolatey asset
|
- name: Upload Chocolatey asset
|
||||||
if: matrix.license_type.build_prefix == 'bit'
|
if: matrix.license_type.build_prefix == 'bit'
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: bitwarden-cli.${{ env._PACKAGE_VERSION }}.nupkg
|
name: bitwarden-cli.${{ env._PACKAGE_VERSION }}.nupkg
|
||||||
path: apps/cli/dist/chocolatey/bitwarden-cli.${{ env._PACKAGE_VERSION }}.nupkg
|
path: apps/cli/dist/chocolatey/bitwarden-cli.${{ env._PACKAGE_VERSION }}.nupkg
|
||||||
|
@ -295,7 +294,7 @@ jobs:
|
||||||
|
|
||||||
- name: Upload NPM Build Directory asset
|
- name: Upload NPM Build Directory asset
|
||||||
if: matrix.license_type.build_prefix == 'bit'
|
if: matrix.license_type.build_prefix == 'bit'
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: bitwarden-cli-${{ env._PACKAGE_VERSION }}-npm-build.zip
|
name: bitwarden-cli-${{ env._PACKAGE_VERSION }}-npm-build.zip
|
||||||
path: apps/cli/bitwarden-cli-${{ env._PACKAGE_VERSION }}-npm-build.zip
|
path: apps/cli/bitwarden-cli-${{ env._PACKAGE_VERSION }}-npm-build.zip
|
||||||
|
@ -312,7 +311,7 @@ jobs:
|
||||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Print environment
|
- name: Print environment
|
||||||
run: |
|
run: |
|
||||||
|
@ -364,14 +363,14 @@ jobs:
|
||||||
run: sudo snap remove bw
|
run: sudo snap remove bw
|
||||||
|
|
||||||
- name: Upload snap asset
|
- name: Upload snap asset
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: bw_${{ env._PACKAGE_VERSION }}_amd64.snap
|
name: bw_${{ env._PACKAGE_VERSION }}_amd64.snap
|
||||||
path: apps/cli/dist/snap/bw_${{ env._PACKAGE_VERSION }}_amd64.snap
|
path: apps/cli/dist/snap/bw_${{ env._PACKAGE_VERSION }}_amd64.snap
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload snap checksum asset
|
- name: Upload snap checksum asset
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: bw-snap-sha256-${{ env._PACKAGE_VERSION }}.txt
|
name: bw-snap-sha256-${{ env._PACKAGE_VERSION }}.txt
|
||||||
path: apps/cli/dist/snap/bw-snap-sha256-${{ env._PACKAGE_VERSION }}.txt
|
path: apps/cli/dist/snap/bw-snap-sha256-${{ env._PACKAGE_VERSION }}.txt
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
---
|
|
||||||
name: Build Desktop
|
name: Build Desktop
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
@ -38,7 +37,7 @@ jobs:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Verify
|
- name: Verify
|
||||||
run: |
|
run: |
|
||||||
|
@ -67,7 +66,7 @@ jobs:
|
||||||
working-directory: apps/desktop
|
working-directory: apps/desktop
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Get Package Version
|
- name: Get Package Version
|
||||||
id: retrieve-version
|
id: retrieve-version
|
||||||
|
@ -140,7 +139,7 @@ jobs:
|
||||||
working-directory: apps/desktop
|
working-directory: apps/desktop
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Set up Node
|
- name: Set up Node
|
||||||
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
||||||
|
@ -169,7 +168,7 @@ jobs:
|
||||||
working-directory: ./
|
working-directory: ./
|
||||||
|
|
||||||
- name: Cache Native Module
|
- name: Cache Native Module
|
||||||
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
|
uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1
|
||||||
id: cache
|
id: cache
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
|
@ -194,42 +193,42 @@ jobs:
|
||||||
run: npm run dist:lin
|
run: npm run dist:lin
|
||||||
|
|
||||||
- name: Upload .deb artifact
|
- name: Upload .deb artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-${{ env._PACKAGE_VERSION }}-amd64.deb
|
name: Bitwarden-${{ env._PACKAGE_VERSION }}-amd64.deb
|
||||||
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-amd64.deb
|
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-amd64.deb
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload .rpm artifact
|
- name: Upload .rpm artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.rpm
|
name: Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.rpm
|
||||||
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.rpm
|
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.rpm
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload .freebsd artifact
|
- name: Upload .freebsd artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-${{ env._PACKAGE_VERSION }}-x64.freebsd
|
name: Bitwarden-${{ env._PACKAGE_VERSION }}-x64.freebsd
|
||||||
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x64.freebsd
|
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x64.freebsd
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload .snap artifact
|
- name: Upload .snap artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: bitwarden_${{ env._PACKAGE_VERSION }}_amd64.snap
|
name: bitwarden_${{ env._PACKAGE_VERSION }}_amd64.snap
|
||||||
path: apps/desktop/dist/bitwarden_${{ env._PACKAGE_VERSION }}_amd64.snap
|
path: apps/desktop/dist/bitwarden_${{ env._PACKAGE_VERSION }}_amd64.snap
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload .AppImage artifact
|
- name: Upload .AppImage artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.AppImage
|
name: Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.AppImage
|
||||||
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.AppImage
|
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.AppImage
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload auto-update artifact
|
- name: Upload auto-update artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: ${{ needs.setup.outputs.release_channel }}-linux.yml
|
name: ${{ needs.setup.outputs.release_channel }}-linux.yml
|
||||||
path: apps/desktop/dist/${{ needs.setup.outputs.release_channel }}-linux.yml
|
path: apps/desktop/dist/${{ needs.setup.outputs.release_channel }}-linux.yml
|
||||||
|
@ -250,7 +249,7 @@ jobs:
|
||||||
NODE_OPTIONS: --max_old_space_size=4096
|
NODE_OPTIONS: --max_old_space_size=4096
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Set up Node
|
- name: Set up Node
|
||||||
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
||||||
|
@ -299,7 +298,7 @@ jobs:
|
||||||
working-directory: ./
|
working-directory: ./
|
||||||
|
|
||||||
- name: Cache Native Module
|
- name: Cache Native Module
|
||||||
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
|
uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1
|
||||||
id: cache
|
id: cache
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
|
@ -354,91 +353,91 @@ jobs:
|
||||||
-NewName bitwarden-${{ env._PACKAGE_VERSION }}-arm64.nsis.7z
|
-NewName bitwarden-${{ env._PACKAGE_VERSION }}-arm64.nsis.7z
|
||||||
|
|
||||||
- name: Upload portable exe artifact
|
- name: Upload portable exe artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-Portable-${{ env._PACKAGE_VERSION }}.exe
|
name: Bitwarden-Portable-${{ env._PACKAGE_VERSION }}.exe
|
||||||
path: apps/desktop/dist/Bitwarden-Portable-${{ env._PACKAGE_VERSION }}.exe
|
path: apps/desktop/dist/Bitwarden-Portable-${{ env._PACKAGE_VERSION }}.exe
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload installer exe artifact
|
- name: Upload installer exe artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-Installer-${{ env._PACKAGE_VERSION }}.exe
|
name: Bitwarden-Installer-${{ env._PACKAGE_VERSION }}.exe
|
||||||
path: apps/desktop/dist/nsis-web/Bitwarden-Installer-${{ env._PACKAGE_VERSION }}.exe
|
path: apps/desktop/dist/nsis-web/Bitwarden-Installer-${{ env._PACKAGE_VERSION }}.exe
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload appx ia32 artifact
|
- name: Upload appx ia32 artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-${{ env._PACKAGE_VERSION }}-ia32.appx
|
name: Bitwarden-${{ env._PACKAGE_VERSION }}-ia32.appx
|
||||||
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-ia32.appx
|
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-ia32.appx
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload store appx ia32 artifact
|
- name: Upload store appx ia32 artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-${{ env._PACKAGE_VERSION }}-ia32-store.appx
|
name: Bitwarden-${{ env._PACKAGE_VERSION }}-ia32-store.appx
|
||||||
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-ia32-store.appx
|
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-ia32-store.appx
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload NSIS ia32 artifact
|
- name: Upload NSIS ia32 artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: bitwarden-${{ env._PACKAGE_VERSION }}-ia32.nsis.7z
|
name: bitwarden-${{ env._PACKAGE_VERSION }}-ia32.nsis.7z
|
||||||
path: apps/desktop/dist/nsis-web/bitwarden-${{ env._PACKAGE_VERSION }}-ia32.nsis.7z
|
path: apps/desktop/dist/nsis-web/bitwarden-${{ env._PACKAGE_VERSION }}-ia32.nsis.7z
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload appx x64 artifact
|
- name: Upload appx x64 artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-${{ env._PACKAGE_VERSION }}-x64.appx
|
name: Bitwarden-${{ env._PACKAGE_VERSION }}-x64.appx
|
||||||
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x64.appx
|
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x64.appx
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload store appx x64 artifact
|
- name: Upload store appx x64 artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-${{ env._PACKAGE_VERSION }}-x64-store.appx
|
name: Bitwarden-${{ env._PACKAGE_VERSION }}-x64-store.appx
|
||||||
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x64-store.appx
|
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x64-store.appx
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload NSIS x64 artifact
|
- name: Upload NSIS x64 artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: bitwarden-${{ env._PACKAGE_VERSION }}-x64.nsis.7z
|
name: bitwarden-${{ env._PACKAGE_VERSION }}-x64.nsis.7z
|
||||||
path: apps/desktop/dist/nsis-web/bitwarden-${{ env._PACKAGE_VERSION }}-x64.nsis.7z
|
path: apps/desktop/dist/nsis-web/bitwarden-${{ env._PACKAGE_VERSION }}-x64.nsis.7z
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload appx ARM64 artifact
|
- name: Upload appx ARM64 artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-${{ env._PACKAGE_VERSION }}-arm64.appx
|
name: Bitwarden-${{ env._PACKAGE_VERSION }}-arm64.appx
|
||||||
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-arm64.appx
|
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-arm64.appx
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload store appx ARM64 artifact
|
- name: Upload store appx ARM64 artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-${{ env._PACKAGE_VERSION }}-arm64-store.appx
|
name: Bitwarden-${{ env._PACKAGE_VERSION }}-arm64-store.appx
|
||||||
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-arm64-store.appx
|
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-arm64-store.appx
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload NSIS ARM64 artifact
|
- name: Upload NSIS ARM64 artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: bitwarden-${{ env._PACKAGE_VERSION }}-arm64.nsis.7z
|
name: bitwarden-${{ env._PACKAGE_VERSION }}-arm64.nsis.7z
|
||||||
path: apps/desktop/dist/nsis-web/bitwarden-${{ env._PACKAGE_VERSION }}-arm64.nsis.7z
|
path: apps/desktop/dist/nsis-web/bitwarden-${{ env._PACKAGE_VERSION }}-arm64.nsis.7z
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload nupkg artifact
|
- name: Upload nupkg artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: bitwarden.${{ env._PACKAGE_VERSION }}.nupkg
|
name: bitwarden.${{ env._PACKAGE_VERSION }}.nupkg
|
||||||
path: apps/desktop/dist/chocolatey/bitwarden.${{ env._PACKAGE_VERSION }}.nupkg
|
path: apps/desktop/dist/chocolatey/bitwarden.${{ env._PACKAGE_VERSION }}.nupkg
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload auto-update artifact
|
- name: Upload auto-update artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: ${{ needs.setup.outputs.release_channel }}.yml
|
name: ${{ needs.setup.outputs.release_channel }}.yml
|
||||||
path: apps/desktop/dist/nsis-web/${{ needs.setup.outputs.release_channel }}.yml
|
path: apps/desktop/dist/nsis-web/${{ needs.setup.outputs.release_channel }}.yml
|
||||||
|
@ -458,7 +457,7 @@ jobs:
|
||||||
working-directory: apps/desktop
|
working-directory: apps/desktop
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Set up Node
|
- name: Set up Node
|
||||||
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
||||||
|
@ -484,14 +483,14 @@ jobs:
|
||||||
|
|
||||||
- name: Cache Build
|
- name: Cache Build
|
||||||
id: build-cache
|
id: build-cache
|
||||||
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
|
uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1
|
||||||
with:
|
with:
|
||||||
path: apps/desktop/build
|
path: apps/desktop/build
|
||||||
key: ${{ runner.os }}-${{ github.run_id }}-build
|
key: ${{ runner.os }}-${{ github.run_id }}-build
|
||||||
|
|
||||||
- name: Cache Safari
|
- name: Cache Safari
|
||||||
id: safari-cache
|
id: safari-cache
|
||||||
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
|
uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1
|
||||||
with:
|
with:
|
||||||
path: apps/browser/dist/Safari
|
path: apps/browser/dist/Safari
|
||||||
key: ${{ runner.os }}-${{ github.run_id }}-safari-extension
|
key: ${{ runner.os }}-${{ github.run_id }}-safari-extension
|
||||||
|
@ -584,7 +583,7 @@ jobs:
|
||||||
working-directory: ./
|
working-directory: ./
|
||||||
|
|
||||||
- name: Cache Native Module
|
- name: Cache Native Module
|
||||||
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
|
uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1
|
||||||
id: cache
|
id: cache
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
|
@ -624,7 +623,7 @@ jobs:
|
||||||
working-directory: apps/desktop
|
working-directory: apps/desktop
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Set up Node
|
- name: Set up Node
|
||||||
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
||||||
|
@ -650,14 +649,14 @@ jobs:
|
||||||
|
|
||||||
- name: Get Build Cache
|
- name: Get Build Cache
|
||||||
id: build-cache
|
id: build-cache
|
||||||
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
|
uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1
|
||||||
with:
|
with:
|
||||||
path: apps/desktop/build
|
path: apps/desktop/build
|
||||||
key: ${{ runner.os }}-${{ github.run_id }}-build
|
key: ${{ runner.os }}-${{ github.run_id }}-build
|
||||||
|
|
||||||
- name: Setup Safari Cache
|
- name: Setup Safari Cache
|
||||||
id: safari-cache
|
id: safari-cache
|
||||||
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
|
uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1
|
||||||
with:
|
with:
|
||||||
path: apps/browser/dist/Safari
|
path: apps/browser/dist/Safari
|
||||||
key: ${{ runner.os }}-${{ github.run_id }}-safari-extension
|
key: ${{ runner.os }}-${{ github.run_id }}-safari-extension
|
||||||
|
@ -750,7 +749,7 @@ jobs:
|
||||||
working-directory: ./
|
working-directory: ./
|
||||||
|
|
||||||
- name: Cache Native Module
|
- name: Cache Native Module
|
||||||
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
|
uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1
|
||||||
id: cache
|
id: cache
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
|
@ -799,28 +798,28 @@ jobs:
|
||||||
run: npm run pack:mac
|
run: npm run pack:mac
|
||||||
|
|
||||||
- name: Upload .zip artifact
|
- name: Upload .zip artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal-mac.zip
|
name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal-mac.zip
|
||||||
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-universal-mac.zip
|
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-universal-mac.zip
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload .dmg artifact
|
- name: Upload .dmg artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg
|
name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg
|
||||||
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg
|
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload .dmg blockmap artifact
|
- name: Upload .dmg blockmap artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg.blockmap
|
name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg.blockmap
|
||||||
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg.blockmap
|
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg.blockmap
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload auto-update artifact
|
- name: Upload auto-update artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: ${{ needs.setup.outputs.release_channel }}-mac.yml
|
name: ${{ needs.setup.outputs.release_channel }}-mac.yml
|
||||||
path: apps/desktop/dist/${{ needs.setup.outputs.release_channel }}-mac.yml
|
path: apps/desktop/dist/${{ needs.setup.outputs.release_channel }}-mac.yml
|
||||||
|
@ -843,7 +842,7 @@ jobs:
|
||||||
working-directory: apps/desktop
|
working-directory: apps/desktop
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Set up Node
|
- name: Set up Node
|
||||||
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
||||||
|
@ -869,14 +868,14 @@ jobs:
|
||||||
|
|
||||||
- name: Get Build Cache
|
- name: Get Build Cache
|
||||||
id: build-cache
|
id: build-cache
|
||||||
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
|
uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1
|
||||||
with:
|
with:
|
||||||
path: apps/desktop/build
|
path: apps/desktop/build
|
||||||
key: ${{ runner.os }}-${{ github.run_id }}-build
|
key: ${{ runner.os }}-${{ github.run_id }}-build
|
||||||
|
|
||||||
- name: Setup Safari Cache
|
- name: Setup Safari Cache
|
||||||
id: safari-cache
|
id: safari-cache
|
||||||
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
|
uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1
|
||||||
with:
|
with:
|
||||||
path: apps/browser/dist/Safari
|
path: apps/browser/dist/Safari
|
||||||
key: ${{ runner.os }}-${{ github.run_id }}-safari-extension
|
key: ${{ runner.os }}-${{ github.run_id }}-safari-extension
|
||||||
|
@ -976,7 +975,7 @@ jobs:
|
||||||
working-directory: ./
|
working-directory: ./
|
||||||
|
|
||||||
- name: Cache Native Module
|
- name: Cache Native Module
|
||||||
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
|
uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1
|
||||||
id: cache
|
id: cache
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
|
@ -1025,7 +1024,7 @@ jobs:
|
||||||
run: npm run pack:mac:mas
|
run: npm run pack:mac:mas
|
||||||
|
|
||||||
- name: Upload .pkg artifact
|
- name: Upload .pkg artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal.pkg
|
name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal.pkg
|
||||||
path: apps/desktop/dist/mas-universal/Bitwarden-${{ env._PACKAGE_VERSION }}-universal.pkg
|
path: apps/desktop/dist/mas-universal/Bitwarden-${{ env._PACKAGE_VERSION }}-universal.pkg
|
||||||
|
@ -1090,7 +1089,7 @@ jobs:
|
||||||
working-directory: apps/desktop
|
working-directory: apps/desktop
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Set up Node
|
- name: Set up Node
|
||||||
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
||||||
|
@ -1111,14 +1110,14 @@ jobs:
|
||||||
|
|
||||||
- name: Get Build Cache
|
- name: Get Build Cache
|
||||||
id: build-cache
|
id: build-cache
|
||||||
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
|
uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1
|
||||||
with:
|
with:
|
||||||
path: apps/desktop/build
|
path: apps/desktop/build
|
||||||
key: ${{ runner.os }}-${{ github.run_id }}-build
|
key: ${{ runner.os }}-${{ github.run_id }}-build
|
||||||
|
|
||||||
- name: Setup Safari Cache
|
- name: Setup Safari Cache
|
||||||
id: safari-cache
|
id: safari-cache
|
||||||
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
|
uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1
|
||||||
with:
|
with:
|
||||||
path: apps/browser/dist/Safari
|
path: apps/browser/dist/Safari
|
||||||
key: ${{ runner.os }}-${{ github.run_id }}-safari-extension
|
key: ${{ runner.os }}-${{ github.run_id }}-safari-extension
|
||||||
|
@ -1211,7 +1210,7 @@ jobs:
|
||||||
working-directory: ./
|
working-directory: ./
|
||||||
|
|
||||||
- name: Cache Native Module
|
- name: Cache Native Module
|
||||||
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
|
uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1
|
||||||
id: cache
|
id: cache
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
|
@ -1263,7 +1262,7 @@ jobs:
|
||||||
zip -r Bitwarden-${{ env._PACKAGE_VERSION }}-masdev-universal.zip Bitwarden.app
|
zip -r Bitwarden-${{ env._PACKAGE_VERSION }}-masdev-universal.zip Bitwarden.app
|
||||||
|
|
||||||
- name: Upload masdev artifact
|
- name: Upload masdev artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-${{ env._PACKAGE_VERSION }}-masdev-universal.zip
|
name: Bitwarden-${{ env._PACKAGE_VERSION }}-masdev-universal.zip
|
||||||
path: apps/desktop/dist/mas-dev-universal/Bitwarden-${{ env._PACKAGE_VERSION }}-masdev-universal.zip
|
path: apps/desktop/dist/mas-dev-universal/Bitwarden-${{ env._PACKAGE_VERSION }}-masdev-universal.zip
|
||||||
|
@ -1281,7 +1280,7 @@ jobs:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Login to Azure
|
- name: Login to Azure
|
||||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
---
|
|
||||||
name: Build Web
|
name: Build Web
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
@ -45,7 +44,7 @@ jobs:
|
||||||
node_version: ${{ steps.retrieve-node-version.outputs.node_version }}
|
node_version: ${{ steps.retrieve-node-version.outputs.node_version }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Get GitHub sha as version
|
- name: Get GitHub sha as version
|
||||||
id: version
|
id: version
|
||||||
|
@ -91,7 +90,7 @@ jobs:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Set up Node
|
- name: Set up Node
|
||||||
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
|
||||||
|
@ -130,7 +129,7 @@ jobs:
|
||||||
run: zip -r web-${{ env._VERSION }}-${{ matrix.name }}.zip build
|
run: zip -r web-${{ env._VERSION }}-${{ matrix.name }}.zip build
|
||||||
|
|
||||||
- name: Upload ${{ matrix.name }} artifact
|
- name: Upload ${{ matrix.name }} artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: web-${{ env._VERSION }}-${{ matrix.name }}.zip
|
name: web-${{ env._VERSION }}-${{ matrix.name }}.zip
|
||||||
path: apps/web/web-${{ env._VERSION }}-${{ matrix.name }}.zip
|
path: apps/web/web-${{ env._VERSION }}-${{ matrix.name }}.zip
|
||||||
|
@ -157,7 +156,7 @@ jobs:
|
||||||
_VERSION: ${{ needs.setup.outputs.version }}
|
_VERSION: ${{ needs.setup.outputs.version }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Check Branch to Publish
|
- name: Check Branch to Publish
|
||||||
env:
|
env:
|
||||||
|
@ -234,7 +233,7 @@ jobs:
|
||||||
run: echo "name=$_AZ_REGISTRY/${PROJECT_NAME}:${IMAGE_TAG}" >> $GITHUB_OUTPUT
|
run: echo "name=$_AZ_REGISTRY/${PROJECT_NAME}:${IMAGE_TAG}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Build Docker image
|
- name: Build Docker image
|
||||||
uses: docker/build-push-action@32945a339266b759abcbdc89316275140b0fc960 # v6.8.0
|
uses: docker/build-push-action@4f58ea79222b3b9dc2c8bbdd6debcef730109a75 # v6.9.0
|
||||||
with:
|
with:
|
||||||
context: apps/web
|
context: apps/web
|
||||||
file: apps/web/Dockerfile
|
file: apps/web/Dockerfile
|
||||||
|
@ -255,7 +254,7 @@ jobs:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Login to Azure
|
- name: Login to Azure
|
||||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
---
|
|
||||||
name: Chromatic
|
name: Chromatic
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
@ -25,7 +24,7 @@ jobs:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Check out repo
|
- name: Check out repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
@ -44,7 +43,7 @@ jobs:
|
||||||
|
|
||||||
- name: Cache NPM
|
- name: Cache NPM
|
||||||
id: npm-cache
|
id: npm-cache
|
||||||
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
|
uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1
|
||||||
with:
|
with:
|
||||||
path: "~/.npm"
|
path: "~/.npm"
|
||||||
key: ${{ runner.os }}-npm-chromatic-${{ hashFiles('**/package-lock.json') }}
|
key: ${{ runner.os }}-npm-chromatic-${{ hashFiles('**/package-lock.json') }}
|
||||||
|
@ -57,7 +56,7 @@ jobs:
|
||||||
run: npm run build-storybook:ci
|
run: npm run build-storybook:ci
|
||||||
|
|
||||||
- name: Publish to Chromatic
|
- name: Publish to Chromatic
|
||||||
uses: chromaui/action@f4e60a7072abcac4203f4ca50613f28e199a52ba # v11.10.4
|
uses: chromaui/action@bbbf288765438d5fd2be13e1d80d542a39e74108 # v11.12.1
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
|
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
---
|
|
||||||
name: Crowdin Sync
|
name: Crowdin Sync
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
@ -23,7 +22,7 @@ jobs:
|
||||||
crowdin_project_id: "308189"
|
crowdin_project_id: "308189"
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Login to Azure
|
- name: Login to Azure
|
||||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
---
|
|
||||||
name: Deploy Web Vault
|
name: Deploy Web Vault
|
||||||
run-name: Deploy Web Vault to ${{ inputs.environment }} from ${{ inputs.branch-or-tag }}
|
run-name: Deploy Web Vault to ${{ inputs.environment }} from ${{ inputs.branch-or-tag }}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
---
|
|
||||||
name: Enforce PR labels
|
name: Enforce PR labels
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
---
|
|
||||||
name: Lint
|
name: Lint
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
@ -21,7 +20,7 @@ jobs:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Lint filenames (no capital characters)
|
- name: Lint filenames (no capital characters)
|
||||||
run: |
|
run: |
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
---
|
|
||||||
name: Locales lint for Crowdin
|
name: Locales lint for Crowdin
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
@ -15,9 +14,9 @@ jobs:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
- name: Checkout base branch repo
|
- name: Checkout base branch repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.pull_request.base.sha }}
|
ref: ${{ github.event.pull_request.base.sha }}
|
||||||
path: base
|
path: base
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
---
|
|
||||||
name: Publish CLI
|
name: Publish CLI
|
||||||
run-name: Publish CLI ${{ inputs.publish_type }}
|
run-name: Publish CLI ${{ inputs.publish_type }}
|
||||||
|
|
||||||
|
@ -92,7 +91,7 @@ jobs:
|
||||||
_PKG_VERSION: ${{ needs.setup.outputs.release-version }}
|
_PKG_VERSION: ${{ needs.setup.outputs.release-version }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Login to Azure
|
- name: Login to Azure
|
||||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||||
|
@ -129,7 +128,7 @@ jobs:
|
||||||
_PKG_VERSION: ${{ needs.setup.outputs.release-version }}
|
_PKG_VERSION: ${{ needs.setup.outputs.release-version }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Login to Azure
|
- name: Login to Azure
|
||||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||||
|
@ -169,7 +168,7 @@ jobs:
|
||||||
_PKG_VERSION: ${{ needs.setup.outputs.release-version }}
|
_PKG_VERSION: ${{ needs.setup.outputs.release-version }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Login to Azure
|
- name: Login to Azure
|
||||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
---
|
|
||||||
name: Publish Desktop
|
name: Publish Desktop
|
||||||
run-name: Publish Desktop ${{ inputs.publish_type }}
|
run-name: Publish Desktop ${{ inputs.publish_type }}
|
||||||
|
|
||||||
|
@ -184,7 +183,7 @@ jobs:
|
||||||
_RELEASE_TAG: ${{ needs.setup.outputs.tag-name }}
|
_RELEASE_TAG: ${{ needs.setup.outputs.tag-name }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Repo
|
- name: Checkout Repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Login to Azure
|
- name: Login to Azure
|
||||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||||
|
@ -228,7 +227,7 @@ jobs:
|
||||||
_RELEASE_TAG: ${{ needs.setup.outputs.tag-name }}
|
_RELEASE_TAG: ${{ needs.setup.outputs.tag-name }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Repo
|
- name: Checkout Repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Print Environment
|
- name: Print Environment
|
||||||
run: |
|
run: |
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
---
|
|
||||||
name: Publish Web
|
name: Publish Web
|
||||||
run-name: Publish Web ${{ inputs.publish_type }}
|
run-name: Publish Web ${{ inputs.publish_type }}
|
||||||
|
|
||||||
|
@ -27,7 +26,7 @@ jobs:
|
||||||
tag_version: ${{ steps.version.outputs.tag }}
|
tag_version: ${{ steps.version.outputs.tag }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Branch check
|
- name: Branch check
|
||||||
if: ${{ inputs.publish_type != 'Dry Run' }}
|
if: ${{ inputs.publish_type != 'Dry Run' }}
|
||||||
|
@ -67,7 +66,7 @@ jobs:
|
||||||
echo "Github Release Option: $_RELEASE_OPTION"
|
echo "Github Release Option: $_RELEASE_OPTION"
|
||||||
|
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
########## ACR ##########
|
########## ACR ##########
|
||||||
- name: Login to Azure - PROD Subscription
|
- name: Login to Azure - PROD Subscription
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
---
|
|
||||||
name: Release Browser
|
name: Release Browser
|
||||||
run-name: Release Browser ${{ inputs.release_type }}
|
run-name: Release Browser ${{ inputs.release_type }}
|
||||||
|
|
||||||
|
@ -27,7 +26,7 @@ jobs:
|
||||||
release-version: ${{ steps.version.outputs.version }}
|
release-version: ${{ steps.version.outputs.version }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Branch check
|
- name: Branch check
|
||||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||||
|
@ -56,7 +55,7 @@ jobs:
|
||||||
needs: setup
|
needs: setup
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Testing locales - extName length
|
- name: Testing locales - extName length
|
||||||
run: |
|
run: |
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
---
|
|
||||||
name: Release CLI
|
name: Release CLI
|
||||||
run-name: Release CLI ${{ inputs.release_type }}
|
run-name: Release CLI ${{ inputs.release_type }}
|
||||||
|
|
||||||
|
@ -27,7 +26,7 @@ jobs:
|
||||||
release-version: ${{ steps.version.outputs.version }}
|
release-version: ${{ steps.version.outputs.version }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Branch check
|
- name: Branch check
|
||||||
if: ${{ inputs.release_type != 'Dry Run' }}
|
if: ${{ inputs.release_type != 'Dry Run' }}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
---
|
|
||||||
name: Release Desktop Beta
|
name: Release Desktop Beta
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
@ -24,7 +23,7 @@ jobs:
|
||||||
node_version: ${{ steps.retrieve-node-version.outputs.node_version }}
|
node_version: ${{ steps.retrieve-node-version.outputs.node_version }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Branch check
|
- name: Branch check
|
||||||
run: |
|
run: |
|
||||||
|
@ -125,7 +124,7 @@ jobs:
|
||||||
working-directory: apps/desktop
|
working-directory: apps/desktop
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
with:
|
with:
|
||||||
ref: ${{ needs.setup.outputs.branch-name }}
|
ref: ${{ needs.setup.outputs.branch-name }}
|
||||||
|
|
||||||
|
@ -159,42 +158,42 @@ jobs:
|
||||||
run: npm run dist:lin
|
run: npm run dist:lin
|
||||||
|
|
||||||
- name: Upload .deb artifact
|
- name: Upload .deb artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-${{ env._PACKAGE_VERSION }}-amd64.deb
|
name: Bitwarden-${{ env._PACKAGE_VERSION }}-amd64.deb
|
||||||
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-amd64.deb
|
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-amd64.deb
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload .rpm artifact
|
- name: Upload .rpm artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.rpm
|
name: Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.rpm
|
||||||
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.rpm
|
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.rpm
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload .freebsd artifact
|
- name: Upload .freebsd artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-${{ env._PACKAGE_VERSION }}-x64.freebsd
|
name: Bitwarden-${{ env._PACKAGE_VERSION }}-x64.freebsd
|
||||||
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x64.freebsd
|
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x64.freebsd
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload .snap artifact
|
- name: Upload .snap artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: bitwarden_${{ env._PACKAGE_VERSION }}_amd64.snap
|
name: bitwarden_${{ env._PACKAGE_VERSION }}_amd64.snap
|
||||||
path: apps/desktop/dist/bitwarden_${{ env._PACKAGE_VERSION }}_amd64.snap
|
path: apps/desktop/dist/bitwarden_${{ env._PACKAGE_VERSION }}_amd64.snap
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload .AppImage artifact
|
- name: Upload .AppImage artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.AppImage
|
name: Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.AppImage
|
||||||
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.AppImage
|
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.AppImage
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload auto-update artifact
|
- name: Upload auto-update artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: ${{ needs.setup.outputs.release-channel }}-linux.yml
|
name: ${{ needs.setup.outputs.release-channel }}-linux.yml
|
||||||
path: apps/desktop/dist/${{ needs.setup.outputs.release-channel }}-linux.yml
|
path: apps/desktop/dist/${{ needs.setup.outputs.release-channel }}-linux.yml
|
||||||
|
@ -215,7 +214,7 @@ jobs:
|
||||||
NODE_OPTIONS: --max_old_space_size=4096
|
NODE_OPTIONS: --max_old_space_size=4096
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
with:
|
with:
|
||||||
ref: ${{ needs.setup.outputs.branch-name }}
|
ref: ${{ needs.setup.outputs.branch-name }}
|
||||||
|
|
||||||
|
@ -300,91 +299,91 @@ jobs:
|
||||||
-NewName bitwarden-${{ env._PACKAGE_VERSION }}-arm64.nsis.7z
|
-NewName bitwarden-${{ env._PACKAGE_VERSION }}-arm64.nsis.7z
|
||||||
|
|
||||||
- name: Upload portable exe artifact
|
- name: Upload portable exe artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-Portable-${{ env._PACKAGE_VERSION }}.exe
|
name: Bitwarden-Portable-${{ env._PACKAGE_VERSION }}.exe
|
||||||
path: apps/desktop/dist/Bitwarden-Portable-${{ env._PACKAGE_VERSION }}.exe
|
path: apps/desktop/dist/Bitwarden-Portable-${{ env._PACKAGE_VERSION }}.exe
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload installer exe artifact
|
- name: Upload installer exe artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-Installer-${{ env._PACKAGE_VERSION }}.exe
|
name: Bitwarden-Installer-${{ env._PACKAGE_VERSION }}.exe
|
||||||
path: apps/desktop/dist/nsis-web/Bitwarden-Installer-${{ env._PACKAGE_VERSION }}.exe
|
path: apps/desktop/dist/nsis-web/Bitwarden-Installer-${{ env._PACKAGE_VERSION }}.exe
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload appx ia32 artifact
|
- name: Upload appx ia32 artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-${{ env._PACKAGE_VERSION }}-ia32.appx
|
name: Bitwarden-${{ env._PACKAGE_VERSION }}-ia32.appx
|
||||||
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-ia32.appx
|
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-ia32.appx
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload store appx ia32 artifact
|
- name: Upload store appx ia32 artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-${{ env._PACKAGE_VERSION }}-ia32-store.appx
|
name: Bitwarden-${{ env._PACKAGE_VERSION }}-ia32-store.appx
|
||||||
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-ia32-store.appx
|
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-ia32-store.appx
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload NSIS ia32 artifact
|
- name: Upload NSIS ia32 artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: bitwarden-${{ env._PACKAGE_VERSION }}-ia32.nsis.7z
|
name: bitwarden-${{ env._PACKAGE_VERSION }}-ia32.nsis.7z
|
||||||
path: apps/desktop/dist/nsis-web/bitwarden-${{ env._PACKAGE_VERSION }}-ia32.nsis.7z
|
path: apps/desktop/dist/nsis-web/bitwarden-${{ env._PACKAGE_VERSION }}-ia32.nsis.7z
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload appx x64 artifact
|
- name: Upload appx x64 artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-${{ env._PACKAGE_VERSION }}-x64.appx
|
name: Bitwarden-${{ env._PACKAGE_VERSION }}-x64.appx
|
||||||
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x64.appx
|
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x64.appx
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload store appx x64 artifact
|
- name: Upload store appx x64 artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-${{ env._PACKAGE_VERSION }}-x64-store.appx
|
name: Bitwarden-${{ env._PACKAGE_VERSION }}-x64-store.appx
|
||||||
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x64-store.appx
|
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x64-store.appx
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload NSIS x64 artifact
|
- name: Upload NSIS x64 artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: bitwarden-${{ env._PACKAGE_VERSION }}-x64.nsis.7z
|
name: bitwarden-${{ env._PACKAGE_VERSION }}-x64.nsis.7z
|
||||||
path: apps/desktop/dist/nsis-web/bitwarden-${{ env._PACKAGE_VERSION }}-x64.nsis.7z
|
path: apps/desktop/dist/nsis-web/bitwarden-${{ env._PACKAGE_VERSION }}-x64.nsis.7z
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload appx ARM64 artifact
|
- name: Upload appx ARM64 artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-${{ env._PACKAGE_VERSION }}-arm64.appx
|
name: Bitwarden-${{ env._PACKAGE_VERSION }}-arm64.appx
|
||||||
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-arm64.appx
|
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-arm64.appx
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload store appx ARM64 artifact
|
- name: Upload store appx ARM64 artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-${{ env._PACKAGE_VERSION }}-arm64-store.appx
|
name: Bitwarden-${{ env._PACKAGE_VERSION }}-arm64-store.appx
|
||||||
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-arm64-store.appx
|
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-arm64-store.appx
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload NSIS ARM64 artifact
|
- name: Upload NSIS ARM64 artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: bitwarden-${{ env._PACKAGE_VERSION }}-arm64.nsis.7z
|
name: bitwarden-${{ env._PACKAGE_VERSION }}-arm64.nsis.7z
|
||||||
path: apps/desktop/dist/nsis-web/bitwarden-${{ env._PACKAGE_VERSION }}-arm64.nsis.7z
|
path: apps/desktop/dist/nsis-web/bitwarden-${{ env._PACKAGE_VERSION }}-arm64.nsis.7z
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload nupkg artifact
|
- name: Upload nupkg artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: bitwarden.${{ env._PACKAGE_VERSION }}.nupkg
|
name: bitwarden.${{ env._PACKAGE_VERSION }}.nupkg
|
||||||
path: apps/desktop/dist/chocolatey/bitwarden.${{ env._PACKAGE_VERSION }}.nupkg
|
path: apps/desktop/dist/chocolatey/bitwarden.${{ env._PACKAGE_VERSION }}.nupkg
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload auto-update artifact
|
- name: Upload auto-update artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: ${{ needs.setup.outputs.release-channel }}.yml
|
name: ${{ needs.setup.outputs.release-channel }}.yml
|
||||||
path: apps/desktop/dist/nsis-web/${{ needs.setup.outputs.release-channel }}.yml
|
path: apps/desktop/dist/nsis-web/${{ needs.setup.outputs.release-channel }}.yml
|
||||||
|
@ -404,7 +403,7 @@ jobs:
|
||||||
working-directory: apps/desktop
|
working-directory: apps/desktop
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
with:
|
with:
|
||||||
ref: ${{ needs.setup.outputs.branch-name }}
|
ref: ${{ needs.setup.outputs.branch-name }}
|
||||||
|
|
||||||
|
@ -427,14 +426,14 @@ jobs:
|
||||||
|
|
||||||
- name: Cache Build
|
- name: Cache Build
|
||||||
id: build-cache
|
id: build-cache
|
||||||
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
|
uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1
|
||||||
with:
|
with:
|
||||||
path: apps/desktop/build
|
path: apps/desktop/build
|
||||||
key: ${{ runner.os }}-${{ github.run_id }}-build
|
key: ${{ runner.os }}-${{ github.run_id }}-build
|
||||||
|
|
||||||
- name: Cache Safari
|
- name: Cache Safari
|
||||||
id: safari-cache
|
id: safari-cache
|
||||||
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
|
uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1
|
||||||
with:
|
with:
|
||||||
path: apps/browser/dist/Safari
|
path: apps/browser/dist/Safari
|
||||||
key: ${{ runner.os }}-${{ github.run_id }}-safari-extension
|
key: ${{ runner.os }}-${{ github.run_id }}-safari-extension
|
||||||
|
@ -538,7 +537,7 @@ jobs:
|
||||||
working-directory: apps/desktop
|
working-directory: apps/desktop
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
with:
|
with:
|
||||||
ref: ${{ needs.setup.outputs.branch-name }}
|
ref: ${{ needs.setup.outputs.branch-name }}
|
||||||
|
|
||||||
|
@ -561,14 +560,14 @@ jobs:
|
||||||
|
|
||||||
- name: Get Build Cache
|
- name: Get Build Cache
|
||||||
id: build-cache
|
id: build-cache
|
||||||
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
|
uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1
|
||||||
with:
|
with:
|
||||||
path: apps/desktop/build
|
path: apps/desktop/build
|
||||||
key: ${{ runner.os }}-${{ github.run_id }}-build
|
key: ${{ runner.os }}-${{ github.run_id }}-build
|
||||||
|
|
||||||
- name: Setup Safari Cache
|
- name: Setup Safari Cache
|
||||||
id: safari-cache
|
id: safari-cache
|
||||||
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
|
uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1
|
||||||
with:
|
with:
|
||||||
path: apps/browser/dist/Safari
|
path: apps/browser/dist/Safari
|
||||||
key: ${{ runner.os }}-${{ github.run_id }}-safari-extension
|
key: ${{ runner.os }}-${{ github.run_id }}-safari-extension
|
||||||
|
@ -708,28 +707,28 @@ jobs:
|
||||||
run: npm run pack:mac
|
run: npm run pack:mac
|
||||||
|
|
||||||
- name: Upload .zip artifact
|
- name: Upload .zip artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal-mac.zip
|
name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal-mac.zip
|
||||||
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-universal-mac.zip
|
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-universal-mac.zip
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload .dmg artifact
|
- name: Upload .dmg artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg
|
name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg
|
||||||
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg
|
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload .dmg blockmap artifact
|
- name: Upload .dmg blockmap artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg.blockmap
|
name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg.blockmap
|
||||||
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg.blockmap
|
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg.blockmap
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload auto-update artifact
|
- name: Upload auto-update artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: ${{ needs.setup.outputs.release-channel }}-mac.yml
|
name: ${{ needs.setup.outputs.release-channel }}-mac.yml
|
||||||
path: apps/desktop/dist/${{ needs.setup.outputs.release-channel }}-mac.yml
|
path: apps/desktop/dist/${{ needs.setup.outputs.release-channel }}-mac.yml
|
||||||
|
@ -751,7 +750,7 @@ jobs:
|
||||||
working-directory: apps/desktop
|
working-directory: apps/desktop
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
with:
|
with:
|
||||||
ref: ${{ needs.setup.outputs.branch-name }}
|
ref: ${{ needs.setup.outputs.branch-name }}
|
||||||
|
|
||||||
|
@ -774,14 +773,14 @@ jobs:
|
||||||
|
|
||||||
- name: Get Build Cache
|
- name: Get Build Cache
|
||||||
id: build-cache
|
id: build-cache
|
||||||
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
|
uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1
|
||||||
with:
|
with:
|
||||||
path: apps/desktop/build
|
path: apps/desktop/build
|
||||||
key: ${{ runner.os }}-${{ github.run_id }}-build
|
key: ${{ runner.os }}-${{ github.run_id }}-build
|
||||||
|
|
||||||
- name: Setup Safari Cache
|
- name: Setup Safari Cache
|
||||||
id: safari-cache
|
id: safari-cache
|
||||||
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
|
uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1
|
||||||
with:
|
with:
|
||||||
path: apps/browser/dist/Safari
|
path: apps/browser/dist/Safari
|
||||||
key: ${{ runner.os }}-${{ github.run_id }}-safari-extension
|
key: ${{ runner.os }}-${{ github.run_id }}-safari-extension
|
||||||
|
@ -916,7 +915,7 @@ jobs:
|
||||||
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
|
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
|
||||||
|
|
||||||
- name: Upload .pkg artifact
|
- name: Upload .pkg artifact
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal.pkg
|
name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal.pkg
|
||||||
path: apps/desktop/dist/mas-universal/Bitwarden-${{ env._PACKAGE_VERSION }}-universal.pkg
|
path: apps/desktop/dist/mas-universal/Bitwarden-${{ env._PACKAGE_VERSION }}-universal.pkg
|
||||||
|
@ -1011,7 +1010,7 @@ jobs:
|
||||||
- release
|
- release
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Setup git config
|
- name: Setup git config
|
||||||
run: |
|
run: |
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
---
|
|
||||||
name: Release Desktop
|
name: Release Desktop
|
||||||
run-name: Release Desktop ${{ inputs.release_type }}
|
run-name: Release Desktop ${{ inputs.release_type }}
|
||||||
|
|
||||||
|
@ -27,7 +26,7 @@ jobs:
|
||||||
release-channel: ${{ steps.release-channel.outputs.channel }}
|
release-channel: ${{ steps.release-channel.outputs.channel }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Branch check
|
- name: Branch check
|
||||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
---
|
|
||||||
name: Release Web
|
name: Release Web
|
||||||
run-name: Release Web ${{ inputs.release_type }}
|
run-name: Release Web ${{ inputs.release_type }}
|
||||||
|
|
||||||
|
@ -24,7 +23,7 @@ jobs:
|
||||||
tag_version: ${{ steps.version.outputs.tag }}
|
tag_version: ${{ steps.version.outputs.tag }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Branch check
|
- name: Branch check
|
||||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
---
|
|
||||||
name: Retrieve Current Desktop Rollout
|
name: Retrieve Current Desktop Rollout
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
---
|
|
||||||
name: Scan
|
name: Scan
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
@ -27,12 +26,12 @@ jobs:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Check out repo
|
- name: Check out repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
|
|
||||||
- name: Scan with Checkmarx
|
- name: Scan with Checkmarx
|
||||||
uses: checkmarx/ast-github-action@9fda5a4a2c297608117a5a56af424502a9192e57 # 2.0.34
|
uses: checkmarx/ast-github-action@f0869bd1a37fddc06499a096101e6c900e815d81 # 2.0.36
|
||||||
env:
|
env:
|
||||||
INCREMENTAL: "${{ contains(github.event_name, 'pull_request') && '--sast-incremental' || '' }}"
|
INCREMENTAL: "${{ contains(github.event_name, 'pull_request') && '--sast-incremental' || '' }}"
|
||||||
with:
|
with:
|
||||||
|
@ -47,7 +46,7 @@ jobs:
|
||||||
--output-path . ${{ env.INCREMENTAL }}
|
--output-path . ${{ env.INCREMENTAL }}
|
||||||
|
|
||||||
- name: Upload Checkmarx results to GitHub
|
- name: Upload Checkmarx results to GitHub
|
||||||
uses: github/codeql-action/upload-sarif@461ef6c76dfe95d5c364de2f431ddbd31a417628 # v3.26.9
|
uses: github/codeql-action/upload-sarif@f779452ac5af1c261dce0346a8f964149f49322b # v3.26.13
|
||||||
with:
|
with:
|
||||||
sarif_file: cx_result.sarif
|
sarif_file: cx_result.sarif
|
||||||
|
|
||||||
|
@ -61,13 +60,13 @@ jobs:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Check out repo
|
- name: Check out repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
|
|
||||||
- name: Scan with SonarCloud
|
- name: Scan with SonarCloud
|
||||||
uses: sonarsource/sonarcloud-github-action@eb211723266fe8e83102bac7361f0a05c3ac1d1b # v3.0.0
|
uses: sonarsource/sonarcloud-github-action@383f7e52eae3ab0510c3cb0e7d9d150bbaeab838 # v3.1.0
|
||||||
env:
|
env:
|
||||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
---
|
|
||||||
name: Staged Rollout Desktop
|
name: Staged Rollout Desktop
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
---
|
|
||||||
name: 'Close stale issues and PRs'
|
name: 'Close stale issues and PRs'
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
---
|
|
||||||
name: Testing
|
name: Testing
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
@ -41,7 +40,7 @@ jobs:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Check out repo
|
- name: Check out repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Get Node Version
|
- name: Get Node Version
|
||||||
id: retrieve-node-version
|
id: retrieve-node-version
|
||||||
|
@ -86,13 +85,13 @@ jobs:
|
||||||
fail-on-error: true
|
fail-on-error: true
|
||||||
|
|
||||||
- name: Upload coverage to codecov.io
|
- name: Upload coverage to codecov.io
|
||||||
uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # v4.5.0
|
uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4.6.0
|
||||||
if: ${{ needs.check-test-secrets.outputs.available == 'true' }}
|
if: ${{ needs.check-test-secrets.outputs.available == 'true' }}
|
||||||
env:
|
env:
|
||||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
|
||||||
- name: Upload results to codecov.io
|
- name: Upload results to codecov.io
|
||||||
uses: codecov/test-results-action@1b5b448b98e58ba90d1a1a1d9fcb72ca2263be46 # v1.0.0
|
uses: codecov/test-results-action@9739113ad922ea0a9abb4b2c0f8bf6a4aa8ef820 # v1.0.1
|
||||||
if: ${{ needs.check-test-secrets.outputs.available == 'true' }}
|
if: ${{ needs.check-test-secrets.outputs.available == 'true' }}
|
||||||
env:
|
env:
|
||||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
@ -121,7 +120,7 @@ jobs:
|
||||||
sudo apt-get install -y gnome-keyring dbus-x11
|
sudo apt-get install -y gnome-keyring dbus-x11
|
||||||
|
|
||||||
- name: Check out repo
|
- name: Check out repo
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
working-directory: ./apps/desktop/desktop_native
|
working-directory: ./apps/desktop/desktop_native
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
---
|
|
||||||
name: Auto Bump Desktop Version
|
name: Auto Bump Desktop Version
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
---
|
|
||||||
name: Version Bump
|
name: Version Bump
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
@ -58,7 +57,7 @@ jobs:
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Checkout Branch
|
- name: Checkout Branch
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
with:
|
with:
|
||||||
ref: main
|
ref: main
|
||||||
|
|
||||||
|
@ -533,7 +532,7 @@ jobs:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Branch
|
- name: Checkout Branch
|
||||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
with:
|
with:
|
||||||
ref: main
|
ref: main
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,15 @@
|
||||||
"joinOrganization": {
|
"joinOrganization": {
|
||||||
"message": "Join organization"
|
"message": "Join organization"
|
||||||
},
|
},
|
||||||
|
"joinOrganizationName": {
|
||||||
|
"message": "Join $ORGANIZATIONNAME$",
|
||||||
|
"placeholders": {
|
||||||
|
"organizationName": {
|
||||||
|
"content": "$1",
|
||||||
|
"example": "My Org Name"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"finishJoiningThisOrganizationBySettingAMasterPassword": {
|
"finishJoiningThisOrganizationBySettingAMasterPassword": {
|
||||||
"message": "Finish joining this organization by setting a master password."
|
"message": "Finish joining this organization by setting a master password."
|
||||||
},
|
},
|
||||||
|
|
|
@ -34,7 +34,7 @@ export class HintComponent extends BaseHintComponent {
|
||||||
toastService,
|
toastService,
|
||||||
);
|
);
|
||||||
|
|
||||||
super.onSuccessfulSubmit = async () => {
|
this.onSuccessfulSubmit = async () => {
|
||||||
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
|
// 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
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
this.router.navigate([this.successRoute]);
|
this.router.navigate([this.successRoute]);
|
||||||
|
|
|
@ -105,7 +105,7 @@ export class LockComponent extends BaseLockComponent implements OnInit {
|
||||||
this.successRoute = "/tabs/current";
|
this.successRoute = "/tabs/current";
|
||||||
this.isInitialLockScreen = (window as any).previousPopupUrl == null;
|
this.isInitialLockScreen = (window as any).previousPopupUrl == null;
|
||||||
|
|
||||||
super.onSuccessfulSubmit = async () => {
|
this.onSuccessfulSubmit = async () => {
|
||||||
const previousUrl = this.routerService.getPreviousUrl();
|
const previousUrl = this.routerService.getPreviousUrl();
|
||||||
if (previousUrl) {
|
if (previousUrl) {
|
||||||
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
|
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
|
||||||
|
|
|
@ -78,10 +78,10 @@ export class LoginComponentV1 extends BaseLoginComponent implements OnInit {
|
||||||
registerRouteService,
|
registerRouteService,
|
||||||
toastService,
|
toastService,
|
||||||
);
|
);
|
||||||
super.onSuccessfulLogin = async () => {
|
this.onSuccessfulLogin = async () => {
|
||||||
await syncService.fullSync(true);
|
await syncService.fullSync(true);
|
||||||
};
|
};
|
||||||
super.successRoute = "/tabs/vault";
|
this.successRoute = "/tabs/vault";
|
||||||
this.showPasswordless = flagEnabled("showPasswordless");
|
this.showPasswordless = flagEnabled("showPasswordless");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ export class LoginViaAuthRequestComponent extends BaseLoginWithDeviceComponent {
|
||||||
loginStrategyService,
|
loginStrategyService,
|
||||||
toastService,
|
toastService,
|
||||||
);
|
);
|
||||||
super.onSuccessfulLogin = async () => {
|
this.onSuccessfulLogin = async () => {
|
||||||
await syncService.fullSync(true);
|
await syncService.fullSync(true);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,7 +79,7 @@ export class SsoComponent extends BaseSsoComponent {
|
||||||
});
|
});
|
||||||
this.clientId = "browser";
|
this.clientId = "browser";
|
||||||
|
|
||||||
super.onSuccessfulLogin = async () => {
|
this.onSuccessfulLogin = async () => {
|
||||||
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
|
// 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
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
syncService.fullSync(true);
|
syncService.fullSync(true);
|
||||||
|
@ -92,13 +92,13 @@ export class SsoComponent extends BaseSsoComponent {
|
||||||
this.win.close();
|
this.win.close();
|
||||||
};
|
};
|
||||||
|
|
||||||
super.onSuccessfulLoginTde = async () => {
|
this.onSuccessfulLoginTde = async () => {
|
||||||
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
|
// 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
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
syncService.fullSync(true);
|
syncService.fullSync(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
super.onSuccessfulLoginTdeNavigate = async () => {
|
this.onSuccessfulLoginTdeNavigate = async () => {
|
||||||
this.win.close();
|
this.win.close();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,7 +118,7 @@ export class TwoFactorAuthComponent
|
||||||
win,
|
win,
|
||||||
toastService,
|
toastService,
|
||||||
);
|
);
|
||||||
super.onSuccessfulLoginTdeNavigate = async () => {
|
this.onSuccessfulLoginTdeNavigate = async () => {
|
||||||
this.win.close();
|
this.win.close();
|
||||||
};
|
};
|
||||||
this.onSuccessfulLoginNavigate = this.goAfterLogIn;
|
this.onSuccessfulLoginNavigate = this.goAfterLogIn;
|
||||||
|
@ -131,7 +131,7 @@ export class TwoFactorAuthComponent
|
||||||
// WebAuthn fallback response
|
// WebAuthn fallback response
|
||||||
this.selectedProviderType = TwoFactorProviderType.WebAuthn;
|
this.selectedProviderType = TwoFactorProviderType.WebAuthn;
|
||||||
this.token = this.route.snapshot.paramMap.get("webAuthnResponse");
|
this.token = this.route.snapshot.paramMap.get("webAuthnResponse");
|
||||||
super.onSuccessfulLogin = async () => {
|
this.onSuccessfulLogin = async () => {
|
||||||
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
|
// 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
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
this.syncService.fullSync(true);
|
this.syncService.fullSync(true);
|
||||||
|
|
|
@ -87,23 +87,23 @@ export class TwoFactorComponent extends BaseTwoFactorComponent implements OnInit
|
||||||
accountService,
|
accountService,
|
||||||
toastService,
|
toastService,
|
||||||
);
|
);
|
||||||
super.onSuccessfulLogin = async () => {
|
this.onSuccessfulLogin = async () => {
|
||||||
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
|
// 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
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
syncService.fullSync(true);
|
syncService.fullSync(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
super.onSuccessfulLoginTde = async () => {
|
this.onSuccessfulLoginTde = async () => {
|
||||||
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
|
// 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
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
syncService.fullSync(true);
|
syncService.fullSync(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
super.onSuccessfulLoginTdeNavigate = async () => {
|
this.onSuccessfulLoginTdeNavigate = async () => {
|
||||||
this.win.close();
|
this.win.close();
|
||||||
};
|
};
|
||||||
|
|
||||||
super.successRoute = "/tabs/vault";
|
this.successRoute = "/tabs/vault";
|
||||||
// FIXME: Chromium 110 has broken WebAuthn support in extensions via an iframe
|
// FIXME: Chromium 110 has broken WebAuthn support in extensions via an iframe
|
||||||
this.webAuthnNewTab = true;
|
this.webAuthnNewTab = true;
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,7 @@ export class TwoFactorComponent extends BaseTwoFactorComponent implements OnInit
|
||||||
// WebAuthn fallback response
|
// WebAuthn fallback response
|
||||||
this.selectedProviderType = TwoFactorProviderType.WebAuthn;
|
this.selectedProviderType = TwoFactorProviderType.WebAuthn;
|
||||||
this.token = this.route.snapshot.paramMap.get("webAuthnResponse");
|
this.token = this.route.snapshot.paramMap.get("webAuthnResponse");
|
||||||
super.onSuccessfulLogin = async () => {
|
this.onSuccessfulLogin = async () => {
|
||||||
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
|
// 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
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
this.syncService.fullSync(true);
|
this.syncService.fullSync(true);
|
||||||
|
@ -155,7 +155,7 @@ export class TwoFactorComponent extends BaseTwoFactorComponent implements OnInit
|
||||||
// eslint-disable-next-line rxjs-angular/prefer-takeuntil, rxjs/no-async-subscribe
|
// eslint-disable-next-line rxjs-angular/prefer-takeuntil, rxjs/no-async-subscribe
|
||||||
this.route.queryParams.pipe(first()).subscribe(async (qParams) => {
|
this.route.queryParams.pipe(first()).subscribe(async (qParams) => {
|
||||||
if (qParams.sso === "true") {
|
if (qParams.sso === "true") {
|
||||||
super.onSuccessfulLogin = async () => {
|
this.onSuccessfulLogin = async () => {
|
||||||
// This is not awaited so we don't pause the application while the sync is happening.
|
// This is not awaited so we don't pause the application while the sync is happening.
|
||||||
// This call is executed by the service that lives in the background script so it will continue
|
// This call is executed by the service that lives in the background script so it will continue
|
||||||
// the sync even if this tab closes.
|
// the sync even if this tab closes.
|
||||||
|
|
|
@ -1158,7 +1158,6 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
this.showInlineMenuIdentities &&
|
|
||||||
this.inlineMenuFieldQualificationService.isFieldForAccountCreationForm(
|
this.inlineMenuFieldQualificationService.isFieldForAccountCreationForm(
|
||||||
autofillFieldData,
|
autofillFieldData,
|
||||||
pageDetails,
|
pageDetails,
|
||||||
|
|
|
@ -23,9 +23,11 @@ import {
|
||||||
LockV2Component,
|
LockV2Component,
|
||||||
PasswordHintComponent,
|
PasswordHintComponent,
|
||||||
RegistrationFinishComponent,
|
RegistrationFinishComponent,
|
||||||
|
RegistrationLockAltIcon,
|
||||||
RegistrationStartComponent,
|
RegistrationStartComponent,
|
||||||
RegistrationStartSecondaryComponent,
|
RegistrationStartSecondaryComponent,
|
||||||
RegistrationStartSecondaryComponentData,
|
RegistrationStartSecondaryComponentData,
|
||||||
|
RegistrationUserAddIcon,
|
||||||
SetPasswordJitComponent,
|
SetPasswordJitComponent,
|
||||||
UserLockIcon,
|
UserLockIcon,
|
||||||
VaultIcon,
|
VaultIcon,
|
||||||
|
@ -502,6 +504,47 @@ const routes: Routes = [
|
||||||
path: "",
|
path: "",
|
||||||
component: ExtensionAnonLayoutWrapperComponent,
|
component: ExtensionAnonLayoutWrapperComponent,
|
||||||
children: [
|
children: [
|
||||||
|
{
|
||||||
|
path: "signup",
|
||||||
|
canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()],
|
||||||
|
data: {
|
||||||
|
state: "signup",
|
||||||
|
pageIcon: RegistrationUserAddIcon,
|
||||||
|
pageTitle: {
|
||||||
|
key: "createAccount",
|
||||||
|
},
|
||||||
|
showBackButton: true,
|
||||||
|
} satisfies RouteDataProperties & ExtensionAnonLayoutWrapperData,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: "",
|
||||||
|
component: RegistrationStartComponent,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "",
|
||||||
|
component: RegistrationStartSecondaryComponent,
|
||||||
|
outlet: "secondary",
|
||||||
|
data: {
|
||||||
|
loginRoute: "/home",
|
||||||
|
} satisfies RegistrationStartSecondaryComponentData,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "finish-signup",
|
||||||
|
canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()],
|
||||||
|
data: {
|
||||||
|
pageIcon: RegistrationLockAltIcon,
|
||||||
|
state: "finish-signup",
|
||||||
|
showBackButton: true,
|
||||||
|
} satisfies RouteDataProperties & ExtensionAnonLayoutWrapperData,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: "",
|
||||||
|
component: RegistrationFinishComponent,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: "lockV2",
|
path: "lockV2",
|
||||||
canActivate: [canAccessFeature(FeatureFlag.ExtensionRefresh), lockGuard()],
|
canActivate: [canAccessFeature(FeatureFlag.ExtensionRefresh), lockGuard()],
|
||||||
|
@ -526,49 +569,6 @@ const routes: Routes = [
|
||||||
path: "",
|
path: "",
|
||||||
component: AnonLayoutWrapperComponent,
|
component: AnonLayoutWrapperComponent,
|
||||||
children: [
|
children: [
|
||||||
{
|
|
||||||
path: "signup",
|
|
||||||
canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()],
|
|
||||||
data: {
|
|
||||||
state: "signup",
|
|
||||||
pageTitle: {
|
|
||||||
key: "createAccount",
|
|
||||||
},
|
|
||||||
} satisfies RouteDataProperties & AnonLayoutWrapperData,
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: "",
|
|
||||||
component: RegistrationStartComponent,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "",
|
|
||||||
component: RegistrationStartSecondaryComponent,
|
|
||||||
outlet: "secondary",
|
|
||||||
data: {
|
|
||||||
loginRoute: "/home",
|
|
||||||
} satisfies RegistrationStartSecondaryComponentData,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "finish-signup",
|
|
||||||
canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()],
|
|
||||||
data: {
|
|
||||||
pageTitle: {
|
|
||||||
key: "setAStrongPassword",
|
|
||||||
},
|
|
||||||
pageSubtitle: {
|
|
||||||
key: "finishCreatingYourAccountBySettingAPassword",
|
|
||||||
},
|
|
||||||
state: "finish-signup",
|
|
||||||
} satisfies RouteDataProperties & AnonLayoutWrapperData,
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: "",
|
|
||||||
component: RegistrationFinishComponent,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: "set-password-jit",
|
path: "set-password-jit",
|
||||||
canActivate: [canAccessFeature(FeatureFlag.EmailVerification)],
|
canActivate: [canAccessFeature(FeatureFlag.EmailVerification)],
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@koa/multer": "3.0.2",
|
"@koa/multer": "3.0.2",
|
||||||
"@koa/router": "12.0.1",
|
"@koa/router": "13.1.0",
|
||||||
"argon2": "0.40.1",
|
"argon2": "0.40.1",
|
||||||
"big-integer": "1.6.52",
|
"big-integer": "1.6.52",
|
||||||
"browser-hrtime": "1.1.8",
|
"browser-hrtime": "1.1.8",
|
||||||
|
@ -68,7 +68,7 @@
|
||||||
"inquirer": "8.2.6",
|
"inquirer": "8.2.6",
|
||||||
"jsdom": "25.0.1",
|
"jsdom": "25.0.1",
|
||||||
"jszip": "3.10.1",
|
"jszip": "3.10.1",
|
||||||
"koa": "2.15.0",
|
"koa": "2.15.3",
|
||||||
"koa-bodyparser": "4.4.1",
|
"koa-bodyparser": "4.4.1",
|
||||||
"koa-json": "2.0.2",
|
"koa-json": "2.0.2",
|
||||||
"lowdb": "1.0.0",
|
"lowdb": "1.0.0",
|
||||||
|
@ -80,7 +80,7 @@
|
||||||
"papaparse": "5.4.1",
|
"papaparse": "5.4.1",
|
||||||
"proper-lockfile": "4.1.2",
|
"proper-lockfile": "4.1.2",
|
||||||
"rxjs": "7.8.1",
|
"rxjs": "7.8.1",
|
||||||
"tldts": "6.1.51",
|
"tldts": "6.1.52",
|
||||||
"zxcvbn": "4.4.2"
|
"zxcvbn": "4.4.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -249,7 +249,7 @@
|
||||||
"autoStart": true,
|
"autoStart": true,
|
||||||
"base": "core22",
|
"base": "core22",
|
||||||
"confinement": "strict",
|
"confinement": "strict",
|
||||||
"plugs": ["default", "network", "network-bind", "password-manager-service"],
|
"plugs": ["default", "network-bind", "password-manager-service"],
|
||||||
"stagePackages": ["default"]
|
"stagePackages": ["default"]
|
||||||
},
|
},
|
||||||
"protocols": [
|
"protocols": [
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@bitwarden/desktop",
|
"name": "@bitwarden/desktop",
|
||||||
"description": "A secure and free password manager for all of your devices.",
|
"description": "A secure and free password manager for all of your devices.",
|
||||||
"version": "2024.10.0",
|
"version": "2024.10.2",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"bitwarden",
|
"bitwarden",
|
||||||
"password",
|
"password",
|
||||||
|
|
|
@ -21,9 +21,11 @@ import {
|
||||||
LockV2Component,
|
LockV2Component,
|
||||||
PasswordHintComponent,
|
PasswordHintComponent,
|
||||||
RegistrationFinishComponent,
|
RegistrationFinishComponent,
|
||||||
|
RegistrationLockAltIcon,
|
||||||
RegistrationStartComponent,
|
RegistrationStartComponent,
|
||||||
RegistrationStartSecondaryComponent,
|
RegistrationStartSecondaryComponent,
|
||||||
RegistrationStartSecondaryComponentData,
|
RegistrationStartSecondaryComponentData,
|
||||||
|
RegistrationUserAddIcon,
|
||||||
SetPasswordJitComponent,
|
SetPasswordJitComponent,
|
||||||
UserLockIcon,
|
UserLockIcon,
|
||||||
} from "@bitwarden/auth/angular";
|
} from "@bitwarden/auth/angular";
|
||||||
|
@ -212,6 +214,7 @@ const routes: Routes = [
|
||||||
path: "signup",
|
path: "signup",
|
||||||
canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()],
|
canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()],
|
||||||
data: {
|
data: {
|
||||||
|
pageIcon: RegistrationUserAddIcon,
|
||||||
pageTitle: {
|
pageTitle: {
|
||||||
key: "createAccount",
|
key: "createAccount",
|
||||||
},
|
},
|
||||||
|
@ -235,12 +238,7 @@ const routes: Routes = [
|
||||||
path: "finish-signup",
|
path: "finish-signup",
|
||||||
canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()],
|
canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()],
|
||||||
data: {
|
data: {
|
||||||
pageTitle: {
|
pageIcon: RegistrationLockAltIcon,
|
||||||
key: "setAStrongPassword",
|
|
||||||
},
|
|
||||||
pageSubtitle: {
|
|
||||||
key: "finishCreatingYourAccountBySettingAPassword",
|
|
||||||
},
|
|
||||||
} satisfies AnonLayoutWrapperData,
|
} satisfies AnonLayoutWrapperData,
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
|
|
@ -99,7 +99,7 @@ export class LoginComponentV1 extends BaseLoginComponent implements OnInit, OnDe
|
||||||
registerRouteService,
|
registerRouteService,
|
||||||
toastService,
|
toastService,
|
||||||
);
|
);
|
||||||
super.onSuccessfulLogin = () => {
|
this.onSuccessfulLogin = () => {
|
||||||
return syncService.fullSync(true);
|
return syncService.fullSync(true);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ export class LoginViaAuthRequestComponent extends BaseLoginWithDeviceComponent {
|
||||||
toastService,
|
toastService,
|
||||||
);
|
);
|
||||||
|
|
||||||
super.onSuccessfulLogin = () => {
|
this.onSuccessfulLogin = () => {
|
||||||
return syncService.fullSync(true);
|
return syncService.fullSync(true);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,13 +65,13 @@ export class SsoComponent extends BaseSsoComponent {
|
||||||
accountService,
|
accountService,
|
||||||
toastService,
|
toastService,
|
||||||
);
|
);
|
||||||
super.onSuccessfulLogin = async () => {
|
this.onSuccessfulLogin = async () => {
|
||||||
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
|
// 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
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
syncService.fullSync(true);
|
syncService.fullSync(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
super.onSuccessfulLoginTde = async () => {
|
this.onSuccessfulLoginTde = async () => {
|
||||||
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
|
// 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
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
syncService.fullSync(true);
|
syncService.fullSync(true);
|
||||||
|
|
|
@ -89,13 +89,13 @@ export class TwoFactorComponent extends BaseTwoFactorComponent implements OnDest
|
||||||
accountService,
|
accountService,
|
||||||
toastService,
|
toastService,
|
||||||
);
|
);
|
||||||
super.onSuccessfulLogin = async () => {
|
this.onSuccessfulLogin = async () => {
|
||||||
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
|
// 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
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
syncService.fullSync(true);
|
syncService.fullSync(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
super.onSuccessfulLoginTde = async () => {
|
this.onSuccessfulLoginTde = async () => {
|
||||||
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
|
// 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
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
syncService.fullSync(true);
|
syncService.fullSync(true);
|
||||||
|
|
|
@ -623,6 +623,15 @@
|
||||||
"joinOrganization": {
|
"joinOrganization": {
|
||||||
"message": "Join organization"
|
"message": "Join organization"
|
||||||
},
|
},
|
||||||
|
"joinOrganizationName": {
|
||||||
|
"message": "Join $ORGANIZATIONNAME$",
|
||||||
|
"placeholders": {
|
||||||
|
"organizationName": {
|
||||||
|
"content": "$1",
|
||||||
|
"example": "My Org Name"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"finishJoiningThisOrganizationBySettingAMasterPassword": {
|
"finishJoiningThisOrganizationBySettingAMasterPassword": {
|
||||||
"message": "Finish joining this organization by setting a master password."
|
"message": "Finish joining this organization by setting a master password."
|
||||||
},
|
},
|
||||||
|
|
|
@ -87,6 +87,9 @@ export class Main {
|
||||||
// on ready stuff...
|
// on ready stuff...
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.commandLine.appendSwitch("ignore-certificate-errors");
|
||||||
|
app.commandLine.appendSwitch("allow-insecure-localhost", "true");
|
||||||
|
|
||||||
if (appDataPath != null) {
|
if (appDataPath != null) {
|
||||||
app.setPath("userData", appDataPath);
|
app.setPath("userData", appDataPath);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "@bitwarden/desktop",
|
"name": "@bitwarden/desktop",
|
||||||
"version": "2024.10.0",
|
"version": "2024.10.2",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@bitwarden/desktop",
|
"name": "@bitwarden/desktop",
|
||||||
"version": "2024.10.0",
|
"version": "2024.10.2",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@bitwarden/desktop-napi": "file:../desktop_native/napi",
|
"@bitwarden/desktop-napi": "file:../desktop_native/napi",
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"name": "@bitwarden/desktop",
|
"name": "@bitwarden/desktop",
|
||||||
"productName": "Bitwarden",
|
"productName": "Bitwarden",
|
||||||
"description": "A secure and free password manager for all of your devices.",
|
"description": "A secure and free password manager for all of your devices.",
|
||||||
"version": "2024.10.0",
|
"version": "2024.10.2",
|
||||||
"author": "Bitwarden Inc. <hello@bitwarden.com> (https://bitwarden.com)",
|
"author": "Bitwarden Inc. <hello@bitwarden.com> (https://bitwarden.com)",
|
||||||
"homepage": "https://bitwarden.com",
|
"homepage": "https://bitwarden.com",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
|
|
|
@ -2,15 +2,7 @@
|
||||||
{{ "personalOwnershipExemption" | i18n }}
|
{{ "personalOwnershipExemption" | i18n }}
|
||||||
</bit-callout>
|
</bit-callout>
|
||||||
|
|
||||||
<div class="form-group">
|
<bit-form-control>
|
||||||
<div class="form-check">
|
<input type="checkbox" bitCheckbox [formControl]="enabled" id="enabled" />
|
||||||
<input
|
<bit-label>{{ "turnOn" | i18n }}</bit-label>
|
||||||
class="form-check-input"
|
</bit-form-control>
|
||||||
type="checkbox"
|
|
||||||
id="enabled"
|
|
||||||
[formControl]="enabled"
|
|
||||||
name="Enabled"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" for="enabled">{{ "turnOn" | i18n }}</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
|
@ -52,7 +52,11 @@
|
||||||
<form
|
<form
|
||||||
*ngIf="org && !loading"
|
*ngIf="org && !loading"
|
||||||
[bitSubmit]="submitCollectionManagement"
|
[bitSubmit]="submitCollectionManagement"
|
||||||
[formGroup]="collectionManagementFormGroup"
|
[formGroup]="
|
||||||
|
limitCollectionCreationDeletionSplitFeatureFlagIsEnabled
|
||||||
|
? collectionManagementFormGroup_VNext
|
||||||
|
: collectionManagementFormGroup
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<h1 bitTypography="h1" class="tw-mt-16 tw-pb-2.5">{{ "collectionManagement" | i18n }}</h1>
|
<h1 bitTypography="h1" class="tw-mt-16 tw-pb-2.5">{{ "collectionManagement" | i18n }}</h1>
|
||||||
<p bitTypography="body1">{{ "collectionManagementDesc" | i18n }}</p>
|
<p bitTypography="body1">{{ "collectionManagementDesc" | i18n }}</p>
|
||||||
|
@ -60,12 +64,24 @@
|
||||||
<bit-label>{{ "allowAdminAccessToAllCollectionItemsDesc" | i18n }}</bit-label>
|
<bit-label>{{ "allowAdminAccessToAllCollectionItemsDesc" | i18n }}</bit-label>
|
||||||
<input type="checkbox" bitCheckbox formControlName="allowAdminAccessToAllCollectionItems" />
|
<input type="checkbox" bitCheckbox formControlName="allowAdminAccessToAllCollectionItems" />
|
||||||
</bit-form-control>
|
</bit-form-control>
|
||||||
<bit-form-control>
|
<ng-container *ngIf="limitCollectionCreationDeletionSplitFeatureFlagIsEnabled">
|
||||||
<bit-label>{{ "limitCollectionCreationDeletionDesc" | i18n }}</bit-label>
|
<bit-form-control>
|
||||||
<input type="checkbox" bitCheckbox formControlName="limitCollectionCreationDeletion" />
|
<bit-label>{{ "limitCollectionCreationDesc" | i18n }}</bit-label>
|
||||||
</bit-form-control>
|
<input type="checkbox" bitCheckbox formControlName="limitCollectionCreation" />
|
||||||
|
</bit-form-control>
|
||||||
|
<bit-form-control>
|
||||||
|
<bit-label>{{ "limitCollectionDeletionDesc" | i18n }}</bit-label>
|
||||||
|
<input type="checkbox" bitCheckbox formControlName="limitCollectionDeletion" />
|
||||||
|
</bit-form-control>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container *ngIf="!limitCollectionCreationDeletionSplitFeatureFlagIsEnabled">
|
||||||
|
<bit-form-control>
|
||||||
|
<bit-label>{{ "limitCollectionCreationDeletionDesc" | i18n }}</bit-label>
|
||||||
|
<input type="checkbox" bitCheckbox formControlName="limitCollectionCreationDeletion" />
|
||||||
|
</bit-form-control>
|
||||||
|
</ng-container>
|
||||||
<button
|
<button
|
||||||
*ngIf="!selfHosted"
|
*ngIf="!selfHosted || limitCollectionCreationDeletionSplitFeatureFlagIsEnabled"
|
||||||
type="submit"
|
type="submit"
|
||||||
bitButton
|
bitButton
|
||||||
bitFormButton
|
bitFormButton
|
||||||
|
|
|
@ -10,6 +10,8 @@ import { OrganizationCollectionManagementUpdateRequest } from "@bitwarden/common
|
||||||
import { OrganizationKeysRequest } from "@bitwarden/common/admin-console/models/request/organization-keys.request";
|
import { OrganizationKeysRequest } from "@bitwarden/common/admin-console/models/request/organization-keys.request";
|
||||||
import { OrganizationUpdateRequest } from "@bitwarden/common/admin-console/models/request/organization-update.request";
|
import { OrganizationUpdateRequest } from "@bitwarden/common/admin-console/models/request/organization-update.request";
|
||||||
import { OrganizationResponse } from "@bitwarden/common/admin-console/models/response/organization.response";
|
import { OrganizationResponse } from "@bitwarden/common/admin-console/models/response/organization.response";
|
||||||
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||||
|
@ -38,6 +40,8 @@ export class AccountComponent implements OnInit, OnDestroy {
|
||||||
org: OrganizationResponse;
|
org: OrganizationResponse;
|
||||||
taxFormPromise: Promise<unknown>;
|
taxFormPromise: Promise<unknown>;
|
||||||
|
|
||||||
|
limitCollectionCreationDeletionSplitFeatureFlagIsEnabled: boolean;
|
||||||
|
|
||||||
// FormGroup validators taken from server Organization domain object
|
// FormGroup validators taken from server Organization domain object
|
||||||
protected formGroup = this.formBuilder.group({
|
protected formGroup = this.formBuilder.group({
|
||||||
orgName: this.formBuilder.control(
|
orgName: this.formBuilder.control(
|
||||||
|
@ -53,6 +57,7 @@ export class AccountComponent implements OnInit, OnDestroy {
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Deprecated. Delete with https://bitwarden.atlassian.net/browse/PM-10863
|
||||||
protected collectionManagementFormGroup = this.formBuilder.group({
|
protected collectionManagementFormGroup = this.formBuilder.group({
|
||||||
limitCollectionCreationDeletion: this.formBuilder.control({ value: false, disabled: true }),
|
limitCollectionCreationDeletion: this.formBuilder.control({ value: false, disabled: true }),
|
||||||
allowAdminAccessToAllCollectionItems: this.formBuilder.control({
|
allowAdminAccessToAllCollectionItems: this.formBuilder.control({
|
||||||
|
@ -61,6 +66,15 @@ export class AccountComponent implements OnInit, OnDestroy {
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
protected collectionManagementFormGroup_VNext = this.formBuilder.group({
|
||||||
|
limitCollectionCreation: this.formBuilder.control({ value: false, disabled: false }),
|
||||||
|
limitCollectionDeletion: this.formBuilder.control({ value: false, disabled: false }),
|
||||||
|
allowAdminAccessToAllCollectionItems: this.formBuilder.control({
|
||||||
|
value: false,
|
||||||
|
disabled: false,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
protected organizationId: string;
|
protected organizationId: string;
|
||||||
protected publicKeyBuffer: Uint8Array;
|
protected publicKeyBuffer: Uint8Array;
|
||||||
|
|
||||||
|
@ -78,11 +92,17 @@ export class AccountComponent implements OnInit, OnDestroy {
|
||||||
private dialogService: DialogService,
|
private dialogService: DialogService,
|
||||||
private formBuilder: FormBuilder,
|
private formBuilder: FormBuilder,
|
||||||
private toastService: ToastService,
|
private toastService: ToastService,
|
||||||
|
private configService: ConfigService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
this.selfHosted = this.platformUtilsService.isSelfHost();
|
this.selfHosted = this.platformUtilsService.isSelfHost();
|
||||||
|
|
||||||
|
this.configService
|
||||||
|
.getFeatureFlag$(FeatureFlag.LimitCollectionCreationDeletionSplit)
|
||||||
|
.pipe(takeUntil(this.destroy$))
|
||||||
|
.subscribe((x) => (this.limitCollectionCreationDeletionSplitFeatureFlagIsEnabled = x));
|
||||||
|
|
||||||
this.route.params
|
this.route.params
|
||||||
.pipe(
|
.pipe(
|
||||||
switchMap((params) => this.organizationService.get$(params.organizationId)),
|
switchMap((params) => this.organizationService.get$(params.organizationId)),
|
||||||
|
@ -104,10 +124,15 @@ export class AccountComponent implements OnInit, OnDestroy {
|
||||||
this.canUseApi = organization.useApi;
|
this.canUseApi = organization.useApi;
|
||||||
|
|
||||||
// Update disabled states - reactive forms prefers not using disabled attribute
|
// Update disabled states - reactive forms prefers not using disabled attribute
|
||||||
if (!this.selfHosted) {
|
// Disabling these fields for self hosted orgs is deprecated
|
||||||
this.formGroup.get("orgName").enable();
|
// This block can be completely removed as part of
|
||||||
this.collectionManagementFormGroup.get("limitCollectionCreationDeletion").enable();
|
// https://bitwarden.atlassian.net/browse/PM-10863
|
||||||
this.collectionManagementFormGroup.get("allowAdminAccessToAllCollectionItems").enable();
|
if (!this.limitCollectionCreationDeletionSplitFeatureFlagIsEnabled) {
|
||||||
|
if (!this.selfHosted) {
|
||||||
|
this.formGroup.get("orgName").enable();
|
||||||
|
this.collectionManagementFormGroup.get("limitCollectionCreationDeletion").enable();
|
||||||
|
this.collectionManagementFormGroup.get("allowAdminAccessToAllCollectionItems").enable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.selfHosted && this.canEditSubscription) {
|
if (!this.selfHosted && this.canEditSubscription) {
|
||||||
|
@ -125,10 +150,18 @@ export class AccountComponent implements OnInit, OnDestroy {
|
||||||
orgName: this.org.name,
|
orgName: this.org.name,
|
||||||
billingEmail: this.org.billingEmail,
|
billingEmail: this.org.billingEmail,
|
||||||
});
|
});
|
||||||
this.collectionManagementFormGroup.patchValue({
|
if (this.limitCollectionCreationDeletionSplitFeatureFlagIsEnabled) {
|
||||||
limitCollectionCreationDeletion: this.org.limitCollectionCreationDeletion,
|
this.collectionManagementFormGroup_VNext.patchValue({
|
||||||
allowAdminAccessToAllCollectionItems: this.org.allowAdminAccessToAllCollectionItems,
|
limitCollectionCreation: this.org.limitCollectionCreation,
|
||||||
});
|
limitCollectionDeletion: this.org.limitCollectionDeletion,
|
||||||
|
allowAdminAccessToAllCollectionItems: this.org.allowAdminAccessToAllCollectionItems,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.collectionManagementFormGroup.patchValue({
|
||||||
|
limitCollectionCreationDeletion: this.org.limitCollectionCreationDeletion,
|
||||||
|
allowAdminAccessToAllCollectionItems: this.org.allowAdminAccessToAllCollectionItems,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
});
|
});
|
||||||
|
@ -177,15 +210,23 @@ export class AccountComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
submitCollectionManagement = async () => {
|
submitCollectionManagement = async () => {
|
||||||
// Early exit if self-hosted
|
// Early exit if self-hosted
|
||||||
if (this.selfHosted) {
|
if (this.selfHosted && !this.limitCollectionCreationDeletionSplitFeatureFlagIsEnabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const request = new OrganizationCollectionManagementUpdateRequest();
|
const request = new OrganizationCollectionManagementUpdateRequest();
|
||||||
request.limitCreateDeleteOwnerAdmin =
|
if (this.limitCollectionCreationDeletionSplitFeatureFlagIsEnabled) {
|
||||||
this.collectionManagementFormGroup.value.limitCollectionCreationDeletion;
|
request.limitCollectionCreation =
|
||||||
request.allowAdminAccessToAllCollectionItems =
|
this.collectionManagementFormGroup_VNext.value.limitCollectionCreation;
|
||||||
this.collectionManagementFormGroup.value.allowAdminAccessToAllCollectionItems;
|
request.limitCollectionDeletion =
|
||||||
|
this.collectionManagementFormGroup_VNext.value.limitCollectionDeletion;
|
||||||
|
request.allowAdminAccessToAllCollectionItems =
|
||||||
|
this.collectionManagementFormGroup_VNext.value.allowAdminAccessToAllCollectionItems;
|
||||||
|
} else {
|
||||||
|
request.limitCreateDeleteOwnerAdmin =
|
||||||
|
this.collectionManagementFormGroup.value.limitCollectionCreationDeletion;
|
||||||
|
request.allowAdminAccessToAllCollectionItems =
|
||||||
|
this.collectionManagementFormGroup.value.allowAdminAccessToAllCollectionItems;
|
||||||
|
}
|
||||||
|
|
||||||
await this.organizationApiService.updateCollectionManagement(this.organizationId, request);
|
await this.organizationApiService.updateCollectionManagement(this.organizationId, request);
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,36 @@ describe("DefaultRegistrationFinishService", () => {
|
||||||
expect(service).not.toBeFalsy();
|
expect(service).not.toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("getOrgNameFromOrgInvite()", () => {
|
||||||
|
let orgInvite: OrganizationInvite | null;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
orgInvite = new OrganizationInvite();
|
||||||
|
orgInvite.organizationId = "organizationId";
|
||||||
|
orgInvite.organizationUserId = "organizationUserId";
|
||||||
|
orgInvite.token = "orgInviteToken";
|
||||||
|
orgInvite.email = "email";
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns null when the org invite is null", async () => {
|
||||||
|
acceptOrgInviteService.getOrganizationInvite.mockResolvedValue(null);
|
||||||
|
|
||||||
|
const result = await service.getOrgNameFromOrgInvite();
|
||||||
|
|
||||||
|
expect(result).toBeNull();
|
||||||
|
expect(acceptOrgInviteService.getOrganizationInvite).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns the organization name from the organization invite when it exists", async () => {
|
||||||
|
acceptOrgInviteService.getOrganizationInvite.mockResolvedValue(orgInvite);
|
||||||
|
|
||||||
|
const result = await service.getOrgNameFromOrgInvite();
|
||||||
|
|
||||||
|
expect(result).toEqual(orgInvite.organizationName);
|
||||||
|
expect(acceptOrgInviteService.getOrganizationInvite).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("getMasterPasswordPolicyOptsFromOrgInvite()", () => {
|
describe("getMasterPasswordPolicyOptsFromOrgInvite()", () => {
|
||||||
let orgInvite: OrganizationInvite | null;
|
let orgInvite: OrganizationInvite | null;
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,15 @@ export class WebRegistrationFinishService
|
||||||
super(cryptoService, accountApiService);
|
super(cryptoService, accountApiService);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override async getOrgNameFromOrgInvite(): Promise<string | null> {
|
||||||
|
const orgInvite = await this.acceptOrgInviteService.getOrganizationInvite();
|
||||||
|
if (orgInvite == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return orgInvite.organizationName;
|
||||||
|
}
|
||||||
|
|
||||||
override async getMasterPasswordPolicyOptsFromOrgInvite(): Promise<MasterPasswordPolicyOptions | null> {
|
override async getMasterPasswordPolicyOptsFromOrgInvite(): Promise<MasterPasswordPolicyOptions | null> {
|
||||||
// If there's a deep linked org invite, use it to get the password policies
|
// If there's a deep linked org invite, use it to get the password policies
|
||||||
const orgInvite = await this.acceptOrgInviteService.getOrganizationInvite();
|
const orgInvite = await this.acceptOrgInviteService.getOrganizationInvite();
|
||||||
|
|
|
@ -71,7 +71,7 @@ export class RegisterFormComponent extends BaseRegisterComponent implements OnIn
|
||||||
dialogService,
|
dialogService,
|
||||||
toastService,
|
toastService,
|
||||||
);
|
);
|
||||||
super.modifyRegisterRequest = async (request: RegisterRequest) => {
|
this.modifyRegisterRequest = async (request: RegisterRequest) => {
|
||||||
// Org invites are deep linked. Non-existent accounts are redirected to the register page.
|
// Org invites are deep linked. Non-existent accounts are redirected to the register page.
|
||||||
// Org user id and token are included here only for validation and two factor purposes.
|
// Org user id and token are included here only for validation and two factor purposes.
|
||||||
const orgInvite = await acceptOrgInviteService.getOrganizationInvite();
|
const orgInvite = await acceptOrgInviteService.getOrganizationInvite();
|
||||||
|
|
|
@ -12,7 +12,13 @@
|
||||||
<button type="button" bitButton buttonType="danger" (click)="deauthorizeSessions()">
|
<button type="button" bitButton buttonType="danger" (click)="deauthorizeSessions()">
|
||||||
{{ "deauthorizeSessions" | i18n }}
|
{{ "deauthorizeSessions" | i18n }}
|
||||||
</button>
|
</button>
|
||||||
<button type="button" bitButton buttonType="danger" [bitAction]="purgeVault">
|
<button
|
||||||
|
*ngIf="showPurgeVault$ | async"
|
||||||
|
type="button"
|
||||||
|
bitButton
|
||||||
|
buttonType="danger"
|
||||||
|
[bitAction]="purgeVault"
|
||||||
|
>
|
||||||
{{ "purgeVault" | i18n }}
|
{{ "purgeVault" | i18n }}
|
||||||
</button>
|
</button>
|
||||||
<button type="button" bitButton buttonType="danger" [bitAction]="deleteAccount">
|
<button type="button" bitButton buttonType="danger" [bitAction]="deleteAccount">
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
import { Component, OnInit, ViewChild, ViewContainerRef } from "@angular/core";
|
import { Component, OnInit, ViewChild, ViewContainerRef } from "@angular/core";
|
||||||
import { lastValueFrom } from "rxjs";
|
import { lastValueFrom, map, Observable, of, switchMap } from "rxjs";
|
||||||
|
|
||||||
import { ModalService } from "@bitwarden/angular/services/modal.service";
|
import { ModalService } from "@bitwarden/angular/services/modal.service";
|
||||||
|
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||||
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||||
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { DialogService } from "@bitwarden/components";
|
import { DialogService } from "@bitwarden/components";
|
||||||
|
|
||||||
import { PurgeVaultComponent } from "../../../vault/settings/purge-vault.component";
|
import { PurgeVaultComponent } from "../../../vault/settings/purge-vault.component";
|
||||||
|
@ -19,15 +22,32 @@ export class AccountComponent implements OnInit {
|
||||||
deauthModalRef: ViewContainerRef;
|
deauthModalRef: ViewContainerRef;
|
||||||
|
|
||||||
showChangeEmail = true;
|
showChangeEmail = true;
|
||||||
|
showPurgeVault$: Observable<boolean>;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private modalService: ModalService,
|
private modalService: ModalService,
|
||||||
private dialogService: DialogService,
|
private dialogService: DialogService,
|
||||||
private userVerificationService: UserVerificationService,
|
private userVerificationService: UserVerificationService,
|
||||||
|
private configService: ConfigService,
|
||||||
|
private organizationService: OrganizationService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
this.showChangeEmail = await this.userVerificationService.hasMasterPassword();
|
this.showChangeEmail = await this.userVerificationService.hasMasterPassword();
|
||||||
|
this.showPurgeVault$ = this.configService
|
||||||
|
.getFeatureFlag$(FeatureFlag.AccountDeprovisioning)
|
||||||
|
.pipe(
|
||||||
|
switchMap((isAccountDeprovisioningEnabled) =>
|
||||||
|
isAccountDeprovisioningEnabled
|
||||||
|
? this.organizationService.organizations$.pipe(
|
||||||
|
map(
|
||||||
|
(organizations) =>
|
||||||
|
!organizations.some((o) => o.userIsManagedByOrganization === true),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: of(true),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async deauthorizeSessions() {
|
async deauthorizeSessions() {
|
||||||
|
|
|
@ -61,7 +61,7 @@ export class ChangeKdfConfirmationComponent {
|
||||||
const masterPassword = this.form.value.masterPassword;
|
const masterPassword = this.form.value.masterPassword;
|
||||||
|
|
||||||
// Ensure the KDF config is valid.
|
// Ensure the KDF config is valid.
|
||||||
this.kdfConfig.validateKdfConfig();
|
this.kdfConfig.validateKdfConfigForSetting();
|
||||||
|
|
||||||
const request = new KdfRequest();
|
const request = new KdfRequest();
|
||||||
request.kdf = this.kdfConfig.kdfType;
|
request.kdf = this.kdfConfig.kdfType;
|
||||||
|
|
|
@ -27,6 +27,9 @@ import {
|
||||||
LockV2Component,
|
LockV2Component,
|
||||||
LockIcon,
|
LockIcon,
|
||||||
UserLockIcon,
|
UserLockIcon,
|
||||||
|
RegistrationUserAddIcon,
|
||||||
|
RegistrationLockAltIcon,
|
||||||
|
RegistrationExpiredLinkIcon,
|
||||||
} from "@bitwarden/auth/angular";
|
} from "@bitwarden/auth/angular";
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
|
|
||||||
|
@ -285,6 +288,7 @@ const routes: Routes = [
|
||||||
path: "signup",
|
path: "signup",
|
||||||
canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()],
|
canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()],
|
||||||
data: {
|
data: {
|
||||||
|
pageIcon: RegistrationUserAddIcon,
|
||||||
pageTitle: {
|
pageTitle: {
|
||||||
key: "createAccount",
|
key: "createAccount",
|
||||||
},
|
},
|
||||||
|
@ -309,12 +313,7 @@ const routes: Routes = [
|
||||||
path: "finish-signup",
|
path: "finish-signup",
|
||||||
canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()],
|
canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()],
|
||||||
data: {
|
data: {
|
||||||
pageTitle: {
|
pageIcon: RegistrationLockAltIcon,
|
||||||
key: "setAStrongPassword",
|
|
||||||
},
|
|
||||||
pageSubtitle: {
|
|
||||||
key: "finishCreatingYourAccountBySettingAPassword",
|
|
||||||
},
|
|
||||||
titleId: "setAStrongPassword",
|
titleId: "setAStrongPassword",
|
||||||
} satisfies RouteDataProperties & AnonLayoutWrapperData,
|
} satisfies RouteDataProperties & AnonLayoutWrapperData,
|
||||||
children: [
|
children: [
|
||||||
|
@ -361,6 +360,7 @@ const routes: Routes = [
|
||||||
path: "signup-link-expired",
|
path: "signup-link-expired",
|
||||||
canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()],
|
canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()],
|
||||||
data: {
|
data: {
|
||||||
|
pageIcon: RegistrationExpiredLinkIcon,
|
||||||
pageTitle: {
|
pageTitle: {
|
||||||
key: "expiredLink",
|
key: "expiredLink",
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { NgModule } from "@angular/core";
|
import { NgModule } from "@angular/core";
|
||||||
import { RouterModule, Routes } from "@angular/router";
|
import { RouterModule, Routes } from "@angular/router";
|
||||||
|
|
||||||
import { unauthGuardFn } from "@bitwarden/angular/auth/guards";
|
|
||||||
import { canAccessFeature } from "@bitwarden/angular/platform/guard/feature-flag.guard";
|
import { canAccessFeature } from "@bitwarden/angular/platform/guard/feature-flag.guard";
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
|
|
||||||
|
@ -11,7 +10,7 @@ const routes: Routes = [
|
||||||
{
|
{
|
||||||
path: "",
|
path: "",
|
||||||
component: AccessIntelligenceComponent,
|
component: AccessIntelligenceComponent,
|
||||||
canActivate: [canAccessFeature(FeatureFlag.AccessIntelligence), unauthGuardFn()],
|
canActivate: [canAccessFeature(FeatureFlag.AccessIntelligence)],
|
||||||
data: {
|
data: {
|
||||||
titleId: "accessIntelligence",
|
titleId: "accessIntelligence",
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
<app-header></app-header>
|
<app-header></app-header>
|
||||||
<bit-tab-group [(selectedIndex)]="tabIndex">
|
<bit-tab-group [(selectedIndex)]="tabIndex">
|
||||||
<bit-tab label="{{ 'allApplicationsWithCount' | i18n: apps.length }}">
|
<bit-tab label="Raw Data">
|
||||||
|
<tools-password-health></tools-password-health>
|
||||||
|
</bit-tab>
|
||||||
|
<!-- <bit-tab label="{{ 'allApplicationsWithCount' | i18n: apps.length }}">
|
||||||
<h2 bitTypography="h2">{{ "allApplications" | i18n }}</h2>
|
<h2 bitTypography="h2">{{ "allApplications" | i18n }}</h2>
|
||||||
<tools-application-table></tools-application-table>
|
<tools-application-table></tools-application-table>
|
||||||
</bit-tab>
|
</bit-tab>
|
||||||
|
@ -19,5 +22,5 @@
|
||||||
</ng-template>
|
</ng-template>
|
||||||
<h2 bitTypography="h2">{{ "notifiedMembers" | i18n }}</h2>
|
<h2 bitTypography="h2">{{ "notifiedMembers" | i18n }}</h2>
|
||||||
<tools-notified-members-table></tools-notified-members-table>
|
<tools-notified-members-table></tools-notified-members-table>
|
||||||
</bit-tab>
|
</bit-tab> -->
|
||||||
</bit-tab-group>
|
</bit-tab-group>
|
||||||
|
|
|
@ -11,6 +11,7 @@ import { HeaderModule } from "../../layouts/header/header.module";
|
||||||
|
|
||||||
import { ApplicationTableComponent } from "./application-table.component";
|
import { ApplicationTableComponent } from "./application-table.component";
|
||||||
import { NotifiedMembersTableComponent } from "./notified-members-table.component";
|
import { NotifiedMembersTableComponent } from "./notified-members-table.component";
|
||||||
|
import { PasswordHealthComponent } from "./password-health.component";
|
||||||
|
|
||||||
export enum AccessIntelligenceTabType {
|
export enum AccessIntelligenceTabType {
|
||||||
AllApps = 0,
|
AllApps = 0,
|
||||||
|
@ -26,6 +27,7 @@ export enum AccessIntelligenceTabType {
|
||||||
CommonModule,
|
CommonModule,
|
||||||
JslibModule,
|
JslibModule,
|
||||||
HeaderModule,
|
HeaderModule,
|
||||||
|
PasswordHealthComponent,
|
||||||
NotifiedMembersTableComponent,
|
NotifiedMembersTableComponent,
|
||||||
TabsModule,
|
TabsModule,
|
||||||
],
|
],
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
<bit-container>
|
||||||
|
<p>{{ "passwordsReportDesc" | i18n }}</p>
|
||||||
|
<div *ngIf="loading">
|
||||||
|
<i
|
||||||
|
class="bwi bwi-spinner bwi-spin tw-text-muted"
|
||||||
|
title="{{ 'loading' | i18n }}"
|
||||||
|
aria-hidden="true"
|
||||||
|
></i>
|
||||||
|
<span class="tw-sr-only">{{ "loading" | i18n }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="tw-mt-4" *ngIf="!loading">
|
||||||
|
<bit-table [dataSource]="dataSource">
|
||||||
|
<ng-container header>
|
||||||
|
<tr bitRow>
|
||||||
|
<th bitCell></th>
|
||||||
|
<th bitCell bitSortable="name">{{ "name" | i18n }}</th>
|
||||||
|
<th bitCell class="tw-text-right">{{ "weakness" | i18n }}</th>
|
||||||
|
<th bitCell class="tw-text-right">{{ "timesReused" | i18n }}</th>
|
||||||
|
<th bitCell class="tw-text-right">{{ "timesExposed" | i18n }}</th>
|
||||||
|
</tr>
|
||||||
|
</ng-container>
|
||||||
|
<ng-template body let-rows$>
|
||||||
|
<tr bitRow *ngFor="let r of rows$ | async">
|
||||||
|
<td bitCell>
|
||||||
|
<app-vault-icon [cipher]="r"></app-vault-icon>
|
||||||
|
</td>
|
||||||
|
<td bitCell>
|
||||||
|
<ng-container>
|
||||||
|
<span>{{ r.name }}</span>
|
||||||
|
</ng-container>
|
||||||
|
<br />
|
||||||
|
<small>{{ r.subTitle }}</small>
|
||||||
|
</td>
|
||||||
|
<td bitCell class="tw-text-right">
|
||||||
|
<span
|
||||||
|
bitBadge
|
||||||
|
*ngIf="passwordStrengthMap.has(r.id)"
|
||||||
|
[variant]="passwordStrengthMap.get(r.id)[1]"
|
||||||
|
>
|
||||||
|
{{ passwordStrengthMap.get(r.id)[0] | i18n }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td bitCell class="tw-text-right">
|
||||||
|
<span bitBadge *ngIf="passwordUseMap.has(r.login.password)" variant="warning">
|
||||||
|
{{ "reusedXTimes" | i18n: passwordUseMap.get(r.login.password) }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td bitCell class="tw-text-right">
|
||||||
|
<span bitBadge *ngIf="exposedPasswordMap.has(r.id)" variant="warning">
|
||||||
|
{{ "exposedXTimes" | i18n: exposedPasswordMap.get(r.id) }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</ng-template>
|
||||||
|
</bit-table>
|
||||||
|
</div>
|
||||||
|
</bit-container>
|
|
@ -0,0 +1,114 @@
|
||||||
|
import { ComponentFixture, TestBed } from "@angular/core/testing";
|
||||||
|
import { ActivatedRoute, convertToParamMap } from "@angular/router";
|
||||||
|
import { MockProxy, mock } from "jest-mock-extended";
|
||||||
|
import { of } from "rxjs";
|
||||||
|
|
||||||
|
import { AuditService } from "@bitwarden/common/abstractions/audit.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 { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength";
|
||||||
|
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||||
|
import { TableModule } from "@bitwarden/components";
|
||||||
|
import { TableBodyDirective } from "@bitwarden/components/src/table/table.component";
|
||||||
|
|
||||||
|
import { LooseComponentsModule } from "../../shared";
|
||||||
|
import { PipesModule } from "../../vault/individual-vault/pipes/pipes.module";
|
||||||
|
// eslint-disable-next-line no-restricted-imports
|
||||||
|
import { cipherData } from "../reports/pages/reports-ciphers.mock";
|
||||||
|
|
||||||
|
import { PasswordHealthComponent } from "./password-health.component";
|
||||||
|
|
||||||
|
describe("PasswordHealthComponent", () => {
|
||||||
|
let component: PasswordHealthComponent;
|
||||||
|
let fixture: ComponentFixture<PasswordHealthComponent>;
|
||||||
|
let passwordStrengthService: MockProxy<PasswordStrengthServiceAbstraction>;
|
||||||
|
let organizationService: MockProxy<OrganizationService>;
|
||||||
|
let cipherServiceMock: MockProxy<CipherService>;
|
||||||
|
let auditServiceMock: MockProxy<AuditService>;
|
||||||
|
const activeRouteParams = convertToParamMap({ organizationId: "orgId" });
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
passwordStrengthService = mock<PasswordStrengthServiceAbstraction>();
|
||||||
|
auditServiceMock = mock<AuditService>();
|
||||||
|
organizationService = mock<OrganizationService>({
|
||||||
|
get: jest.fn().mockResolvedValue({ id: "orgId" } as Organization),
|
||||||
|
});
|
||||||
|
cipherServiceMock = mock<CipherService>({
|
||||||
|
getAllFromApiForOrganization: jest.fn().mockResolvedValue(cipherData),
|
||||||
|
});
|
||||||
|
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [PasswordHealthComponent, PipesModule, TableModule, LooseComponentsModule],
|
||||||
|
declarations: [TableBodyDirective],
|
||||||
|
providers: [
|
||||||
|
{ provide: CipherService, useValue: cipherServiceMock },
|
||||||
|
{ provide: PasswordStrengthServiceAbstraction, useValue: passwordStrengthService },
|
||||||
|
{ provide: OrganizationService, useValue: organizationService },
|
||||||
|
{ provide: I18nService, useValue: mock<I18nService>() },
|
||||||
|
{ provide: AuditService, useValue: auditServiceMock },
|
||||||
|
{
|
||||||
|
provide: ActivatedRoute,
|
||||||
|
useValue: {
|
||||||
|
paramMap: of(activeRouteParams),
|
||||||
|
url: of([]),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}).compileComponents();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(PasswordHealthComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should initialize component", () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should populate reportCiphers with ciphers that have password issues", async () => {
|
||||||
|
passwordStrengthService.getPasswordStrength.mockReturnValue({ score: 1 } as any);
|
||||||
|
|
||||||
|
auditServiceMock.passwordLeaked.mockResolvedValue(5);
|
||||||
|
|
||||||
|
await component.setCiphers();
|
||||||
|
|
||||||
|
const cipherIds = component.reportCiphers.map((c) => c.id);
|
||||||
|
|
||||||
|
expect(cipherIds).toEqual([
|
||||||
|
"cbea34a8-bde4-46ad-9d19-b05001228ab1",
|
||||||
|
"cbea34a8-bde4-46ad-9d19-b05001228ab2",
|
||||||
|
"cbea34a8-bde4-46ad-9d19-b05001228cd3",
|
||||||
|
]);
|
||||||
|
expect(component.reportCiphers.length).toEqual(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should correctly populate passwordStrengthMap", async () => {
|
||||||
|
passwordStrengthService.getPasswordStrength.mockImplementation((password) => {
|
||||||
|
let score = 0;
|
||||||
|
if (password === "123") {
|
||||||
|
score = 1;
|
||||||
|
} else {
|
||||||
|
score = 4;
|
||||||
|
}
|
||||||
|
return { score } as any;
|
||||||
|
});
|
||||||
|
|
||||||
|
auditServiceMock.passwordLeaked.mockResolvedValue(0);
|
||||||
|
|
||||||
|
await component.setCiphers();
|
||||||
|
|
||||||
|
expect(component.passwordStrengthMap.size).toBeGreaterThan(0);
|
||||||
|
expect(component.passwordStrengthMap.get("cbea34a8-bde4-46ad-9d19-b05001228ab2")).toEqual([
|
||||||
|
"veryWeak",
|
||||||
|
"danger",
|
||||||
|
]);
|
||||||
|
expect(component.passwordStrengthMap.get("cbea34a8-bde4-46ad-9d19-b05001228cd3")).toEqual([
|
||||||
|
"veryWeak",
|
||||||
|
"danger",
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,229 @@
|
||||||
|
import { CommonModule } from "@angular/common";
|
||||||
|
import { Component, DestroyRef, inject, OnInit } from "@angular/core";
|
||||||
|
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
||||||
|
import { ActivatedRoute } from "@angular/router";
|
||||||
|
import { from, map, switchMap, tap } from "rxjs";
|
||||||
|
|
||||||
|
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||||
|
import { AuditService } from "@bitwarden/common/abstractions/audit.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 { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||||
|
import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength";
|
||||||
|
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||||
|
import { CipherType } from "@bitwarden/common/vault/enums";
|
||||||
|
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||||
|
import {
|
||||||
|
BadgeModule,
|
||||||
|
BadgeVariant,
|
||||||
|
ContainerComponent,
|
||||||
|
TableDataSource,
|
||||||
|
TableModule,
|
||||||
|
} from "@bitwarden/components";
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-restricted-imports
|
||||||
|
import { HeaderModule } from "../../layouts/header/header.module";
|
||||||
|
// eslint-disable-next-line no-restricted-imports
|
||||||
|
import { OrganizationBadgeModule } from "../../vault/individual-vault/organization-badge/organization-badge.module";
|
||||||
|
// eslint-disable-next-line no-restricted-imports
|
||||||
|
import { PipesModule } from "../../vault/individual-vault/pipes/pipes.module";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
standalone: true,
|
||||||
|
selector: "tools-password-health",
|
||||||
|
templateUrl: "password-health.component.html",
|
||||||
|
imports: [
|
||||||
|
BadgeModule,
|
||||||
|
OrganizationBadgeModule,
|
||||||
|
CommonModule,
|
||||||
|
ContainerComponent,
|
||||||
|
PipesModule,
|
||||||
|
JslibModule,
|
||||||
|
HeaderModule,
|
||||||
|
TableModule,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class PasswordHealthComponent implements OnInit {
|
||||||
|
passwordStrengthMap = new Map<string, [string, BadgeVariant]>();
|
||||||
|
|
||||||
|
weakPasswordCiphers: CipherView[] = [];
|
||||||
|
|
||||||
|
passwordUseMap = new Map<string, number>();
|
||||||
|
|
||||||
|
exposedPasswordMap = new Map<string, number>();
|
||||||
|
|
||||||
|
dataSource = new TableDataSource<CipherView>();
|
||||||
|
|
||||||
|
reportCiphers: CipherView[] = [];
|
||||||
|
reportCipherIds: string[] = [];
|
||||||
|
|
||||||
|
organization: Organization;
|
||||||
|
|
||||||
|
loading = true;
|
||||||
|
|
||||||
|
private destroyRef = inject(DestroyRef);
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
protected cipherService: CipherService,
|
||||||
|
protected passwordStrengthService: PasswordStrengthServiceAbstraction,
|
||||||
|
protected organizationService: OrganizationService,
|
||||||
|
protected auditService: AuditService,
|
||||||
|
protected i18nService: I18nService,
|
||||||
|
protected activatedRoute: ActivatedRoute,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.activatedRoute.paramMap
|
||||||
|
.pipe(
|
||||||
|
takeUntilDestroyed(this.destroyRef),
|
||||||
|
map((params) => params.get("organizationId")),
|
||||||
|
switchMap((organizationId) => {
|
||||||
|
return from(this.organizationService.get(organizationId));
|
||||||
|
}),
|
||||||
|
tap((organization) => {
|
||||||
|
this.organization = organization;
|
||||||
|
}),
|
||||||
|
switchMap(() => from(this.setCiphers())),
|
||||||
|
)
|
||||||
|
.subscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
async setCiphers() {
|
||||||
|
const allCiphers = await this.cipherService.getAllFromApiForOrganization(this.organization.id);
|
||||||
|
allCiphers.forEach(async (cipher) => {
|
||||||
|
this.findWeakPassword(cipher);
|
||||||
|
this.findReusedPassword(cipher);
|
||||||
|
await this.findExposedPassword(cipher);
|
||||||
|
});
|
||||||
|
this.dataSource.data = this.reportCiphers;
|
||||||
|
this.loading = false;
|
||||||
|
|
||||||
|
// const reportIssues = allCiphers.map((c) => {
|
||||||
|
// if (this.passwordStrengthMap.has(c.id)) {
|
||||||
|
// return c;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (this.passwordUseMap.has(c.id)) {
|
||||||
|
// return c;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (this.exposedPasswordMap.has(c.id)) {
|
||||||
|
// return c;
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
|
protected checkForExistingCipher(ciph: CipherView) {
|
||||||
|
if (!this.reportCipherIds.includes(ciph.id)) {
|
||||||
|
this.reportCipherIds.push(ciph.id);
|
||||||
|
this.reportCiphers.push(ciph);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async findExposedPassword(cipher: CipherView) {
|
||||||
|
const { type, login, isDeleted, edit, viewPassword, id } = cipher;
|
||||||
|
if (
|
||||||
|
type !== CipherType.Login ||
|
||||||
|
login.password == null ||
|
||||||
|
login.password === "" ||
|
||||||
|
isDeleted ||
|
||||||
|
(!this.organization && !edit) ||
|
||||||
|
!viewPassword
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const exposedCount = await this.auditService.passwordLeaked(login.password);
|
||||||
|
if (exposedCount > 0) {
|
||||||
|
this.exposedPasswordMap.set(id, exposedCount);
|
||||||
|
this.checkForExistingCipher(cipher);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected findReusedPassword(cipher: CipherView) {
|
||||||
|
const { type, login, isDeleted, edit, viewPassword } = cipher;
|
||||||
|
if (
|
||||||
|
type !== CipherType.Login ||
|
||||||
|
login.password == null ||
|
||||||
|
login.password === "" ||
|
||||||
|
isDeleted ||
|
||||||
|
(!this.organization && !edit) ||
|
||||||
|
!viewPassword
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.passwordUseMap.has(login.password)) {
|
||||||
|
this.passwordUseMap.set(login.password, this.passwordUseMap.get(login.password) || 0 + 1);
|
||||||
|
} else {
|
||||||
|
this.passwordUseMap.set(login.password, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.checkForExistingCipher(cipher);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected findWeakPassword(cipher: CipherView): void {
|
||||||
|
const { type, login, isDeleted, edit, viewPassword } = cipher;
|
||||||
|
if (
|
||||||
|
type !== CipherType.Login ||
|
||||||
|
login.password == null ||
|
||||||
|
login.password === "" ||
|
||||||
|
isDeleted ||
|
||||||
|
(!this.organization && !edit) ||
|
||||||
|
!viewPassword
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasUserName = this.isUserNameNotEmpty(cipher);
|
||||||
|
let userInput: string[] = [];
|
||||||
|
if (hasUserName) {
|
||||||
|
const atPosition = login.username.indexOf("@");
|
||||||
|
if (atPosition > -1) {
|
||||||
|
userInput = userInput
|
||||||
|
.concat(
|
||||||
|
login.username
|
||||||
|
.substring(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 { score } = this.passwordStrengthService.getPasswordStrength(
|
||||||
|
login.password,
|
||||||
|
null,
|
||||||
|
userInput.length > 0 ? userInput : null,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (score != null && score <= 2) {
|
||||||
|
this.passwordStrengthMap.set(cipher.id, this.scoreKey(score));
|
||||||
|
this.checkForExistingCipher(cipher);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private isUserNameNotEmpty(c: CipherView): boolean {
|
||||||
|
return !Utils.isNullOrWhitespace(c.login.username);
|
||||||
|
}
|
||||||
|
|
||||||
|
private scoreKey(score: number): [string, BadgeVariant] {
|
||||||
|
switch (score) {
|
||||||
|
case 4:
|
||||||
|
return ["strong", "success"];
|
||||||
|
case 3:
|
||||||
|
return ["good", "primary"];
|
||||||
|
case 2:
|
||||||
|
return ["weak", "warning"];
|
||||||
|
default:
|
||||||
|
return ["veryWeak", "danger"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -288,6 +288,7 @@ function createCollectionView(i: number): CollectionAdminView {
|
||||||
view.id = `collection-${i}`;
|
view.id = `collection-${i}`;
|
||||||
view.name = `Collection ${i}`;
|
view.name = `Collection ${i}`;
|
||||||
view.organizationId = organization?.id;
|
view.organizationId = organization?.id;
|
||||||
|
view.manage = true;
|
||||||
|
|
||||||
if (group !== undefined) {
|
if (group !== undefined) {
|
||||||
view.groups = [
|
view.groups = [
|
||||||
|
|
|
@ -15,7 +15,7 @@ const icon = svgIcon`<svg xmlns="http://www.w3.org/2000/svg" width="120" height=
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [SharedModule, ButtonModule, NoItemsModule],
|
imports: [SharedModule, ButtonModule, NoItemsModule],
|
||||||
template: `<bit-no-items [icon]="icon" class="tw-mt-2 tw-block">
|
template: `<bit-no-items [icon]="icon" class="tw-mt-2 tw-block">
|
||||||
<span slot="title" class="tw-mt-4 tw-block">{{ "collectionAccessRestricted" | i18n }}</span>
|
<span slot="title" class="tw-mt-4 tw-block">{{ "youDoNotHavePermissions" | i18n }}</span>
|
||||||
<button
|
<button
|
||||||
*ngIf="canEditCollection"
|
*ngIf="canEditCollection"
|
||||||
slot="button"
|
slot="button"
|
||||||
|
|
|
@ -1208,6 +1208,9 @@
|
||||||
"noPermissionToViewAllCollectionItems": {
|
"noPermissionToViewAllCollectionItems": {
|
||||||
"message": "You do not have permission to view all items in this collection."
|
"message": "You do not have permission to view all items in this collection."
|
||||||
},
|
},
|
||||||
|
"youDoNotHavePermissions": {
|
||||||
|
"message": "You do not have permissions to this collection"
|
||||||
|
},
|
||||||
"noCollectionsInList": {
|
"noCollectionsInList": {
|
||||||
"message": "There are no collections to list."
|
"message": "There are no collections to list."
|
||||||
},
|
},
|
||||||
|
@ -3793,6 +3796,15 @@
|
||||||
"joinOrganization": {
|
"joinOrganization": {
|
||||||
"message": "Join organization"
|
"message": "Join organization"
|
||||||
},
|
},
|
||||||
|
"joinOrganizationName": {
|
||||||
|
"message": "Join $ORGANIZATIONNAME$",
|
||||||
|
"placeholders": {
|
||||||
|
"organizationName": {
|
||||||
|
"content": "$1",
|
||||||
|
"example": "My Org Name"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"joinOrganizationDesc": {
|
"joinOrganizationDesc": {
|
||||||
"message": "You've been invited to join the organization listed above. To accept the invitation, you need to log in or create a new Bitwarden account."
|
"message": "You've been invited to join the organization listed above. To accept the invitation, you need to log in or create a new Bitwarden account."
|
||||||
},
|
},
|
||||||
|
@ -8204,6 +8216,12 @@
|
||||||
"limitCollectionCreationDeletionDesc": {
|
"limitCollectionCreationDeletionDesc": {
|
||||||
"message": "Limit collection creation and deletion to owners and admins"
|
"message": "Limit collection creation and deletion to owners and admins"
|
||||||
},
|
},
|
||||||
|
"limitCollectionCreationDesc": {
|
||||||
|
"message": "Limit collection creation to owners and admins"
|
||||||
|
},
|
||||||
|
"limitCollectionDeletionDesc": {
|
||||||
|
"message": "Limit collection deletion to owners and admins"
|
||||||
|
},
|
||||||
"allowAdminAccessToAllCollectionItemsDesc": {
|
"allowAdminAccessToAllCollectionItemsDesc": {
|
||||||
"message": "Owners and admins can manage all collections and items"
|
"message": "Owners and admins can manage all collections and items"
|
||||||
},
|
},
|
||||||
|
|
|
@ -74,7 +74,7 @@ export class CollectionView implements View, ITreeNodeObject {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const canDeleteManagedCollections = !org?.limitCollectionCreationDeletion || org.isAdmin;
|
const canDeleteManagedCollections = !org?.limitCollectionDeletion || org.isAdmin;
|
||||||
|
|
||||||
// Only use individual permissions, not admin permissions
|
// Only use individual permissions, not admin permissions
|
||||||
return canDeleteManagedCollections && this.manage;
|
return canDeleteManagedCollections && this.manage;
|
||||||
|
|
|
@ -2,8 +2,10 @@ export * from "./bitwarden-logo.icon";
|
||||||
export * from "./bitwarden-shield.icon";
|
export * from "./bitwarden-shield.icon";
|
||||||
export * from "./lock.icon";
|
export * from "./lock.icon";
|
||||||
export * from "./registration-check-email.icon";
|
export * from "./registration-check-email.icon";
|
||||||
export * from "./registration-expired-link.icon";
|
|
||||||
export * from "./user-lock.icon";
|
export * from "./user-lock.icon";
|
||||||
export * from "./user-verification-biometrics-fingerprint.icon";
|
export * from "./user-verification-biometrics-fingerprint.icon";
|
||||||
export * from "./wave.icon";
|
export * from "./wave.icon";
|
||||||
export * from "./vault.icon";
|
export * from "./vault.icon";
|
||||||
|
export * from "./registration-user-add.icon";
|
||||||
|
export * from "./registration-lock-alt.icon";
|
||||||
|
export * from "./registration-expired-link.icon";
|
||||||
|
|
|
@ -1,12 +1,23 @@
|
||||||
import { svgIcon } from "@bitwarden/components";
|
import { svgIcon } from "@bitwarden/components";
|
||||||
|
|
||||||
export const RegistrationCheckEmailIcon = svgIcon`
|
export const RegistrationCheckEmailIcon = svgIcon`
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="144" height="113" fill="none">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 100" fill="none">
|
||||||
<g fill="#175DDC" clip-path="url(#a)">
|
<path class="tw-stroke-art-primary" stroke-linecap="round" stroke-width="2.477"
|
||||||
<path class="tw-fill-primary-600" fill-rule="evenodd" d="M39.19 26.64c0-.765.62-1.384 1.383-1.384h18.785a1.383 1.383 0 0 1 0 2.766H40.573c-.764 0-1.383-.619-1.383-1.383ZM39.19 37.819c0-.764.62-1.383 1.383-1.383H58.81a1.383 1.383 0 0 1 0 2.766H40.573c-.764 0-1.383-.62-1.383-1.383ZM39.19 48.998c0-.764.62-1.383 1.383-1.383H61.82a1.383 1.383 0 0 1 0 2.766H40.573c-.764 0-1.383-.62-1.383-1.383Z" clip-rule="evenodd"/>
|
d="M104.552 42.242v12.023M48.415 17.31l6.51-4.858a7.43 7.43 0 0 1 8.984.074l1.172.904M24.844 34.897l-6.857 5.116A7.43 7.43 0 0 0 15 45.97v42.366a7.43 7.43 0 0 0 7.43 7.43h74.691a7.43 7.43 0 0 0 7.431-7.43V64.291" />
|
||||||
<path class="tw-fill-primary-600" d="M94.576 60.504c0 .382.31.692.691.692 14.892 0 26.977-11.935 26.977-26.675a.692.692 0 0 0-1.383 0c0 13.96-11.451 25.292-25.594 25.292a.691.691 0 0 0-.691.691ZM68.982 35.213c.382 0 .692-.31.692-.692 0-13.96 11.45-25.291 25.593-25.291a.691.691 0 1 0 0-1.383c-14.89 0-26.976 11.935-26.976 26.674 0 .382.31.692.691.692Z"/>
|
<path class="tw-stroke-art-primary" stroke-linecap="round" stroke-width="2.477"
|
||||||
<path class="tw-fill-primary-600" fill-rule="evenodd" d="M95.387 2.926c-6.295 0-12.16 1.84-17.086 5.013l-1.136-.877a9.68 9.68 0 0 0-11.705-.096l-8.172 6.098a1.33 1.33 0 0 0-.064.05H33.393a4.149 4.149 0 0 0-4.149 4.15v16.753c-.07.035-.14.078-.205.127l-8.464 6.315a9.68 9.68 0 0 0-3.89 7.759v51.696c0 5.346 4.333 9.68 9.68 9.68h90.733c5.346 0 9.68-4.334 9.68-9.68v-26.48l8.099 8.098a4.84 4.84 0 0 0 6.845 0l.721-.721a4.84 4.84 0 0 0 0-6.845l-15.665-15.665V44.056c0-.587-.366-1.089-.882-1.29a31.666 31.666 0 0 0 1.086-8.245c0-17.45-14.146-31.595-31.595-31.595Zm28.625 52.61v-7.624a31.463 31.463 0 0 1-2.803 4.82l2.803 2.803Zm-4.51-.6a31.84 31.84 0 0 1-3.651 3.659l20.981 20.982c.81.81 2.124.81 2.934 0l.721-.722a2.073 2.073 0 0 0 0-2.933l-20.985-20.986Zm-5.851 5.37a31.434 31.434 0 0 1-16.653 5.77l-.023.014-9.463 5.427a15.205 15.205 0 0 1 2.167 1.666l33.149 30.601a6.876 6.876 0 0 0 1.184-3.87V70.668l-10.361-10.362ZM29.244 37.442l-7.014 5.234a6.914 6.914 0 0 0-2.588 3.925c.062.025.123.056.183.091l9.42 5.626V37.442Zm2.766 16.527 8.172 4.881c.124-.036.255-.056.39-.056h27.813a1.383 1.383 0 0 1 0 2.766H44.72l13.656 8.156a15.208 15.208 0 0 1 4.116-.567H79.36c1.801 0 3.571.32 5.233.928.095-.103.206-.193.334-.267l6.805-3.902C76.004 64.097 63.791 50.735 63.791 34.52a31.454 31.454 0 0 1 6.082-18.64h-36.48c-.764 0-1.383.619-1.383 1.383v36.705Zm40.135-40.851a31.78 31.78 0 0 1 3.8-3.504l-.47-.363a6.914 6.914 0 0 0-8.36-.068l-5.27 3.932h10.212c.03 0 .059 0 .088.003ZM66.557 34.52c0-15.922 12.907-28.83 28.83-28.83 15.922 0 28.829 12.908 28.829 28.83 0 15.922-12.907 28.83-28.83 28.83-15.922 0-28.83-12.908-28.83-28.83ZM19.45 49.691v50.223c0 1.418.428 2.738 1.16 3.835l31.298-30.315a15.21 15.21 0 0 1 3.266-2.41L19.45 49.69Zm3.124 56.007a6.888 6.888 0 0 0 3.79 1.13h90.734a6.879 6.879 0 0 0 3.752-1.106L87.803 75.216a12.446 12.446 0 0 0-8.442-3.301H62.49a12.446 12.446 0 0 0-8.658 3.506l-31.259 30.277Z" clip-rule="evenodd"/></g><defs><clipPath id="a">
|
d="M25.48 50.5V20.058a2.477 2.477 0 0 1 2.476-2.477h32.091" />
|
||||||
<path class="tw-fill-primary-600" fill="#fff" d="M.09 0h143.82v112.705H.09z"/>
|
<path class="tw-stroke-art-accent" stroke-linecap="round" stroke-width="2.477"
|
||||||
</clipPath>
|
d="M33.778 27.71h15.674M33.778 37.037h15.217M33.778 46.364h17.728M33.778 55.691h23.206" />
|
||||||
</defs>
|
<path class="tw-stroke-art-primary" stroke-width="2.477"
|
||||||
</svg>`;
|
d="M102.645 93.86 74.211 67.614a12.384 12.384 0 0 0-8.4-3.284H52.41c-3.216 0-6.306 1.251-8.616 3.488L16.904 93.86" />
|
||||||
|
<path class="tw-stroke-art-primary" stroke-linecap="round" stroke-width="2.477" d="m71.36 64.73 8.904-5.106" />
|
||||||
|
<path class="tw-stroke-art-primary" stroke-linecap="round" stroke-width="2.477" d="M1.238-1.238h37.47"
|
||||||
|
transform="matrix(.85856 .5127 .51278 -.85852 15.476 43.85)" />
|
||||||
|
<path class="tw-stroke-art-primary" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.477"
|
||||||
|
d="M104.722 34.286c0 13.922-11.286 25.207-25.209 25.207-13.922 0-25.208-11.285-25.208-25.207 0-13.92 11.286-25.206 25.208-25.206 13.923 0 25.209 11.285 25.209 25.206Z" />
|
||||||
|
<path class="tw-stroke-art-accent" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.238"
|
||||||
|
d="M101.346 34.287c0 11.972-9.82 21.678-21.932 21.678m0-43.355c-12.113 0-21.932 9.705-21.932 21.677" />
|
||||||
|
<path class="tw-stroke-art-primary" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.477"
|
||||||
|
d="m99.636 49.689 3.853 3.852 14.322 14.32a3.096 3.096 0 0 1 0 4.379l-.303.303a3.097 3.097 0 0 1-4.379 0l-14.322-14.32-3.852-3.853" />
|
||||||
|
</svg>
|
||||||
|
`;
|
||||||
|
|
|
@ -1,20 +1,9 @@
|
||||||
import { svgIcon } from "@bitwarden/components";
|
import { svgIcon } from "@bitwarden/components";
|
||||||
|
|
||||||
export const RegistrationExpiredLinkIcon = svgIcon`
|
export const RegistrationExpiredLinkIcon = svgIcon`
|
||||||
<svg width="64" height="64" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 100" fill="none">
|
||||||
<g clip-path="url(#clip0_8198_6255)">
|
<path class="tw-art-primary" fill="#175DDC"
|
||||||
<path
|
d="M36.167 38.348c4.543-9.911 14.651-16.806 26.387-16.806 15.986 0 28.945 12.79 28.945 28.567 0 15.777-12.96 28.568-28.945 28.568-11.988 0-22.278-7.193-26.673-17.453-.484-1.13-1.803-1.657-2.947-1.18a2.209 2.209 0 0 0-1.195 2.908c5.073 11.845 16.957 20.163 30.815 20.163 18.47 0 33.442-14.777 33.442-33.006 0-18.228-14.972-33.006-33.442-33.006-14.18 0-26.294 8.708-31.16 20.999l-3.547-6.307a2.057 2.057 0 0 0-3.586 2.017l5.807 10.326a2.057 2.057 0 0 0 2.802.785l10.327-5.808a2.057 2.057 0 1 0-2.018-3.586l-5.012 2.819Z" />
|
||||||
class="tw-fill-primary-600"
|
<path class="tw-art-primary" fill="#175DDC"
|
||||||
d="M2.70609 5.38455C3.71495 3.18341 5.95991 1.65214 8.56633 1.65214C12.1167 1.65214 14.9948 4.4927 14.9948 7.99672C14.9948 11.5007 12.1167 14.3413 8.56633 14.3413C5.90396 14.3413 3.61848 12.7438 2.64241 10.4652C2.53502 10.2144 2.24202 10.0971 1.98799 10.2031C1.73396 10.3091 1.61509 10.5983 1.72248 10.849C2.8493 13.4796 5.48864 15.327 8.56633 15.327C12.6683 15.327 15.9936 12.0451 15.9936 7.99672C15.9936 3.9483 12.6683 0.666412 8.56633 0.666412C5.41721 0.666412 2.72675 2.60033 1.64603 5.33002L0.858226 3.92917C0.734524 3.70921 0.455929 3.63117 0.235967 3.75487C0.0160044 3.87858 -0.0620299 4.15717 0.0616722 4.37713L1.35147 6.6706C1.47517 6.89056 1.75377 6.9686 1.97373 6.8449L4.2672 5.5551C4.48716 5.4314 4.5652 5.1528 4.44149 4.93284C4.31779 4.71288 4.0392 4.63484 3.81923 4.75854L2.70609 5.38455Z"
|
d="M72.263 60.447a2.25 2.25 0 0 1-2.785-.229l-8.806-8.242a2.229 2.229 0 0 1-.512-.727 2.148 2.148 0 0 1-.183-.867V29.829c0-.583.234-1.142.653-1.556a2.251 2.251 0 0 1 3.152 0c.42.412.653.973.653 1.556v19.602l8.11 7.595a2.178 2.178 0 0 1 .537 2.413c-.164.41-.452.761-.82 1.008Z" />
|
||||||
fill="#175DDC" />
|
|
||||||
<path
|
|
||||||
class="tw-fill-primary-600"
|
|
||||||
d="M10.7225 10.2926C10.6408 10.3474 10.5437 10.3767 10.4447 10.3767C10.318 10.3767 10.1962 10.3283 10.1041 10.2418L8.14837 8.41125C8.09985 8.36578 8.06123 8.31053 8.03449 8.24991C8.00775 8.18928 7.99389 8.12376 7.99389 8.05727V3.49271C7.99389 3.36314 8.04588 3.23896 8.13896 3.14704C8.23204 3.05512 8.3578 3.00378 8.48901 3.00378C8.62021 3.00378 8.74597 3.05561 8.83905 3.14704C8.93213 3.23847 8.98412 3.36314 8.98412 3.49271V7.84605L10.7853 9.53284C10.8571 9.60031 10.9071 9.68734 10.9284 9.78268C10.9497 9.87802 10.9413 9.97776 10.9047 10.0687C10.868 10.1596 10.8042 10.2379 10.7225 10.2926Z"
|
|
||||||
fill="#175DDC" />
|
|
||||||
</g>
|
|
||||||
<defs>
|
|
||||||
<clipPath id="clip0_8198_6255">
|
|
||||||
<rect width="15.9952" height="15.9952" fill="white" />
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
</svg>`;
|
</svg>`;
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
import { svgIcon } from "@bitwarden/components";
|
||||||
|
|
||||||
|
export const RegistrationLockAltIcon = svgIcon`
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 100" fill="none">
|
||||||
|
<path class="tw-fill-art-primary" fill-rule="evenodd"
|
||||||
|
d="M47.048 77.093a1 1 0 0 1 1 1v5.811a1 1 0 0 1-2 0v-5.811a1 1 0 0 1 1-1Z"
|
||||||
|
clip-rule="evenodd" />
|
||||||
|
<path class="tw-fill-art-primary" fill-rule="evenodd"
|
||||||
|
d="M53.547 81.8a1 1 0 0 1-.643 1.26l-5.548 1.795a1 1 0 1 1-.616-1.902l5.547-1.797a1 1 0 0 1 1.26.644Z"
|
||||||
|
clip-rule="evenodd" />
|
||||||
|
<path class="tw-fill-art-primary" fill-rule="evenodd"
|
||||||
|
d="M46.462 83.094a1 1 0 0 1 1.396.225l3.435 4.755a1 1 0 1 1-1.622 1.17l-3.434-4.754a1 1 0 0 1 .225-1.396Z"
|
||||||
|
clip-rule="evenodd" />
|
||||||
|
<path class="tw-fill-art-primary" fill-rule="evenodd"
|
||||||
|
d="M47.634 83.094a1 1 0 0 1 .225 1.396l-3.434 4.755a1 1 0 1 1-1.621-1.171l3.434-4.755a1 1 0 0 1 1.396-.225Z"
|
||||||
|
clip-rule="evenodd" />
|
||||||
|
<path class="tw-fill-art-primary" fill-rule="evenodd"
|
||||||
|
d="M40.549 81.8a1 1 0 0 1 1.26-.644l5.547 1.797a1 1 0 1 1-.617 1.902l-5.547-1.796a1 1 0 0 1-.643-1.26ZM65.91 77.093a1 1 0 0 1 1 1v5.811a1 1 0 0 1-2 0v-5.811a1 1 0 0 1 1-1Z"
|
||||||
|
clip-rule="evenodd" />
|
||||||
|
<path class="tw-fill-art-primary" fill-rule="evenodd"
|
||||||
|
d="M72.463 81.802a1 1 0 0 1-.647 1.258l-5.6 1.796a1 1 0 0 1-.611-1.904l5.6-1.796a1 1 0 0 1 1.258.646Z"
|
||||||
|
clip-rule="evenodd" />
|
||||||
|
<path class="tw-fill-art-primary" fill-rule="evenodd"
|
||||||
|
d="M65.325 83.094a1 1 0 0 1 1.396.225l3.434 4.755a1 1 0 0 1-1.621 1.17L65.1 84.49a1 1 0 0 1 .225-1.396Z"
|
||||||
|
clip-rule="evenodd" />
|
||||||
|
<path class="tw-fill-art-primary" fill-rule="evenodd"
|
||||||
|
d="M66.49 83.09a1 1 0 0 1 .235 1.394l-3.382 4.755a1 1 0 1 1-1.63-1.16l3.382-4.754a1 1 0 0 1 1.394-.236Z"
|
||||||
|
clip-rule="evenodd" />
|
||||||
|
<path class="tw-fill-art-primary" fill-rule="evenodd"
|
||||||
|
d="M59.41 81.8a1 1 0 0 1 1.26-.644l5.548 1.797a1 1 0 1 1-.616 1.902l-5.548-1.796a1 1 0 0 1-.643-1.26ZM77.5 88.5a1 1 0 0 1 1-1h11a1 1 0 1 1 0 2h-11a1 1 0 0 1-1-1ZM94.5 88.5a1 1 0 0 1 1-1h11a1 1 0 0 1 0 2h-11a1 1 0 0 1-1-1Z"
|
||||||
|
clip-rule="evenodd" />
|
||||||
|
<path class="tw-fill-art-accent" fill-rule="evenodd"
|
||||||
|
d="M105 72.5H46c-5.799 0-10.5 4.701-10.5 10.5v.5C35.5 89.299 40.201 94 46 94h59c5.799 0 10.5-4.701 10.5-10.5V83c0-5.799-4.701-10.5-10.5-10.5Zm-59-2c-6.904 0-12.5 5.596-12.5 12.5v.5C33.5 90.404 39.096 96 46 96h59c6.904 0 12.5-5.596 12.5-12.5V83c0-6.904-5.596-12.5-12.5-12.5H46Z"
|
||||||
|
clip-rule="evenodd" />
|
||||||
|
<path class="tw-fill-art-primary" fill-rule="evenodd"
|
||||||
|
d="M30.5 42.5a7 7 0 0 0-7 7V85a7 7 0 0 0 7 7h9v2h-9a9 9 0 0 1-9-9V49.5a9 9 0 0 1 9-9h49a9 9 0 0 1 9 9v22.25h-2V49.5a7 7 0 0 0-7-7h-49Z"
|
||||||
|
clip-rule="evenodd" />
|
||||||
|
<path class="tw-fill-art-primary" fill-rule="evenodd"
|
||||||
|
d="M54.75 5C43.592 5 34.5 14.056 34.5 25.15V41h-2V25.15C32.5 12.943 42.496 3 54.75 3 67.002 3 77 12.889 77 25.15V41h-2V25.15C75 14.005 65.91 5 54.75 5ZM51 54.158c0-1.996 1.543-3.658 3.5-3.658s3.5 1.662 3.5 3.658a3.722 3.722 0 0 1-1.201 2.758L56.8 57v6.106c0 1.298-1.006 2.395-2.3 2.395-1.294 0-2.3-1.097-2.3-2.395V57l.001-.083A3.722 3.722 0 0 1 51 54.158Zm3.5-2.658c-1.357 0-2.5 1.165-2.5 2.658a2.71 2.71 0 0 0 1.029 2.148l.231.18-.043.29c-.011.072-.017.147-.017.223v6.106c0 .795.606 1.395 1.3 1.395.694 0 1.3-.6 1.3-1.395V57c0-.076-.006-.15-.017-.224l-.043-.29.231-.179A2.71 2.71 0 0 0 57 54.158c0-1.493-1.143-2.658-2.5-2.658Z"
|
||||||
|
clip-rule="evenodd" />
|
||||||
|
</svg>`;
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { svgIcon } from "@bitwarden/components";
|
||||||
|
|
||||||
|
export const RegistrationUserAddIcon = svgIcon`
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 100" fill="none">
|
||||||
|
<path class="tw-fill-art-primary" fill-rule="evenodd"
|
||||||
|
d="M0 21.627a7.798 7.798 0 0 1 7.798-7.798H89.38a7.798 7.798 0 0 1 7.799 7.798v8.764h-2.4v-8.764a5.399 5.399 0 0 0-5.398-5.398H7.797A5.399 5.399 0 0 0 2.4 21.627v49.19a5.399 5.399 0 0 0 5.4 5.399h9.483v2.399H7.798A7.798 7.798 0 0 1 0 70.817v-49.19Zm49.378 54.589h13.498v2.399H49.378v-2.4Z"
|
||||||
|
clip-rule="evenodd" />
|
||||||
|
<path class="tw-fill-art-primary" fill-rule="evenodd"
|
||||||
|
d="M88.78 61.819c8.946 0 16.197-7.252 16.197-16.197s-7.251-16.196-16.196-16.196-16.197 7.251-16.197 16.196S79.836 61.82 88.781 61.82Zm0 2.4c10.27 0 18.597-8.326 18.597-18.597 0-10.27-8.326-18.596-18.596-18.596s-18.596 8.326-18.596 18.596S78.51 64.218 88.78 64.218Z"
|
||||||
|
clip-rule="evenodd" />
|
||||||
|
<path class="tw-fill-art-primary" fill-rule="evenodd"
|
||||||
|
d="M61.005 90.612h54.28c1.303 0 1.833-.344 2.01-.53.128-.134.396-.517.226-1.586-2.187-13.74-14.213-24.278-28.752-24.278S62.203 74.757 60.017 88.496c-.09.569.026 1.226.279 1.662.115.199.23.305.316.359.072.045.184.095.393.095Zm0 2.4h54.28c3.346 0 5.104-1.76 4.605-4.894-2.371-14.903-15.402-26.3-31.121-26.3-15.72 0-28.75 11.397-31.122 26.3-.337 2.122.744 4.894 3.358 4.894Z"
|
||||||
|
clip-rule="evenodd" />
|
||||||
|
<path class="tw-fill-art-accent" fill-rule="evenodd"
|
||||||
|
d="M77.983 21.027a1.2 1.2 0 0 1-1.2-1.2v-.6a1.2 1.2 0 0 1 2.4 0v.6a1.2 1.2 0 0 1-1.2 1.2ZM83.382 21.027a1.2 1.2 0 0 1-1.2-1.2v-.497a1.2 1.2 0 1 1 2.4 0v.498a1.2 1.2 0 0 1-1.2 1.2ZM88.78 21.027a1.2 1.2 0 0 1-1.2-1.2v-.497a1.2 1.2 0 1 1 2.4 0v.498a1.2 1.2 0 0 1-1.2 1.2Z"
|
||||||
|
clip-rule="evenodd" />
|
||||||
|
<path class="tw-fill-art-primary" fill-rule="evenodd" d="M95.083 24.027H0v-1.2h95.083v1.2Z"
|
||||||
|
clip-rule="evenodd" />
|
||||||
|
<g clip-path="url(#a)">
|
||||||
|
<path class="tw-fill-art-accent"
|
||||||
|
d="M32.727 93.11a16.908 16.908 0 0 1-9.477-2.91 17.228 17.228 0 0 1-6.284-7.752 17.467 17.467 0 0 1-.97-9.98 17.343 17.343 0 0 1 4.669-8.843 17.002 17.002 0 0 1 8.735-4.727 16.867 16.867 0 0 1 9.856.982 17.113 17.113 0 0 1 7.656 6.362 17.419 17.419 0 0 1 2.875 9.596 17.4 17.4 0 0 1-5.003 12.208 16.977 16.977 0 0 1-12.057 5.065Zm0-32.245c-2.924 0-5.784.877-8.216 2.523a14.932 14.932 0 0 0-5.447 6.72 15.148 15.148 0 0 0-.84 8.652 15.028 15.028 0 0 0 4.047 7.667 14.729 14.729 0 0 0 7.572 4.098c2.87.578 5.842.281 8.545-.851a14.827 14.827 0 0 0 6.637-5.515 15.11 15.11 0 0 0 2.493-8.319 15.087 15.087 0 0 0-4.336-10.583 14.714 14.714 0 0 0-10.453-4.39l-.002-.002Zm8.82 14.168h-6.9a1.105 1.105 0 0 1-.793-.333 1.149 1.149 0 0 1-.328-.802v-6.99a.81.81 0 0 0-.233-.568.793.793 0 0 0-1.357.569v6.985a1.144 1.144 0 0 1-.328.802 1.115 1.115 0 0 1-.793.332h-6.907a.788.788 0 0 0-.562.237.812.812 0 0 0 0 1.139.79.79 0 0 0 .562.235h6.899c.296 0 .582.12.791.333.21.212.329.5.329.8v6.99c0 .213.084.418.232.57a.788.788 0 0 0 1.125 0 .809.809 0 0 0 .232-.57v-6.98c0-.301.119-.59.329-.802.21-.212.494-.332.79-.332h6.906a.795.795 0 0 0 .795-.806.81.81 0 0 0-.232-.569.791.791 0 0 0-.563-.236l.004-.004h.002Z" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
`;
|
|
@ -37,6 +37,14 @@ describe("DefaultRegistrationFinishService", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("getOrgNameFromOrgInvite()", () => {
|
||||||
|
it("returns null", async () => {
|
||||||
|
const result = await service.getOrgNameFromOrgInvite();
|
||||||
|
|
||||||
|
expect(result).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("finishRegistration()", () => {
|
describe("finishRegistration()", () => {
|
||||||
let email: string;
|
let email: string;
|
||||||
let emailVerificationToken: string;
|
let emailVerificationToken: string;
|
||||||
|
|
|
@ -15,6 +15,10 @@ export class DefaultRegistrationFinishService implements RegistrationFinishServi
|
||||||
protected accountApiService: AccountApiService,
|
protected accountApiService: AccountApiService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
getOrgNameFromOrgInvite(): Promise<string | null> {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
getMasterPasswordPolicyOptsFromOrgInvite(): Promise<MasterPasswordPolicyOptions | null> {
|
getMasterPasswordPolicyOptsFromOrgInvite(): Promise<MasterPasswordPolicyOptions | null> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { CommonModule } from "@angular/common";
|
import { CommonModule } from "@angular/common";
|
||||||
import { Component, OnDestroy, OnInit } from "@angular/core";
|
import { Component, OnDestroy, OnInit } from "@angular/core";
|
||||||
import { ActivatedRoute, Params, Router, RouterModule } from "@angular/router";
|
import { ActivatedRoute, Params, Router, RouterModule } from "@angular/router";
|
||||||
import { EMPTY, Subject, from, switchMap, takeUntil, tap } from "rxjs";
|
import { Subject, firstValueFrom } from "rxjs";
|
||||||
|
|
||||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||||
import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options";
|
import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options";
|
||||||
|
@ -15,6 +15,7 @@ import { ValidationService } from "@bitwarden/common/platform/abstractions/valid
|
||||||
import { ToastService } from "@bitwarden/components";
|
import { ToastService } from "@bitwarden/components";
|
||||||
|
|
||||||
import { LoginStrategyServiceAbstraction, PasswordLoginCredentials } from "../../../common";
|
import { LoginStrategyServiceAbstraction, PasswordLoginCredentials } from "../../../common";
|
||||||
|
import { AnonLayoutWrapperDataService } from "../../anon-layout/anon-layout-wrapper-data.service";
|
||||||
import { InputPasswordComponent } from "../../input-password/input-password.component";
|
import { InputPasswordComponent } from "../../input-password/input-password.component";
|
||||||
import { PasswordInputResult } from "../../input-password/password-input-result";
|
import { PasswordInputResult } from "../../input-password/password-input-result";
|
||||||
|
|
||||||
|
@ -60,55 +61,72 @@ export class RegistrationFinishComponent implements OnInit, OnDestroy {
|
||||||
private accountApiService: AccountApiService,
|
private accountApiService: AccountApiService,
|
||||||
private loginStrategyService: LoginStrategyServiceAbstraction,
|
private loginStrategyService: LoginStrategyServiceAbstraction,
|
||||||
private logService: LogService,
|
private logService: LogService,
|
||||||
|
private anonLayoutWrapperDataService: AnonLayoutWrapperDataService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
this.listenForQueryParamChanges();
|
const qParams = await firstValueFrom(this.activatedRoute.queryParams);
|
||||||
this.masterPasswordPolicyOptions =
|
this.handleQueryParams(qParams);
|
||||||
await this.registrationFinishService.getMasterPasswordPolicyOptsFromOrgInvite();
|
|
||||||
|
if (
|
||||||
|
qParams.fromEmail &&
|
||||||
|
qParams.fromEmail === "true" &&
|
||||||
|
this.email &&
|
||||||
|
this.emailVerificationToken
|
||||||
|
) {
|
||||||
|
await this.initEmailVerificationFlow();
|
||||||
|
} else {
|
||||||
|
// Org Invite flow OR registration with email verification disabled Flow
|
||||||
|
const orgInviteFlow = await this.initOrgInviteFlowIfPresent();
|
||||||
|
|
||||||
|
if (!orgInviteFlow) {
|
||||||
|
this.initRegistrationWithEmailVerificationDisabledFlow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.loading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private listenForQueryParamChanges() {
|
private handleQueryParams(qParams: Params) {
|
||||||
this.activatedRoute.queryParams
|
if (qParams.email != null && qParams.email.indexOf("@") > -1) {
|
||||||
.pipe(
|
this.email = qParams.email;
|
||||||
tap((qParams: Params) => {
|
}
|
||||||
if (qParams.email != null && qParams.email.indexOf("@") > -1) {
|
|
||||||
this.email = qParams.email;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (qParams.token != null) {
|
if (qParams.token != null) {
|
||||||
this.emailVerificationToken = qParams.token;
|
this.emailVerificationToken = qParams.token;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qParams.orgSponsoredFreeFamilyPlanToken != null) {
|
if (qParams.orgSponsoredFreeFamilyPlanToken != null) {
|
||||||
this.orgSponsoredFreeFamilyPlanToken = qParams.orgSponsoredFreeFamilyPlanToken;
|
this.orgSponsoredFreeFamilyPlanToken = qParams.orgSponsoredFreeFamilyPlanToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qParams.acceptEmergencyAccessInviteToken != null && qParams.emergencyAccessId) {
|
if (qParams.acceptEmergencyAccessInviteToken != null && qParams.emergencyAccessId) {
|
||||||
this.acceptEmergencyAccessInviteToken = qParams.acceptEmergencyAccessInviteToken;
|
this.acceptEmergencyAccessInviteToken = qParams.acceptEmergencyAccessInviteToken;
|
||||||
this.emergencyAccessId = qParams.emergencyAccessId;
|
this.emergencyAccessId = qParams.emergencyAccessId;
|
||||||
}
|
}
|
||||||
}),
|
}
|
||||||
switchMap((qParams: Params) => {
|
|
||||||
if (
|
|
||||||
qParams.fromEmail &&
|
|
||||||
qParams.fromEmail === "true" &&
|
|
||||||
this.email &&
|
|
||||||
this.emailVerificationToken
|
|
||||||
) {
|
|
||||||
return from(
|
|
||||||
this.registerVerificationEmailClicked(this.email, this.emailVerificationToken),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
// org invite flow
|
|
||||||
this.loading = false;
|
|
||||||
return EMPTY;
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
|
|
||||||
takeUntil(this.destroy$),
|
private async initOrgInviteFlowIfPresent(): Promise<boolean> {
|
||||||
)
|
this.masterPasswordPolicyOptions =
|
||||||
.subscribe();
|
await this.registrationFinishService.getMasterPasswordPolicyOptsFromOrgInvite();
|
||||||
|
|
||||||
|
const orgName = await this.registrationFinishService.getOrgNameFromOrgInvite();
|
||||||
|
if (orgName) {
|
||||||
|
// Org invite exists
|
||||||
|
// Set the page title and subtitle appropriately
|
||||||
|
this.anonLayoutWrapperDataService.setAnonLayoutWrapperData({
|
||||||
|
pageTitle: {
|
||||||
|
key: "joinOrganizationName",
|
||||||
|
placeholders: [orgName],
|
||||||
|
},
|
||||||
|
pageSubtitle: {
|
||||||
|
key: "finishJoiningThisOrganizationBySettingAMasterPassword",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
async handlePasswordFormSubmit(passwordInputResult: PasswordInputResult) {
|
async handlePasswordFormSubmit(passwordInputResult: PasswordInputResult) {
|
||||||
|
@ -162,9 +180,24 @@ export class RegistrationFinishComponent implements OnInit, OnDestroy {
|
||||||
this.submitting = false;
|
this.submitting = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private setDefaultPageTitleAndSubtitle() {
|
||||||
|
this.anonLayoutWrapperDataService.setAnonLayoutWrapperData({
|
||||||
|
pageTitle: {
|
||||||
|
key: "setAStrongPassword",
|
||||||
|
},
|
||||||
|
pageSubtitle: {
|
||||||
|
key: "finishCreatingYourAccountBySettingAPassword",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async initEmailVerificationFlow() {
|
||||||
|
this.setDefaultPageTitleAndSubtitle();
|
||||||
|
await this.registerVerificationEmailClicked(this.email, this.emailVerificationToken);
|
||||||
|
}
|
||||||
|
|
||||||
private async registerVerificationEmailClicked(email: string, emailVerificationToken: string) {
|
private async registerVerificationEmailClicked(email: string, emailVerificationToken: string) {
|
||||||
const request = new RegisterVerificationEmailClickedRequest(email, emailVerificationToken);
|
const request = new RegisterVerificationEmailClickedRequest(email, emailVerificationToken);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await this.accountApiService.registerVerificationEmailClicked(request);
|
const result = await this.accountApiService.registerVerificationEmailClicked(request);
|
||||||
|
|
||||||
|
@ -174,11 +207,9 @@ export class RegistrationFinishComponent implements OnInit, OnDestroy {
|
||||||
message: this.i18nService.t("emailVerifiedV2"),
|
message: this.i18nService.t("emailVerifiedV2"),
|
||||||
variant: "success",
|
variant: "success",
|
||||||
});
|
});
|
||||||
this.loading = false;
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
await this.handleRegisterVerificationEmailClickedError(e);
|
await this.handleRegisterVerificationEmailClickedError(e);
|
||||||
this.loading = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,6 +235,10 @@ export class RegistrationFinishComponent implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private initRegistrationWithEmailVerificationDisabledFlow() {
|
||||||
|
this.setDefaultPageTitleAndSubtitle();
|
||||||
|
}
|
||||||
|
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
this.destroy$.next();
|
this.destroy$.next();
|
||||||
this.destroy$.complete();
|
this.destroy$.complete();
|
||||||
|
|
|
@ -3,6 +3,13 @@ import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/mod
|
||||||
import { PasswordInputResult } from "../../input-password/password-input-result";
|
import { PasswordInputResult } from "../../input-password/password-input-result";
|
||||||
|
|
||||||
export abstract class RegistrationFinishService {
|
export abstract class RegistrationFinishService {
|
||||||
|
/**
|
||||||
|
* Retrieves the organization name from an organization invite if it exists.
|
||||||
|
* Organization invites can currently only be accepted on the web.
|
||||||
|
* @returns a promise which resolves to the organization name string or null if no invite exists.
|
||||||
|
*/
|
||||||
|
abstract getOrgNameFromOrgInvite(): Promise<string | null>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the master password policy options from an organization invite if it exits.
|
* Gets the master password policy options from an organization invite if it exits.
|
||||||
* Organization invites can currently only be accepted on the web.
|
* Organization invites can currently only be accepted on the web.
|
||||||
|
@ -18,7 +25,7 @@ export abstract class RegistrationFinishService {
|
||||||
* @param orgSponsoredFreeFamilyPlanToken The optional org sponsored free family plan token.
|
* @param orgSponsoredFreeFamilyPlanToken The optional org sponsored free family plan token.
|
||||||
* @param acceptEmergencyAccessInviteToken The optional accept emergency access invite token.
|
* @param acceptEmergencyAccessInviteToken The optional accept emergency access invite token.
|
||||||
* @param emergencyAccessId The optional emergency access id which is required to validate the emergency access invite token.
|
* @param emergencyAccessId The optional emergency access id which is required to validate the emergency access invite token.
|
||||||
* Returns a promise which resolves to the captcha bypass token string upon a successful account creation.
|
* @returns a promise which resolves to the captcha bypass token string upon a successful account creation.
|
||||||
*/
|
*/
|
||||||
abstract finishRegistration(
|
abstract finishRegistration(
|
||||||
email: string,
|
email: string,
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
<div class="tw-flex tw-flex-col tw-items-center tw-justify-center">
|
<div class="tw-flex tw-flex-col tw-items-center tw-justify-center">
|
||||||
<bit-icon [icon]="Icons.RegistrationExpiredLinkIcon" class="tw-mb-6"></bit-icon>
|
|
||||||
|
|
||||||
<p
|
<p
|
||||||
bitTypography="body1"
|
bitTypography="body1"
|
||||||
class="tw-text-center tw-mb-3 tw-text-main"
|
class="tw-text-center tw-mb-3 tw-text-main"
|
||||||
|
|
|
@ -79,19 +79,6 @@
|
||||||
|
|
||||||
<ng-container *ngIf="state === RegistrationStartState.CHECK_EMAIL">
|
<ng-container *ngIf="state === RegistrationStartState.CHECK_EMAIL">
|
||||||
<div class="tw-flex tw-flex-col tw-items-center tw-justify-center">
|
<div class="tw-flex tw-flex-col tw-items-center tw-justify-center">
|
||||||
<bit-icon [icon]="Icons.RegistrationCheckEmailIcon" class="tw-mb-6"></bit-icon>
|
|
||||||
|
|
||||||
<h2
|
|
||||||
bitTypography="h2"
|
|
||||||
id="check_your_email_heading"
|
|
||||||
class="tw-font-bold tw-mb-3 tw-text-main"
|
|
||||||
tabindex="0"
|
|
||||||
aria-describedby="follow_the_link_body"
|
|
||||||
appAutofocus
|
|
||||||
>
|
|
||||||
{{ "checkYourEmail" | i18n }}
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<p bitTypography="body1" class="tw-text-center tw-mb-3 tw-text-main" id="follow_the_link_body">
|
<p bitTypography="body1" class="tw-text-center tw-mb-3 tw-text-main" id="follow_the_link_body">
|
||||||
{{ "followTheLinkInTheEmailSentTo" | i18n }}
|
{{ "followTheLinkInTheEmailSentTo" | i18n }}
|
||||||
<span class="tw-font-bold">{{ email.value }}</span>
|
<span class="tw-font-bold">{{ email.value }}</span>
|
||||||
|
|
|
@ -19,6 +19,8 @@ import {
|
||||||
} from "@bitwarden/components";
|
} from "@bitwarden/components";
|
||||||
|
|
||||||
import { LoginEmailService } from "../../../common";
|
import { LoginEmailService } from "../../../common";
|
||||||
|
import { AnonLayoutWrapperDataService } from "../../anon-layout/anon-layout-wrapper-data.service";
|
||||||
|
import { RegistrationUserAddIcon } from "../../icons";
|
||||||
import { RegistrationCheckEmailIcon } from "../../icons/registration-check-email.icon";
|
import { RegistrationCheckEmailIcon } from "../../icons/registration-check-email.icon";
|
||||||
import { RegistrationEnvSelectorComponent } from "../registration-env-selector/registration-env-selector.component";
|
import { RegistrationEnvSelectorComponent } from "../registration-env-selector/registration-env-selector.component";
|
||||||
|
|
||||||
|
@ -55,7 +57,6 @@ export class RegistrationStartComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
state: RegistrationStartState = RegistrationStartState.USER_DATA_ENTRY;
|
state: RegistrationStartState = RegistrationStartState.USER_DATA_ENTRY;
|
||||||
RegistrationStartState = RegistrationStartState;
|
RegistrationStartState = RegistrationStartState;
|
||||||
readonly Icons = { RegistrationCheckEmailIcon };
|
|
||||||
|
|
||||||
isSelfHost = false;
|
isSelfHost = false;
|
||||||
|
|
||||||
|
@ -90,6 +91,7 @@ export class RegistrationStartComponent implements OnInit, OnDestroy {
|
||||||
private accountApiService: AccountApiService,
|
private accountApiService: AccountApiService,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private loginEmailService: LoginEmailService,
|
private loginEmailService: LoginEmailService,
|
||||||
|
private anonLayoutWrapperDataService: AnonLayoutWrapperDataService,
|
||||||
) {
|
) {
|
||||||
this.isSelfHost = platformUtilsService.isSelfHost();
|
this.isSelfHost = platformUtilsService.isSelfHost();
|
||||||
}
|
}
|
||||||
|
@ -159,6 +161,12 @@ export class RegistrationStartComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
// Result is null, so email verification is required
|
// Result is null, so email verification is required
|
||||||
this.state = RegistrationStartState.CHECK_EMAIL;
|
this.state = RegistrationStartState.CHECK_EMAIL;
|
||||||
|
this.anonLayoutWrapperDataService.setAnonLayoutWrapperData({
|
||||||
|
pageTitle: {
|
||||||
|
key: "checkYourEmail",
|
||||||
|
},
|
||||||
|
pageIcon: RegistrationCheckEmailIcon,
|
||||||
|
});
|
||||||
this.registrationStartStateChange.emit(this.state);
|
this.registrationStartStateChange.emit(this.state);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -182,6 +190,12 @@ export class RegistrationStartComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
goBack() {
|
goBack() {
|
||||||
this.state = RegistrationStartState.USER_DATA_ENTRY;
|
this.state = RegistrationStartState.USER_DATA_ENTRY;
|
||||||
|
this.anonLayoutWrapperDataService.setAnonLayoutWrapperData({
|
||||||
|
pageIcon: RegistrationUserAddIcon,
|
||||||
|
pageTitle: {
|
||||||
|
key: "createAccount",
|
||||||
|
},
|
||||||
|
});
|
||||||
this.registrationStartStateChange.emit(this.state);
|
this.registrationStartStateChange.emit(this.state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,8 @@ import {
|
||||||
// eslint-disable-next-line import/no-restricted-paths
|
// eslint-disable-next-line import/no-restricted-paths
|
||||||
import { PreloadedEnglishI18nModule } from "../../../../../../apps/web/src/app/core/tests";
|
import { PreloadedEnglishI18nModule } from "../../../../../../apps/web/src/app/core/tests";
|
||||||
import { LoginEmailService } from "../../../common";
|
import { LoginEmailService } from "../../../common";
|
||||||
|
import { AnonLayoutWrapperDataService } from "../../anon-layout/anon-layout-wrapper-data.service";
|
||||||
|
import { AnonLayoutWrapperData } from "../../anon-layout/anon-layout-wrapper.component";
|
||||||
|
|
||||||
import { RegistrationStartComponent } from "./registration-start.component";
|
import { RegistrationStartComponent } from "./registration-start.component";
|
||||||
|
|
||||||
|
@ -96,6 +98,14 @@ const decorators = (options: {
|
||||||
loginEmail$: new BehaviorSubject<string | null>(options.initialLoginEmail || null),
|
loginEmail$: new BehaviorSubject<string | null>(options.initialLoginEmail || null),
|
||||||
} as Partial<LoginEmailService>,
|
} as Partial<LoginEmailService>,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
provide: AnonLayoutWrapperDataService,
|
||||||
|
useValue: {
|
||||||
|
setAnonLayoutWrapperData: (data: AnonLayoutWrapperData) => {
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
} as Partial<AnonLayoutWrapperDataService>,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
provide: ToastService,
|
provide: ToastService,
|
||||||
useValue: {
|
useValue: {
|
||||||
|
|
|
@ -11,9 +11,11 @@ import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"
|
||||||
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
||||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||||
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
||||||
|
import { PBKDF2KdfConfig } from "@bitwarden/common/auth/models/domain/kdf-config";
|
||||||
import { TokenTwoFactorRequest } from "@bitwarden/common/auth/models/request/identity-token/token-two-factor.request";
|
import { TokenTwoFactorRequest } from "@bitwarden/common/auth/models/request/identity-token/token-two-factor.request";
|
||||||
import { IdentityTokenResponse } from "@bitwarden/common/auth/models/response/identity-token.response";
|
import { IdentityTokenResponse } from "@bitwarden/common/auth/models/response/identity-token.response";
|
||||||
import { IdentityTwoFactorResponse } from "@bitwarden/common/auth/models/response/identity-two-factor.response";
|
import { IdentityTwoFactorResponse } from "@bitwarden/common/auth/models/response/identity-two-factor.response";
|
||||||
|
import { PreloginResponse } from "@bitwarden/common/auth/models/response/prelogin.response";
|
||||||
import { FakeMasterPasswordService } from "@bitwarden/common/auth/services/master-password/fake-master-password.service";
|
import { FakeMasterPasswordService } from "@bitwarden/common/auth/services/master-password/fake-master-password.service";
|
||||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||||
import { VaultTimeoutAction } from "@bitwarden/common/enums/vault-timeout-action.enum";
|
import { VaultTimeoutAction } from "@bitwarden/common/enums/vault-timeout-action.enum";
|
||||||
|
@ -159,6 +161,9 @@ describe("LoginStrategyService", () => {
|
||||||
new IdentityTokenResponse({
|
new IdentityTokenResponse({
|
||||||
ForcePasswordReset: false,
|
ForcePasswordReset: false,
|
||||||
Kdf: KdfType.Argon2id,
|
Kdf: KdfType.Argon2id,
|
||||||
|
KdfIterations: 2,
|
||||||
|
KdfMemory: 16,
|
||||||
|
KdfParallelism: 1,
|
||||||
Key: "KEY",
|
Key: "KEY",
|
||||||
PrivateKey: "PRIVATE_KEY",
|
PrivateKey: "PRIVATE_KEY",
|
||||||
ResetMasterPassword: false,
|
ResetMasterPassword: false,
|
||||||
|
@ -169,6 +174,15 @@ describe("LoginStrategyService", () => {
|
||||||
token_type: "Bearer",
|
token_type: "Bearer",
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
apiService.postPrelogin.mockResolvedValue(
|
||||||
|
new PreloginResponse({
|
||||||
|
Kdf: KdfType.Argon2id,
|
||||||
|
KdfIterations: 2,
|
||||||
|
KdfMemory: 16,
|
||||||
|
KdfParallelism: 1,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
tokenService.decodeAccessToken.calledWith("ACCESS_TOKEN").mockResolvedValue({
|
tokenService.decodeAccessToken.calledWith("ACCESS_TOKEN").mockResolvedValue({
|
||||||
sub: "USER_ID",
|
sub: "USER_ID",
|
||||||
name: "NAME",
|
name: "NAME",
|
||||||
|
@ -194,6 +208,15 @@ describe("LoginStrategyService", () => {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
apiService.postPrelogin.mockResolvedValue(
|
||||||
|
new PreloginResponse({
|
||||||
|
Kdf: KdfType.Argon2id,
|
||||||
|
KdfIterations: 2,
|
||||||
|
KdfMemory: 16,
|
||||||
|
KdfParallelism: 1,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
await sut.logIn(credentials);
|
await sut.logIn(credentials);
|
||||||
|
|
||||||
const twoFactorToken = new TokenTwoFactorRequest(
|
const twoFactorToken = new TokenTwoFactorRequest(
|
||||||
|
@ -205,6 +228,9 @@ describe("LoginStrategyService", () => {
|
||||||
new IdentityTokenResponse({
|
new IdentityTokenResponse({
|
||||||
ForcePasswordReset: false,
|
ForcePasswordReset: false,
|
||||||
Kdf: KdfType.Argon2id,
|
Kdf: KdfType.Argon2id,
|
||||||
|
KdfIterations: 2,
|
||||||
|
KdfMemory: 16,
|
||||||
|
KdfParallelism: 1,
|
||||||
Key: "KEY",
|
Key: "KEY",
|
||||||
PrivateKey: "PRIVATE_KEY",
|
PrivateKey: "PRIVATE_KEY",
|
||||||
ResetMasterPassword: false,
|
ResetMasterPassword: false,
|
||||||
|
@ -241,6 +267,15 @@ describe("LoginStrategyService", () => {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
apiService.postPrelogin.mockResolvedValue(
|
||||||
|
new PreloginResponse({
|
||||||
|
Kdf: KdfType.Argon2id,
|
||||||
|
KdfIterations: 2,
|
||||||
|
KdfMemory: 16,
|
||||||
|
KdfParallelism: 1,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
await sut.logIn(credentials);
|
await sut.logIn(credentials);
|
||||||
|
|
||||||
loginStrategyCacheExpirationState.stateSubject.next(new Date(Date.now() - 1000 * 60 * 5));
|
loginStrategyCacheExpirationState.stateSubject.next(new Date(Date.now() - 1000 * 60 * 5));
|
||||||
|
@ -253,4 +288,40 @@ describe("LoginStrategyService", () => {
|
||||||
|
|
||||||
await expect(sut.logInTwoFactor(twoFactorToken, "CAPTCHA")).rejects.toThrow();
|
await expect(sut.logInTwoFactor(twoFactorToken, "CAPTCHA")).rejects.toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("throw error on too low kdf config", async () => {
|
||||||
|
const credentials = new PasswordLoginCredentials("EMAIL", "MASTER_PASSWORD");
|
||||||
|
apiService.postIdentityToken.mockResolvedValue(
|
||||||
|
new IdentityTokenResponse({
|
||||||
|
ForcePasswordReset: false,
|
||||||
|
Kdf: KdfType.PBKDF2_SHA256,
|
||||||
|
KdfIterations: PBKDF2KdfConfig.PRELOGIN_ITERATIONS.min - 1,
|
||||||
|
Key: "KEY",
|
||||||
|
PrivateKey: "PRIVATE_KEY",
|
||||||
|
ResetMasterPassword: false,
|
||||||
|
access_token: "ACCESS_TOKEN",
|
||||||
|
expires_in: 3600,
|
||||||
|
refresh_token: "REFRESH_TOKEN",
|
||||||
|
scope: "api offline_access",
|
||||||
|
token_type: "Bearer",
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
apiService.postPrelogin.mockResolvedValue(
|
||||||
|
new PreloginResponse({
|
||||||
|
Kdf: KdfType.PBKDF2_SHA256,
|
||||||
|
KdfIterations: PBKDF2KdfConfig.PRELOGIN_ITERATIONS.min - 1,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
tokenService.decodeAccessToken.calledWith("ACCESS_TOKEN").mockResolvedValue({
|
||||||
|
sub: "USER_ID",
|
||||||
|
name: "NAME",
|
||||||
|
email: "EMAIL",
|
||||||
|
premium: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
await expect(sut.logIn(credentials)).rejects.toThrow(
|
||||||
|
`PBKDF2 iterations must be between ${PBKDF2KdfConfig.PRELOGIN_ITERATIONS.min} and ${PBKDF2KdfConfig.PRELOGIN_ITERATIONS.max}`,
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -264,6 +264,9 @@ export class LoginStrategyService implements LoginStrategyServiceAbstraction {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kdfConfig.validateKdfConfigForPrelogin();
|
||||||
|
|
||||||
return await this.cryptoService.makeMasterKey(masterPassword, email, kdfConfig);
|
return await this.cryptoService.makeMasterKey(masterPassword, email, kdfConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,9 +51,13 @@ describe("ORGANIZATIONS state", () => {
|
||||||
keyConnectorEnabled: false,
|
keyConnectorEnabled: false,
|
||||||
keyConnectorUrl: "kcu",
|
keyConnectorUrl: "kcu",
|
||||||
accessSecretsManager: false,
|
accessSecretsManager: false,
|
||||||
|
limitCollectionCreation: false,
|
||||||
|
limitCollectionDeletion: false,
|
||||||
|
// Deprecated: https://bitwarden.atlassian.net/browse/PM-10863
|
||||||
limitCollectionCreationDeletion: false,
|
limitCollectionCreationDeletion: false,
|
||||||
allowAdminAccessToAllCollectionItems: false,
|
allowAdminAccessToAllCollectionItems: false,
|
||||||
familySponsorshipLastSyncDate: new Date(),
|
familySponsorshipLastSyncDate: new Date(),
|
||||||
|
userIsManagedByOrganization: false,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const result = sut.deserializer(JSON.parse(JSON.stringify(expectedResult)));
|
const result = sut.deserializer(JSON.parse(JSON.stringify(expectedResult)));
|
||||||
|
|
|
@ -52,8 +52,12 @@ export class OrganizationData {
|
||||||
familySponsorshipValidUntil?: Date;
|
familySponsorshipValidUntil?: Date;
|
||||||
familySponsorshipToDelete?: boolean;
|
familySponsorshipToDelete?: boolean;
|
||||||
accessSecretsManager: boolean;
|
accessSecretsManager: boolean;
|
||||||
|
limitCollectionCreation: boolean;
|
||||||
|
limitCollectionDeletion: boolean;
|
||||||
|
// Deprecated: https://bitwarden.atlassian.net/browse/PM-10863
|
||||||
limitCollectionCreationDeletion: boolean;
|
limitCollectionCreationDeletion: boolean;
|
||||||
allowAdminAccessToAllCollectionItems: boolean;
|
allowAdminAccessToAllCollectionItems: boolean;
|
||||||
|
userIsManagedByOrganization: boolean;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
response?: ProfileOrganizationResponse,
|
response?: ProfileOrganizationResponse,
|
||||||
|
@ -110,8 +114,12 @@ export class OrganizationData {
|
||||||
this.familySponsorshipValidUntil = response.familySponsorshipValidUntil;
|
this.familySponsorshipValidUntil = response.familySponsorshipValidUntil;
|
||||||
this.familySponsorshipToDelete = response.familySponsorshipToDelete;
|
this.familySponsorshipToDelete = response.familySponsorshipToDelete;
|
||||||
this.accessSecretsManager = response.accessSecretsManager;
|
this.accessSecretsManager = response.accessSecretsManager;
|
||||||
|
this.limitCollectionCreation = response.limitCollectionCreation;
|
||||||
|
this.limitCollectionDeletion = response.limitCollectionDeletion;
|
||||||
|
// Deprecated: https://bitwarden.atlassian.net/browse/PM-10863
|
||||||
this.limitCollectionCreationDeletion = response.limitCollectionCreationDeletion;
|
this.limitCollectionCreationDeletion = response.limitCollectionCreationDeletion;
|
||||||
this.allowAdminAccessToAllCollectionItems = response.allowAdminAccessToAllCollectionItems;
|
this.allowAdminAccessToAllCollectionItems = response.allowAdminAccessToAllCollectionItems;
|
||||||
|
this.userIsManagedByOrganization = response.userIsManagedByOrganization;
|
||||||
|
|
||||||
this.isMember = options.isMember;
|
this.isMember = options.isMember;
|
||||||
this.isProviderUser = options.isProviderUser;
|
this.isProviderUser = options.isProviderUser;
|
||||||
|
|
|
@ -68,11 +68,21 @@ export class Organization {
|
||||||
/**
|
/**
|
||||||
* Refers to the ability for an organization to limit collection creation and deletion to owners and admins only
|
* Refers to the ability for an organization to limit collection creation and deletion to owners and admins only
|
||||||
*/
|
*/
|
||||||
|
limitCollectionCreation: boolean;
|
||||||
|
limitCollectionDeletion: boolean;
|
||||||
|
// Deprecated: https://bitwarden.atlassian.net/browse/PM-10863
|
||||||
limitCollectionCreationDeletion: boolean;
|
limitCollectionCreationDeletion: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Refers to the ability for an owner/admin to access all collection items, regardless of assigned collections
|
* Refers to the ability for an owner/admin to access all collection items, regardless of assigned collections
|
||||||
*/
|
*/
|
||||||
allowAdminAccessToAllCollectionItems: boolean;
|
allowAdminAccessToAllCollectionItems: boolean;
|
||||||
|
/**
|
||||||
|
* Indicates if this organization manages the user.
|
||||||
|
* A user is considered managed by an organization if their email domain
|
||||||
|
* matches one of the verified domains of that organization, and the user is a member of it.
|
||||||
|
*/
|
||||||
|
userIsManagedByOrganization: boolean;
|
||||||
|
|
||||||
constructor(obj?: OrganizationData) {
|
constructor(obj?: OrganizationData) {
|
||||||
if (obj == null) {
|
if (obj == null) {
|
||||||
|
@ -125,8 +135,12 @@ export class Organization {
|
||||||
this.familySponsorshipValidUntil = obj.familySponsorshipValidUntil;
|
this.familySponsorshipValidUntil = obj.familySponsorshipValidUntil;
|
||||||
this.familySponsorshipToDelete = obj.familySponsorshipToDelete;
|
this.familySponsorshipToDelete = obj.familySponsorshipToDelete;
|
||||||
this.accessSecretsManager = obj.accessSecretsManager;
|
this.accessSecretsManager = obj.accessSecretsManager;
|
||||||
|
this.limitCollectionCreation = obj.limitCollectionCreation;
|
||||||
|
this.limitCollectionDeletion = obj.limitCollectionDeletion;
|
||||||
|
// Deprecated: https://bitwarden.atlassian.net/browse/PM-10863
|
||||||
this.limitCollectionCreationDeletion = obj.limitCollectionCreationDeletion;
|
this.limitCollectionCreationDeletion = obj.limitCollectionCreationDeletion;
|
||||||
this.allowAdminAccessToAllCollectionItems = obj.allowAdminAccessToAllCollectionItems;
|
this.allowAdminAccessToAllCollectionItems = obj.allowAdminAccessToAllCollectionItems;
|
||||||
|
this.userIsManagedByOrganization = obj.userIsManagedByOrganization;
|
||||||
}
|
}
|
||||||
|
|
||||||
get canAccess() {
|
get canAccess() {
|
||||||
|
@ -163,9 +177,7 @@ export class Organization {
|
||||||
}
|
}
|
||||||
|
|
||||||
get canCreateNewCollections() {
|
get canCreateNewCollections() {
|
||||||
return (
|
return !this.limitCollectionCreation || this.isAdmin || this.permissions.createNewCollections;
|
||||||
!this.limitCollectionCreationDeletion || this.isAdmin || this.permissions.createNewCollections
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get canEditAnyCollection() {
|
get canEditAnyCollection() {
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
export class OrganizationCollectionManagementUpdateRequest {
|
export class OrganizationCollectionManagementUpdateRequest {
|
||||||
|
limitCollectionCreation: boolean;
|
||||||
|
limitCollectionDeletion: boolean;
|
||||||
|
// Deprecated: https://bitwarden.atlassian.net/browse/PM-10863
|
||||||
limitCreateDeleteOwnerAdmin: boolean;
|
limitCreateDeleteOwnerAdmin: boolean;
|
||||||
allowAdminAccessToAllCollectionItems: boolean;
|
allowAdminAccessToAllCollectionItems: boolean;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,9 @@ export class OrganizationResponse extends BaseResponse {
|
||||||
smServiceAccounts?: number;
|
smServiceAccounts?: number;
|
||||||
maxAutoscaleSmSeats?: number;
|
maxAutoscaleSmSeats?: number;
|
||||||
maxAutoscaleSmServiceAccounts?: number;
|
maxAutoscaleSmServiceAccounts?: number;
|
||||||
|
limitCollectionCreation: boolean;
|
||||||
|
limitCollectionDeletion: boolean;
|
||||||
|
// Deprecated: https://bitwarden.atlassian.net/browse/PM-10863
|
||||||
limitCollectionCreationDeletion: boolean;
|
limitCollectionCreationDeletion: boolean;
|
||||||
allowAdminAccessToAllCollectionItems: boolean;
|
allowAdminAccessToAllCollectionItems: boolean;
|
||||||
|
|
||||||
|
@ -69,6 +72,9 @@ export class OrganizationResponse extends BaseResponse {
|
||||||
this.smServiceAccounts = this.getResponseProperty("SmServiceAccounts");
|
this.smServiceAccounts = this.getResponseProperty("SmServiceAccounts");
|
||||||
this.maxAutoscaleSmSeats = this.getResponseProperty("MaxAutoscaleSmSeats");
|
this.maxAutoscaleSmSeats = this.getResponseProperty("MaxAutoscaleSmSeats");
|
||||||
this.maxAutoscaleSmServiceAccounts = this.getResponseProperty("MaxAutoscaleSmServiceAccounts");
|
this.maxAutoscaleSmServiceAccounts = this.getResponseProperty("MaxAutoscaleSmServiceAccounts");
|
||||||
|
this.limitCollectionCreation = this.getResponseProperty("LimitCollectionCreation");
|
||||||
|
this.limitCollectionDeletion = this.getResponseProperty("LimitCollectionDeletion");
|
||||||
|
// Deprecated: https://bitwarden.atlassian.net/browse/PM-10863
|
||||||
this.limitCollectionCreationDeletion = this.getResponseProperty(
|
this.limitCollectionCreationDeletion = this.getResponseProperty(
|
||||||
"LimitCollectionCreationDeletion",
|
"LimitCollectionCreationDeletion",
|
||||||
);
|
);
|
||||||
|
|
|
@ -49,8 +49,12 @@ export class ProfileOrganizationResponse extends BaseResponse {
|
||||||
familySponsorshipValidUntil?: Date;
|
familySponsorshipValidUntil?: Date;
|
||||||
familySponsorshipToDelete?: boolean;
|
familySponsorshipToDelete?: boolean;
|
||||||
accessSecretsManager: boolean;
|
accessSecretsManager: boolean;
|
||||||
|
limitCollectionCreation: boolean;
|
||||||
|
limitCollectionDeletion: boolean;
|
||||||
|
// Deprecated: https://bitwarden.atlassian.net/browse/PM-10863
|
||||||
limitCollectionCreationDeletion: boolean;
|
limitCollectionCreationDeletion: boolean;
|
||||||
allowAdminAccessToAllCollectionItems: boolean;
|
allowAdminAccessToAllCollectionItems: boolean;
|
||||||
|
userIsManagedByOrganization: boolean;
|
||||||
|
|
||||||
constructor(response: any) {
|
constructor(response: any) {
|
||||||
super(response);
|
super(response);
|
||||||
|
@ -109,11 +113,15 @@ export class ProfileOrganizationResponse extends BaseResponse {
|
||||||
}
|
}
|
||||||
this.familySponsorshipToDelete = this.getResponseProperty("FamilySponsorshipToDelete");
|
this.familySponsorshipToDelete = this.getResponseProperty("FamilySponsorshipToDelete");
|
||||||
this.accessSecretsManager = this.getResponseProperty("AccessSecretsManager");
|
this.accessSecretsManager = this.getResponseProperty("AccessSecretsManager");
|
||||||
|
this.limitCollectionCreation = this.getResponseProperty("LimitCollectionCreation");
|
||||||
|
this.limitCollectionDeletion = this.getResponseProperty("LimitCollectionDeletion");
|
||||||
|
// Deprecated: https://bitwarden.atlassian.net/browse/PM-10863
|
||||||
this.limitCollectionCreationDeletion = this.getResponseProperty(
|
this.limitCollectionCreationDeletion = this.getResponseProperty(
|
||||||
"LimitCollectionCreationDeletion",
|
"LimitCollectionCreationDeletion",
|
||||||
);
|
);
|
||||||
this.allowAdminAccessToAllCollectionItems = this.getResponseProperty(
|
this.allowAdminAccessToAllCollectionItems = this.getResponseProperty(
|
||||||
"AllowAdminAccessToAllCollectionItems",
|
"AllowAdminAccessToAllCollectionItems",
|
||||||
);
|
);
|
||||||
|
this.userIsManagedByOrganization = this.getResponseProperty("UserIsManagedByOrganization");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ export type KdfConfig = PBKDF2KdfConfig | Argon2KdfConfig;
|
||||||
*/
|
*/
|
||||||
export class PBKDF2KdfConfig {
|
export class PBKDF2KdfConfig {
|
||||||
static ITERATIONS = new RangeWithDefault(600_000, 2_000_000, 600_000);
|
static ITERATIONS = new RangeWithDefault(600_000, 2_000_000, 600_000);
|
||||||
|
static PRELOGIN_ITERATIONS = new RangeWithDefault(5000, 2_000_000, 600_000);
|
||||||
kdfType: KdfType.PBKDF2_SHA256 = KdfType.PBKDF2_SHA256;
|
kdfType: KdfType.PBKDF2_SHA256 = KdfType.PBKDF2_SHA256;
|
||||||
iterations: number;
|
iterations: number;
|
||||||
|
|
||||||
|
@ -21,10 +22,10 @@ export class PBKDF2KdfConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates the PBKDF2 KDF configuration.
|
* Validates the PBKDF2 KDF configuration for updating the KDF config.
|
||||||
* A Valid PBKDF2 KDF configuration has KDF iterations between the 600_000 and 2_000_000.
|
* A Valid PBKDF2 KDF configuration has KDF iterations between the 600_000 and 2_000_000.
|
||||||
*/
|
*/
|
||||||
validateKdfConfig(): void {
|
validateKdfConfigForSetting(): void {
|
||||||
if (!PBKDF2KdfConfig.ITERATIONS.inRange(this.iterations)) {
|
if (!PBKDF2KdfConfig.ITERATIONS.inRange(this.iterations)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`PBKDF2 iterations must be between ${PBKDF2KdfConfig.ITERATIONS.min} and ${PBKDF2KdfConfig.ITERATIONS.max}`,
|
`PBKDF2 iterations must be between ${PBKDF2KdfConfig.ITERATIONS.min} and ${PBKDF2KdfConfig.ITERATIONS.max}`,
|
||||||
|
@ -32,6 +33,18 @@ export class PBKDF2KdfConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the PBKDF2 KDF configuration for pre-login.
|
||||||
|
* A Valid PBKDF2 KDF configuration has KDF iterations between the 5000 and 2_000_000.
|
||||||
|
*/
|
||||||
|
validateKdfConfigForPrelogin(): void {
|
||||||
|
if (!PBKDF2KdfConfig.PRELOGIN_ITERATIONS.inRange(this.iterations)) {
|
||||||
|
throw new Error(
|
||||||
|
`PBKDF2 iterations must be between ${PBKDF2KdfConfig.PRELOGIN_ITERATIONS.min} and ${PBKDF2KdfConfig.PRELOGIN_ITERATIONS.max}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static fromJSON(json: Jsonify<PBKDF2KdfConfig>): PBKDF2KdfConfig {
|
static fromJSON(json: Jsonify<PBKDF2KdfConfig>): PBKDF2KdfConfig {
|
||||||
return new PBKDF2KdfConfig(json.iterations);
|
return new PBKDF2KdfConfig(json.iterations);
|
||||||
}
|
}
|
||||||
|
@ -44,6 +57,11 @@ export class Argon2KdfConfig {
|
||||||
static MEMORY = new RangeWithDefault(16, 1024, 64);
|
static MEMORY = new RangeWithDefault(16, 1024, 64);
|
||||||
static PARALLELISM = new RangeWithDefault(1, 16, 4);
|
static PARALLELISM = new RangeWithDefault(1, 16, 4);
|
||||||
static ITERATIONS = new RangeWithDefault(2, 10, 3);
|
static ITERATIONS = new RangeWithDefault(2, 10, 3);
|
||||||
|
|
||||||
|
static PRELOGIN_MEMORY = Argon2KdfConfig.MEMORY;
|
||||||
|
static PRELOGIN_PARALLELISM = Argon2KdfConfig.PARALLELISM;
|
||||||
|
static PRELOGIN_ITERATIONS = Argon2KdfConfig.ITERATIONS;
|
||||||
|
|
||||||
kdfType: KdfType.Argon2id = KdfType.Argon2id;
|
kdfType: KdfType.Argon2id = KdfType.Argon2id;
|
||||||
iterations: number;
|
iterations: number;
|
||||||
memory: number;
|
memory: number;
|
||||||
|
@ -56,10 +74,10 @@ export class Argon2KdfConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates the Argon2 KDF configuration.
|
* Validates the Argon2 KDF configuration for updating the KDF config.
|
||||||
* A Valid Argon2 KDF configuration has iterations between 2 and 10, memory between 16mb and 1024mb, and parallelism between 1 and 16.
|
* A Valid Argon2 KDF configuration has iterations between 2 and 10, memory between 16mb and 1024mb, and parallelism between 1 and 16.
|
||||||
*/
|
*/
|
||||||
validateKdfConfig(): void {
|
validateKdfConfigForSetting(): void {
|
||||||
if (!Argon2KdfConfig.ITERATIONS.inRange(this.iterations)) {
|
if (!Argon2KdfConfig.ITERATIONS.inRange(this.iterations)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Argon2 iterations must be between ${Argon2KdfConfig.ITERATIONS.min} and ${Argon2KdfConfig.ITERATIONS.max}`,
|
`Argon2 iterations must be between ${Argon2KdfConfig.ITERATIONS.min} and ${Argon2KdfConfig.ITERATIONS.max}`,
|
||||||
|
@ -79,6 +97,29 @@ export class Argon2KdfConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the Argon2 KDF configuration for pre-login.
|
||||||
|
*/
|
||||||
|
validateKdfConfigForPrelogin(): void {
|
||||||
|
if (!Argon2KdfConfig.PRELOGIN_ITERATIONS.inRange(this.iterations)) {
|
||||||
|
throw new Error(
|
||||||
|
`Argon2 iterations must be between ${Argon2KdfConfig.PRELOGIN_ITERATIONS.min} and ${Argon2KdfConfig.PRELOGIN_ITERATIONS.max}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Argon2KdfConfig.PRELOGIN_MEMORY.inRange(this.memory)) {
|
||||||
|
throw new Error(
|
||||||
|
`Argon2 memory must be between ${Argon2KdfConfig.PRELOGIN_MEMORY.min}mb and ${Argon2KdfConfig.PRELOGIN_MEMORY.max}mb`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Argon2KdfConfig.PRELOGIN_PARALLELISM.inRange(this.parallelism)) {
|
||||||
|
throw new Error(
|
||||||
|
`Argon2 parallelism must be between ${Argon2KdfConfig.PRELOGIN_PARALLELISM.min} and ${Argon2KdfConfig.PRELOGIN_PARALLELISM.max}.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static fromJSON(json: Jsonify<Argon2KdfConfig>): Argon2KdfConfig {
|
static fromJSON(json: Jsonify<Argon2KdfConfig>): Argon2KdfConfig {
|
||||||
return new Argon2KdfConfig(json.iterations, json.memory, json.parallelism);
|
return new Argon2KdfConfig(json.iterations, json.memory, json.parallelism);
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,41 +58,120 @@ describe("KdfConfigService", () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it("validateKdfConfig(): should validate the PBKDF2 KDF config", () => {
|
it("validateKdfConfigForSetting(): should validate the PBKDF2 KDF config", () => {
|
||||||
const kdfConfig: PBKDF2KdfConfig = new PBKDF2KdfConfig(600_000);
|
const kdfConfig: PBKDF2KdfConfig = new PBKDF2KdfConfig(600_000);
|
||||||
expect(() => kdfConfig.validateKdfConfig()).not.toThrow();
|
expect(() => kdfConfig.validateKdfConfigForSetting()).not.toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("validateKdfConfig(): should validate the Argon2id KDF config", () => {
|
it("validateKdfConfigForSetting(): should validate the Argon2id KDF config", () => {
|
||||||
const kdfConfig: Argon2KdfConfig = new Argon2KdfConfig(3, 64, 4);
|
const kdfConfig: Argon2KdfConfig = new Argon2KdfConfig(3, 64, 4);
|
||||||
expect(() => kdfConfig.validateKdfConfig()).not.toThrow();
|
expect(() => kdfConfig.validateKdfConfigForSetting()).not.toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("validateKdfConfig(): should throw an error for invalid PBKDF2 iterations", () => {
|
it("validateKdfConfigForSetting(): should throw an error for invalid PBKDF2 iterations", () => {
|
||||||
const kdfConfig: PBKDF2KdfConfig = new PBKDF2KdfConfig(100);
|
const kdfConfig: PBKDF2KdfConfig = new PBKDF2KdfConfig(100000);
|
||||||
expect(() => kdfConfig.validateKdfConfig()).toThrow(
|
expect(() => kdfConfig.validateKdfConfigForSetting()).toThrow(
|
||||||
`PBKDF2 iterations must be between ${PBKDF2KdfConfig.ITERATIONS.min} and ${PBKDF2KdfConfig.ITERATIONS.max}`,
|
`PBKDF2 iterations must be between ${PBKDF2KdfConfig.ITERATIONS.min} and ${PBKDF2KdfConfig.ITERATIONS.max}`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("validateKdfConfig(): should throw an error for invalid Argon2 iterations", () => {
|
it("validateKdfConfigForSetting(): should throw an error for invalid Argon2 iterations", () => {
|
||||||
const kdfConfig: Argon2KdfConfig = new Argon2KdfConfig(11, 64, 4);
|
const kdfConfig: Argon2KdfConfig = new Argon2KdfConfig(11, 64, 4);
|
||||||
expect(() => kdfConfig.validateKdfConfig()).toThrow(
|
expect(() => kdfConfig.validateKdfConfigForSetting()).toThrow(
|
||||||
`Argon2 iterations must be between ${Argon2KdfConfig.ITERATIONS.min} and ${Argon2KdfConfig.ITERATIONS.max}`,
|
`Argon2 iterations must be between ${Argon2KdfConfig.ITERATIONS.min} and ${Argon2KdfConfig.ITERATIONS.max}`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("validateKdfConfig(): should throw an error for invalid Argon2 memory", () => {
|
it("validateKdfConfigForSetting(): should throw an error for invalid Argon2 memory", () => {
|
||||||
const kdfConfig: Argon2KdfConfig = new Argon2KdfConfig(3, 1025, 4);
|
const kdfConfig: Argon2KdfConfig = new Argon2KdfConfig(3, 1025, 4);
|
||||||
expect(() => kdfConfig.validateKdfConfig()).toThrow(
|
expect(() => kdfConfig.validateKdfConfigForSetting()).toThrow(
|
||||||
`Argon2 memory must be between ${Argon2KdfConfig.MEMORY.min}mb and ${Argon2KdfConfig.MEMORY.max}mb`,
|
`Argon2 memory must be between ${Argon2KdfConfig.MEMORY.min}mb and ${Argon2KdfConfig.MEMORY.max}mb`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("validateKdfConfig(): should throw an error for invalid Argon2 parallelism", () => {
|
it("validateKdfConfigForSetting(): should throw an error for invalid Argon2 parallelism", () => {
|
||||||
const kdfConfig: Argon2KdfConfig = new Argon2KdfConfig(3, 64, 17);
|
const kdfConfig: Argon2KdfConfig = new Argon2KdfConfig(3, 64, 17);
|
||||||
expect(() => kdfConfig.validateKdfConfig()).toThrow(
|
expect(() => kdfConfig.validateKdfConfigForSetting()).toThrow(
|
||||||
`Argon2 parallelism must be between ${Argon2KdfConfig.PARALLELISM.min} and ${Argon2KdfConfig.PARALLELISM.max}`,
|
`Argon2 parallelism must be between ${Argon2KdfConfig.PARALLELISM.min} and ${Argon2KdfConfig.PARALLELISM.max}`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("validateKdfConfigForPrelogin(): should validate the PBKDF2 KDF config", () => {
|
||||||
|
const kdfConfig: PBKDF2KdfConfig = new PBKDF2KdfConfig(600_000);
|
||||||
|
expect(() => kdfConfig.validateKdfConfigForPrelogin()).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("validateKdfConfigForPrelogin(): should validate the Argon2id KDF config", () => {
|
||||||
|
const kdfConfig: Argon2KdfConfig = new Argon2KdfConfig(3, 64, 4);
|
||||||
|
expect(() => kdfConfig.validateKdfConfigForPrelogin()).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("validateKdfConfigForPrelogin(): should throw an error for too low PBKDF2 iterations", () => {
|
||||||
|
const kdfConfig: PBKDF2KdfConfig = new PBKDF2KdfConfig(
|
||||||
|
PBKDF2KdfConfig.PRELOGIN_ITERATIONS.min - 1,
|
||||||
|
);
|
||||||
|
expect(() => kdfConfig.validateKdfConfigForPrelogin()).toThrow(
|
||||||
|
`PBKDF2 iterations must be between ${PBKDF2KdfConfig.PRELOGIN_ITERATIONS.min} and ${PBKDF2KdfConfig.PRELOGIN_ITERATIONS.max}`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("validateKdfConfigForPrelogin(): should throw an error for too high PBKDF2 iterations", () => {
|
||||||
|
const kdfConfig: PBKDF2KdfConfig = new PBKDF2KdfConfig(
|
||||||
|
PBKDF2KdfConfig.PRELOGIN_ITERATIONS.max + 1,
|
||||||
|
);
|
||||||
|
expect(() => kdfConfig.validateKdfConfigForPrelogin()).toThrow(
|
||||||
|
`PBKDF2 iterations must be between ${PBKDF2KdfConfig.PRELOGIN_ITERATIONS.min} and ${PBKDF2KdfConfig.PRELOGIN_ITERATIONS.max}`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("validateKdfConfigForPrelogin(): should throw an error for too low Argon2 iterations", () => {
|
||||||
|
const kdfConfig: Argon2KdfConfig = new Argon2KdfConfig(
|
||||||
|
Argon2KdfConfig.ITERATIONS.min - 1,
|
||||||
|
64,
|
||||||
|
4,
|
||||||
|
);
|
||||||
|
expect(() => kdfConfig.validateKdfConfigForPrelogin()).toThrow(
|
||||||
|
`Argon2 iterations must be between ${Argon2KdfConfig.ITERATIONS.min} and ${Argon2KdfConfig.ITERATIONS.max}`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("validateKdfConfigForPrelogin(): should throw an error for too high Argon2 iterations", () => {
|
||||||
|
const kdfConfig: Argon2KdfConfig = new Argon2KdfConfig(
|
||||||
|
Argon2KdfConfig.PRELOGIN_ITERATIONS.max + 1,
|
||||||
|
64,
|
||||||
|
4,
|
||||||
|
);
|
||||||
|
expect(() => kdfConfig.validateKdfConfigForPrelogin()).toThrow(
|
||||||
|
`Argon2 iterations must be between ${Argon2KdfConfig.ITERATIONS.min} and ${Argon2KdfConfig.ITERATIONS.max}`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("validateKdfConfigForPrelogin(): should throw an error for too low Argon2 memory", () => {
|
||||||
|
const kdfConfig: Argon2KdfConfig = new Argon2KdfConfig(
|
||||||
|
3,
|
||||||
|
Argon2KdfConfig.PRELOGIN_MEMORY.min - 1,
|
||||||
|
4,
|
||||||
|
);
|
||||||
|
expect(() => kdfConfig.validateKdfConfigForPrelogin()).toThrow(
|
||||||
|
`Argon2 memory must be between ${Argon2KdfConfig.PRELOGIN_MEMORY.min}mb and ${Argon2KdfConfig.PRELOGIN_MEMORY.max}mb`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("validateKdfConfigForPrelogin(): should throw an error for too high Argon2 memory", () => {
|
||||||
|
const kdfConfig: Argon2KdfConfig = new Argon2KdfConfig(
|
||||||
|
3,
|
||||||
|
Argon2KdfConfig.PRELOGIN_MEMORY.max + 1,
|
||||||
|
4,
|
||||||
|
);
|
||||||
|
expect(() => kdfConfig.validateKdfConfigForPrelogin()).toThrow(
|
||||||
|
`Argon2 memory must be between ${Argon2KdfConfig.PRELOGIN_MEMORY.min}mb and ${Argon2KdfConfig.PRELOGIN_MEMORY.max}mb`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("validateKdfConfigForPrelogin(): should throw an error for too high Argon2 parallelism", () => {
|
||||||
|
const kdfConfig: Argon2KdfConfig = new Argon2KdfConfig(3, 64, 17);
|
||||||
|
expect(() => kdfConfig.validateKdfConfigForPrelogin()).toThrow(
|
||||||
|
`Argon2 parallelism must be between ${Argon2KdfConfig.PRELOGIN_PARALLELISM.min} and ${Argon2KdfConfig.PRELOGIN_PARALLELISM.max}`,
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -362,7 +362,8 @@ describe("KeyConnectorService", () => {
|
||||||
familySponsorshipValidUntil: null,
|
familySponsorshipValidUntil: null,
|
||||||
familySponsorshipToDelete: null,
|
familySponsorshipToDelete: null,
|
||||||
accessSecretsManager: false,
|
accessSecretsManager: false,
|
||||||
limitCollectionCreationDeletion: true,
|
limitCollectionCreation: true,
|
||||||
|
limitCollectionDeletion: true,
|
||||||
allowAdminAccessToAllCollectionItems: true,
|
allowAdminAccessToAllCollectionItems: true,
|
||||||
flexibleCollections: false,
|
flexibleCollections: false,
|
||||||
object: "profileOrganization",
|
object: "profileOrganization",
|
||||||
|
|
|
@ -36,6 +36,7 @@ export enum FeatureFlag {
|
||||||
Pm3478RefactorOrganizationUserApi = "pm-3478-refactor-organizationuser-api",
|
Pm3478RefactorOrganizationUserApi = "pm-3478-refactor-organizationuser-api",
|
||||||
AccessIntelligence = "pm-13227-access-intelligence",
|
AccessIntelligence = "pm-13227-access-intelligence",
|
||||||
Pm13322AddPolicyDefinitions = "pm-13322-add-policy-definitions",
|
Pm13322AddPolicyDefinitions = "pm-13322-add-policy-definitions",
|
||||||
|
LimitCollectionCreationDeletionSplit = "pm-10863-limit-collection-creation-deletion-split",
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AllowedFeatureFlagTypes = boolean | number | string;
|
export type AllowedFeatureFlagTypes = boolean | number | string;
|
||||||
|
@ -82,6 +83,7 @@ export const DefaultFeatureFlagValue = {
|
||||||
[FeatureFlag.Pm3478RefactorOrganizationUserApi]: FALSE,
|
[FeatureFlag.Pm3478RefactorOrganizationUserApi]: FALSE,
|
||||||
[FeatureFlag.AccessIntelligence]: FALSE,
|
[FeatureFlag.AccessIntelligence]: FALSE,
|
||||||
[FeatureFlag.Pm13322AddPolicyDefinitions]: FALSE,
|
[FeatureFlag.Pm13322AddPolicyDefinitions]: FALSE,
|
||||||
|
[FeatureFlag.LimitCollectionCreationDeletionSplit]: FALSE,
|
||||||
} satisfies Record<FeatureFlag, AllowedFeatureFlagTypes>;
|
} satisfies Record<FeatureFlag, AllowedFeatureFlagTypes>;
|
||||||
|
|
||||||
export type DefaultFeatureFlagValueType = typeof DefaultFeatureFlagValue;
|
export type DefaultFeatureFlagValueType = typeof DefaultFeatureFlagValue;
|
||||||
|
|
|
@ -21,7 +21,6 @@ export class ProfileResponse extends BaseResponse {
|
||||||
securityStamp: string;
|
securityStamp: string;
|
||||||
forcePasswordReset: boolean;
|
forcePasswordReset: boolean;
|
||||||
usesKeyConnector: boolean;
|
usesKeyConnector: boolean;
|
||||||
managedByOrganizationId?: string | null;
|
|
||||||
organizations: ProfileOrganizationResponse[] = [];
|
organizations: ProfileOrganizationResponse[] = [];
|
||||||
providers: ProfileProviderResponse[] = [];
|
providers: ProfileProviderResponse[] = [];
|
||||||
providerOrganizations: ProfileProviderOrganizationResponse[] = [];
|
providerOrganizations: ProfileProviderOrganizationResponse[] = [];
|
||||||
|
@ -43,7 +42,6 @@ export class ProfileResponse extends BaseResponse {
|
||||||
this.securityStamp = this.getResponseProperty("SecurityStamp");
|
this.securityStamp = this.getResponseProperty("SecurityStamp");
|
||||||
this.forcePasswordReset = this.getResponseProperty("ForcePasswordReset") ?? false;
|
this.forcePasswordReset = this.getResponseProperty("ForcePasswordReset") ?? false;
|
||||||
this.usesKeyConnector = this.getResponseProperty("UsesKeyConnector") ?? false;
|
this.usesKeyConnector = this.getResponseProperty("UsesKeyConnector") ?? false;
|
||||||
this.managedByOrganizationId = this.getResponseProperty("ManagedByOrganizationId");
|
|
||||||
|
|
||||||
const organizations = this.getResponseProperty("Organizations");
|
const organizations = this.getResponseProperty("Organizations");
|
||||||
if (organizations != null) {
|
if (organizations != null) {
|
||||||
|
|
|
@ -123,6 +123,14 @@ export class DefaultConfigService implements ConfigService {
|
||||||
serverConfig: ServerConfig | null,
|
serverConfig: ServerConfig | null,
|
||||||
flag: Flag,
|
flag: Flag,
|
||||||
) {
|
) {
|
||||||
|
if (
|
||||||
|
flag === FeatureFlag.ExtensionRefresh ||
|
||||||
|
flag === FeatureFlag.UnauthenticatedExtensionUIRefresh ||
|
||||||
|
flag === FeatureFlag.EmailVerification
|
||||||
|
) {
|
||||||
|
return true as FeatureFlagValueType<Flag>;
|
||||||
|
}
|
||||||
|
|
||||||
if (serverConfig?.featureStates == null || serverConfig.featureStates[flag] == null) {
|
if (serverConfig?.featureStates == null || serverConfig.featureStates[flag] == null) {
|
||||||
return DefaultFeatureFlagValue[flag];
|
return DefaultFeatureFlagValue[flag];
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
import { Meta, Story, Controls } from "@storybook/addon-docs";
|
||||||
|
|
||||||
|
import * as stories from "./icon.stories";
|
||||||
|
|
||||||
|
<Meta of={stories} />
|
||||||
|
|
||||||
|
# Icon Use Instructions
|
||||||
|
|
||||||
|
- Icons will generally be attached to the associated Jira task.
|
||||||
|
- Designers should minify any SVGs before attaching them to Jira using a tool like
|
||||||
|
[SVGOMG](https://jakearchibald.github.io/svgomg/).
|
||||||
|
- **Note:** Ensure the "Remove viewbox" option is toggled off if responsive resizing of the icon
|
||||||
|
is desired.
|
||||||
|
|
||||||
|
## Developer Instructions
|
||||||
|
|
||||||
|
1. **Download the SVG** and import it as an `.svg` initially into the IDE of your choice.
|
||||||
|
|
||||||
|
- The SVG should be formatted using either a built-in formatter or an external tool like
|
||||||
|
[SVG Formatter Beautifier](https://codebeautify.org/svg-formatter-beautifier) to make applying
|
||||||
|
classes easier.
|
||||||
|
|
||||||
|
2. **Rename the file** as a `<name>.icon.ts` TypeScript file.
|
||||||
|
|
||||||
|
3. **Import** `svgIcon` from `@bitwarden/components`.
|
||||||
|
|
||||||
|
4. **Define and export** a `const` to represent your `svgIcon`.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export const ExampleIcon = svgIcon`<svg … </svg>`;
|
||||||
|
```
|
||||||
|
|
||||||
|
5. **Replace any hardcoded strokes or fills** with the appropriate Tailwind class.
|
||||||
|
|
||||||
|
- **Note:** Stroke is used when styling the outline of an SVG path, while fill is used when
|
||||||
|
styling the inside of an SVG path.
|
||||||
|
|
||||||
|
- A non-comprehensive list of common colors and their associated classes is below:
|
||||||
|
|
||||||
|
| Hardcoded Value | Tailwind Stroke Class | Tailwind Fill Class | Tailwind Variable |
|
||||||
|
| ---------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | ----------------------- | ----------------------- |
|
||||||
|
| `#020F66` <span style={{ display: "inline-block", width: "8px", height: "8px", borderRadius: "50%", backgroundColor: "#020F66"}}></span> | `tw-stroke-art-primary` | `tw-fill-art-primary` | `--color-art-primary` |
|
||||||
|
| `#10949D` <span style={{ display: "inline-block", width: "8px", height: "8px", borderRadius: "50%", backgroundColor: "#10949D"}}></span> | `tw-stroke-art-accent` | `tw-fill-art-accent` | `--color-art-accent` |
|
||||||
|
| `#2CDDE9` <span style={{ display: "inline-block", width: "8px", height: "8px", borderRadius: "50%", backgroundColor: "#2CDDE9"}}></span> | `tw-stroke-art-accent` | `tw-fill-art-accent` | `--color-art-accent` |
|
||||||
|
| `#89929F` <span style={{ display: "inline-block", width: "8px", height: "8px", borderRadius: "50%", backgroundColor: "#89929F"}}></span> | `tw-stroke-secondary-600` | `tw-fill-secondary-600` | `--color-secondary-600` |
|
||||||
|
|
||||||
|
- If the hex that you have on an SVG path is not listed above, there are a few ways to figure out
|
||||||
|
the appropriate Tailwind class:
|
||||||
|
|
||||||
|
- **Option 1: Figma**
|
||||||
|
- Open the SVG in Figma.
|
||||||
|
- Click on an individual path on the SVG until you see the path's properties in the
|
||||||
|
right-hand panel.
|
||||||
|
- Scroll down to the Colors section.
|
||||||
|
- Example: `Color/Art/Primary`
|
||||||
|
- This also includes Hex or RGB values that can be used to find the appropriate Tailwind
|
||||||
|
variable as well if you follow the manual search option below.
|
||||||
|
- Create the appropriate stroke or fill class from the color used.
|
||||||
|
- Example: `Color/Art/Primary` corresponds to `--color-art-primary` which corresponds to
|
||||||
|
`tw-stroke-art-primary` or `tw-fill-art-primary`.
|
||||||
|
- **Option 2: Manual Search**
|
||||||
|
- Take the path's stroke or fill hex value and convert it to RGB using a tool like
|
||||||
|
[Hex to RGB](https://www.rgbtohex.net/hex-to-rgb/).
|
||||||
|
- Search for the RGB value without commas in our `tw-theme.css` to find the Tailwind variable
|
||||||
|
that corresponds to the color.
|
||||||
|
- Create the appropriate stroke or fill class using the Tailwind variable.
|
||||||
|
- Example: `--color-art-primary` corresponds to `tw-stroke-art-primary` or
|
||||||
|
`tw-fill-art-primary`.
|
||||||
|
|
||||||
|
6. **Import your SVG const** anywhere you want to use the SVG.
|
||||||
|
|
||||||
|
- **Angular Component Example:**
|
||||||
|
|
||||||
|
- **TypeScript:**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { Component } from "@angular/core";
|
||||||
|
import { ExampleIcon } from "your/path/here";
|
||||||
|
import { IconModule } from '@bitwarden/components';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: "app-example",
|
||||||
|
standalone: true,
|
||||||
|
imports: [IconModule],
|
||||||
|
templateUrl: "./example.component.html",
|
||||||
|
})
|
||||||
|
export class ExampleComponent {
|
||||||
|
readonly Icons = { ExampleIcon, Example2Icon };
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- **HTML:**
|
||||||
|
```html
|
||||||
|
<bit-icon [icon]="Icons.ExampleIcon"></bit-icon>
|
||||||
|
```
|
||||||
|
|
||||||
|
7. **Ensure your SVG renders properly** according to Figma in both light and dark modes on a client
|
||||||
|
which supports multiple style modes.
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue