mirror of
https://github.com/bitwarden/browser.git
synced 2025-01-21 21:11:35 +01:00
Merge branch 'master' into tde-key-model-migration
This commit is contained in:
commit
86423d8e22
9
.github/CODEOWNERS
vendored
9
.github/CODEOWNERS
vendored
@ -4,7 +4,7 @@
|
||||
|
||||
# The following owners will be the default owners for everything in the repo.
|
||||
# Unless a later match takes precedence
|
||||
# @bitwarden/team-leads
|
||||
* @bitwarden/team-leads-eng
|
||||
|
||||
## Secrets Manager team files ##
|
||||
bitwarden_license/bit-web/src/app/secrets-manager @bitwarden/team-secrets-manager-dev
|
||||
@ -76,3 +76,10 @@ libs/components @bitwarden/team-platform-dev
|
||||
|
||||
## Desktop native module ##
|
||||
apps/desktop/desktop_native @bitwarden/team-platform-dev
|
||||
|
||||
## Multiple file owners ##
|
||||
/apps/web/config
|
||||
/apps/web/package.json
|
||||
|
||||
## DevOps team files ##
|
||||
/.github/workflows @bitwarden/dept-devops
|
||||
|
3
.github/whitelist-capital-letters.txt
vendored
3
.github/whitelist-capital-letters.txt
vendored
@ -4,7 +4,6 @@
|
||||
./apps/browser/src/safari/desktop/Base.lproj
|
||||
./apps/browser/src/services/vaultTimeout
|
||||
./apps/browser/store/windows/Assets
|
||||
./libs/common/src/abstractions/userVerification
|
||||
./libs/common/src/abstractions/vaultTimeout
|
||||
./libs/common/src/services/vaultTimeout
|
||||
./bitwarden_license/README.md
|
||||
@ -26,8 +25,6 @@
|
||||
./libs/common/src/misc/linkedFieldOption.decorator.ts
|
||||
./libs/common/src/misc/serviceUtils.ts
|
||||
./libs/common/src/misc/serviceUtils.spec.ts
|
||||
./libs/common/src/abstractions/userVerification/userVerification.service.abstraction.ts
|
||||
./libs/common/src/abstractions/userVerification/userVerification-api.service.abstraction.ts
|
||||
./libs/common/src/abstractions/vaultTimeout/vaultTimeoutSettings.service.ts
|
||||
./libs/common/src/abstractions/vaultTimeout/vaultTimeout.service.ts
|
||||
./libs/common/src/abstractions/anonymousHub.service.ts
|
||||
|
42
.github/workflows/auto-branch-updater.yml
vendored
Normal file
42
.github/workflows/auto-branch-updater.yml
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
---
|
||||
name: Auto Update Branch
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
- 'rc'
|
||||
paths:
|
||||
- 'apps/web/**'
|
||||
- 'libs/**'
|
||||
- '*'
|
||||
- '!*.md'
|
||||
- '!*.txt'
|
||||
- '.github/workflows/build-web.yml'
|
||||
workflow_dispatch:
|
||||
inputs: {}
|
||||
|
||||
jobs:
|
||||
update:
|
||||
name: Update Branch
|
||||
runs-on: ubuntu-22.04
|
||||
env:
|
||||
_BOT_EMAIL: 106330231+bitwarden-devops-bot@users.noreply.github.com
|
||||
_BOT_NAME: bitwarden-devops-bot
|
||||
steps:
|
||||
- name: Setup
|
||||
id: setup
|
||||
run: echo "branch=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
with:
|
||||
ref: 'eu-web-${{ steps.setup.outputs.branch }}'
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Merge ${{ steps.setup.outputs.branch }}
|
||||
run: |
|
||||
git config --local user.email "${{ env._BOT_EMAIL }}"
|
||||
git config --local user.name "${{ env._BOT_NAME }}"
|
||||
git merge origin/${{ steps.setup.outputs.branch }}
|
||||
git push
|
12
.github/workflows/build-browser.yml
vendored
12
.github/workflows/build-browser.yml
vendored
@ -41,7 +41,7 @@ jobs:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Set up cloc
|
||||
run: |
|
||||
@ -79,7 +79,7 @@ jobs:
|
||||
working-directory: apps/browser
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Testing locales - extName length
|
||||
run: |
|
||||
@ -119,7 +119,7 @@ jobs:
|
||||
working-directory: apps/browser
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
|
||||
@ -246,7 +246,7 @@ jobs:
|
||||
_BUILD_NUMBER: ${{ needs.setup.outputs.adj_build_number }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
|
||||
@ -345,7 +345,7 @@ jobs:
|
||||
- build-safari
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Login to Azure
|
||||
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
|
||||
@ -360,7 +360,7 @@ jobs:
|
||||
secrets: "crowdin-api-token"
|
||||
|
||||
- name: Upload Sources
|
||||
uses: crowdin/github-action@102b5aa21783a64027193ef802a616140a1ca102 # v1.8.1
|
||||
uses: crowdin/github-action@ee4ab4ea2feadc0fdc3b200729c7b1c4cf4b38f3 # v1.11.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}
|
||||
|
10
.github/workflows/build-cli.yml
vendored
10
.github/workflows/build-cli.yml
vendored
@ -38,7 +38,7 @@ jobs:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Set up cloc
|
||||
run: |
|
||||
@ -56,7 +56,7 @@ jobs:
|
||||
package_version: ${{ steps.retrieve-version.outputs.package_version }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Get Package Version
|
||||
id: retrieve-version
|
||||
@ -79,7 +79,7 @@ jobs:
|
||||
_WIN_PKG_VERSION: 3.4
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Setup Unix Vars
|
||||
run: |
|
||||
@ -153,7 +153,7 @@ jobs:
|
||||
_WIN_PKG_VERSION: 3.4
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Setup Windows builder
|
||||
run: |
|
||||
@ -299,7 +299,7 @@ jobs:
|
||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Print environment
|
||||
run: |
|
||||
|
22
.github/workflows/build-desktop.yml
vendored
22
.github/workflows/build-desktop.yml
vendored
@ -40,7 +40,7 @@ jobs:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Set up cloc
|
||||
run: |
|
||||
@ -55,7 +55,7 @@ jobs:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Verify
|
||||
run: |
|
||||
@ -83,7 +83,7 @@ jobs:
|
||||
working-directory: apps/desktop
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Get Package Version
|
||||
id: retrieve-version
|
||||
@ -143,7 +143,7 @@ jobs:
|
||||
working-directory: apps/desktop
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
|
||||
@ -259,7 +259,7 @@ jobs:
|
||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
|
||||
@ -472,7 +472,7 @@ jobs:
|
||||
working-directory: apps/desktop
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
|
||||
@ -624,7 +624,7 @@ jobs:
|
||||
working-directory: apps/desktop
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
|
||||
@ -821,7 +821,7 @@ jobs:
|
||||
working-directory: apps/desktop
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
|
||||
@ -1010,7 +1010,7 @@ jobs:
|
||||
working-directory: apps/desktop
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
|
||||
@ -1181,7 +1181,7 @@ jobs:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Login to Azure
|
||||
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
|
||||
@ -1196,7 +1196,7 @@ jobs:
|
||||
secrets: "crowdin-api-token"
|
||||
|
||||
- name: Upload Sources
|
||||
uses: crowdin/github-action@102b5aa21783a64027193ef802a616140a1ca102 # v1.8.1
|
||||
uses: crowdin/github-action@ee4ab4ea2feadc0fdc3b200729c7b1c4cf4b38f3 # v1.11.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}
|
||||
|
16
.github/workflows/build-web.yml
vendored
16
.github/workflows/build-web.yml
vendored
@ -37,7 +37,7 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Set up cloc
|
||||
run: |
|
||||
@ -56,7 +56,7 @@ jobs:
|
||||
version: ${{ steps.version.outputs.value }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Get GitHub sha as version
|
||||
id: version
|
||||
@ -84,10 +84,12 @@ jobs:
|
||||
npm_command: "build:bit:ee"
|
||||
- name: "cloud-euprd"
|
||||
npm_command: "build:bit:euprd"
|
||||
- name: "cloud-euqa"
|
||||
npm_command: "build:bit:euqa"
|
||||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
|
||||
@ -156,7 +158,7 @@ jobs:
|
||||
_VERSION: ${{ needs.setup.outputs.version }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Check Branch to Publish
|
||||
env:
|
||||
@ -249,7 +251,7 @@ jobs:
|
||||
azure-keyvault-name: "bitwarden-ci"
|
||||
|
||||
- name: Build Docker image
|
||||
uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671 # v4.0.0
|
||||
uses: docker/build-push-action@2eb1c1961a95fc15694676618e422e8ba1d63825 # v4.1.1
|
||||
with:
|
||||
context: apps/web
|
||||
file: apps/web/Dockerfile
|
||||
@ -282,7 +284,7 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Login to Azure
|
||||
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
|
||||
@ -297,7 +299,7 @@ jobs:
|
||||
secrets: "crowdin-api-token"
|
||||
|
||||
- name: Upload Sources
|
||||
uses: crowdin/github-action@102b5aa21783a64027193ef802a616140a1ca102 # v1.8.1
|
||||
uses: crowdin/github-action@ee4ab4ea2feadc0fdc3b200729c7b1c4cf4b38f3 # v1.11.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}
|
||||
|
4
.github/workflows/chromatic.yml
vendored
4
.github/workflows/chromatic.yml
vendored
@ -18,7 +18,7 @@ jobs:
|
||||
node-version: "16"
|
||||
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@ -37,7 +37,7 @@ jobs:
|
||||
run: npm run build-storybook:ci
|
||||
|
||||
- name: Publish to Chromatic
|
||||
uses: chromaui/action@a2ed440e22f7d4e2c6b0710f7903aa2df70a1ecd
|
||||
uses: chromaui/action@44caff7e88d584b04f79f04e31e819f9a95d4d8f
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
|
||||
|
2
.github/workflows/crowdin-pull.yml
vendored
2
.github/workflows/crowdin-pull.yml
vendored
@ -23,7 +23,7 @@ jobs:
|
||||
crowdin_project_id: "308189"
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Login to Azure
|
||||
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
|
||||
|
13
.github/workflows/deploy-eu-prod-web.yml
vendored
13
.github/workflows/deploy-eu-prod-web.yml
vendored
@ -18,7 +18,7 @@ jobs:
|
||||
_WEB_ARTIFACT: "web-*-cloud-euprd.zip"
|
||||
steps:
|
||||
- name: Login to Azure - EU Subscription
|
||||
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.6
|
||||
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_KV_EU_PRD_SERVICE_PRINCIPAL }}
|
||||
|
||||
@ -42,12 +42,19 @@ jobs:
|
||||
working-directory: apps/web
|
||||
run: unzip ${{ env._WEB_ARTIFACT }}
|
||||
|
||||
- name: Empty container in Storage Account
|
||||
run: |
|
||||
az storage blob delete-batch \
|
||||
--source '$web' \
|
||||
--pattern '*' \
|
||||
--connection-string "${{ steps.retrieve-secrets.outputs.sa-bitwarden-web-vault-dev-key-temp }}"
|
||||
|
||||
- name: Deploy to Azure Storage Account
|
||||
working-directory: apps/web
|
||||
run: |
|
||||
az storage blob upload-batch --source "./build" \
|
||||
az storage blob upload-batch \
|
||||
--source "./build" \
|
||||
--destination '$web' \
|
||||
--account-name "bwwebvault1itgprod" \
|
||||
--connection-string "${{ steps.retrieve-secrets.outputs.sa-bitwarden-web-vault-dev-key-temp }}" \
|
||||
--overwrite \
|
||||
--no-progress
|
||||
|
60
.github/workflows/deploy-eu-qa-web.yml
vendored
Normal file
60
.github/workflows/deploy-eu-qa-web.yml
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
---
|
||||
name: Deploy Web to EU-QA Cloud
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
description: "Branch name to deploy (examples: 'master', 'feature/sm')"
|
||||
required: true
|
||||
type: string
|
||||
default: master
|
||||
|
||||
jobs:
|
||||
azure-deploy:
|
||||
name: Deploy to Azure
|
||||
runs-on: ubuntu-22.04
|
||||
env:
|
||||
_WEB_ARTIFACT: "web-*-cloud-euqa.zip"
|
||||
steps:
|
||||
- name: Login to Azure - EU Subscription
|
||||
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_KV_EU_QA_SERVICE_PRINCIPAL }}
|
||||
|
||||
- name: Retrieve Storage Account connection string
|
||||
id: retrieve-secrets
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@37ffa14164a7308bc273829edfe75c97cd562375
|
||||
with:
|
||||
keyvault: webvaulteu-westeurope-qa
|
||||
secrets: "sa-bitwarden-web-vault-dev-key-temp"
|
||||
|
||||
- name: Download latest cloud asset
|
||||
uses: bitwarden/gh-actions/download-artifacts@37ffa14164a7308bc273829edfe75c97cd562375
|
||||
with:
|
||||
workflow: build-web.yml
|
||||
path: apps/web
|
||||
workflow_conclusion: success
|
||||
branch: ${{ github.event.inputs.tag }}
|
||||
artifacts: ${{ env._WEB_ARTIFACT }}
|
||||
|
||||
- name: Unzip build asset
|
||||
working-directory: apps/web
|
||||
run: unzip ${{ env._WEB_ARTIFACT }}
|
||||
|
||||
- name: Empty container in Storage Account
|
||||
run: |
|
||||
az storage blob delete-batch \
|
||||
--source '$web' \
|
||||
--pattern '*' \
|
||||
--connection-string "${{ steps.retrieve-secrets.outputs.sa-bitwarden-web-vault-dev-key-temp }}"
|
||||
|
||||
- name: Deploy to Azure Storage Account
|
||||
working-directory: apps/web
|
||||
run: |
|
||||
az storage blob upload-batch \
|
||||
--source "./build" \
|
||||
--destination '$web' \
|
||||
--connection-string "${{ steps.retrieve-secrets.outputs.sa-bitwarden-web-vault-dev-key-temp }}" \
|
||||
--overwrite \
|
||||
--no-progress
|
6
.github/workflows/deploy-non-prod-web.yml
vendored
6
.github/workflows/deploy-non-prod-web.yml
vendored
@ -12,8 +12,6 @@ on:
|
||||
type: choice
|
||||
options:
|
||||
- QA
|
||||
- POC2
|
||||
- eudevtest
|
||||
|
||||
|
||||
jobs:
|
||||
@ -61,7 +59,7 @@ jobs:
|
||||
description: 'Deployment from branch ${{ github.ref_name }}'
|
||||
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Download latest cloud asset
|
||||
uses: bitwarden/gh-actions/download-artifacts@37ffa14164a7308bc273829edfe75c97cd562375
|
||||
@ -77,7 +75,7 @@ jobs:
|
||||
run: unzip ${{ env._ENVIRONMENT_ARTIFACT }}
|
||||
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
with:
|
||||
ref: ${{ env._ENVIRONMENT_BRANCH }}
|
||||
path: deployment
|
||||
|
2
.github/workflows/lint.yml
vendored
2
.github/workflows/lint.yml
vendored
@ -21,7 +21,7 @@ jobs:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Lint filenames (no capital characters)
|
||||
run: |
|
||||
|
4
.github/workflows/release-browser.yml
vendored
4
.github/workflows/release-browser.yml
vendored
@ -27,7 +27,7 @@ jobs:
|
||||
release-version: ${{ steps.version.outputs.version }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Branch check
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
@ -56,7 +56,7 @@ jobs:
|
||||
needs: setup
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Testing locales - extName length
|
||||
run: |
|
||||
|
8
.github/workflows/release-cli.yml
vendored
8
.github/workflows/release-cli.yml
vendored
@ -43,7 +43,7 @@ jobs:
|
||||
release-version: ${{ steps.version.outputs.version }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Branch check
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
@ -141,7 +141,7 @@ jobs:
|
||||
_PKG_VERSION: ${{ needs.setup.outputs.release-version }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Login to Azure
|
||||
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
|
||||
@ -195,7 +195,7 @@ jobs:
|
||||
_PKG_VERSION: ${{ needs.setup.outputs.release-version }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Login to Azure
|
||||
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
|
||||
@ -254,7 +254,7 @@ jobs:
|
||||
_PKG_VERSION: ${{ needs.setup.outputs.release-version }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Login to Azure
|
||||
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
|
||||
|
14
.github/workflows/release-desktop-beta.yml
vendored
14
.github/workflows/release-desktop-beta.yml
vendored
@ -23,7 +23,7 @@ jobs:
|
||||
build_number: ${{ steps.increment-version.outputs.build_number }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Branch check
|
||||
run: |
|
||||
@ -115,7 +115,7 @@ jobs:
|
||||
working-directory: apps/desktop
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
with:
|
||||
ref: ${{ needs.setup.outputs.branch-name }}
|
||||
|
||||
@ -211,7 +211,7 @@ jobs:
|
||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.release-version }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
with:
|
||||
ref: ${{ needs.setup.outputs.branch-name }}
|
||||
|
||||
@ -406,7 +406,7 @@ jobs:
|
||||
working-directory: apps/desktop
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
with:
|
||||
ref: ${{ needs.setup.outputs.branch-name }}
|
||||
|
||||
@ -535,7 +535,7 @@ jobs:
|
||||
working-directory: apps/desktop
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
with:
|
||||
ref: ${{ needs.setup.outputs.branch-name }}
|
||||
|
||||
@ -737,7 +737,7 @@ jobs:
|
||||
working-directory: apps/desktop
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
with:
|
||||
ref: ${{ needs.setup.outputs.branch-name }}
|
||||
|
||||
@ -1011,7 +1011,7 @@ jobs:
|
||||
- release
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Setup git config
|
||||
run: |
|
||||
|
6
.github/workflows/release-desktop.yml
vendored
6
.github/workflows/release-desktop.yml
vendored
@ -53,7 +53,7 @@ jobs:
|
||||
release-channel: ${{ steps.release-channel.outputs.channel }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Branch check
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
@ -254,7 +254,7 @@ jobs:
|
||||
_PKG_VERSION: ${{ needs.setup.outputs.release-version }}
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Login to Azure
|
||||
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
|
||||
@ -315,7 +315,7 @@ jobs:
|
||||
_PKG_VERSION: ${{ needs.setup.outputs.release-version }}
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Print Environment
|
||||
run: |
|
||||
|
4
.github/workflows/release-qa-web.yml
vendored
4
.github/workflows/release-qa-web.yml
vendored
@ -20,7 +20,7 @@ jobs:
|
||||
description: 'Deployment from branch ${{ github.ref_name }}'
|
||||
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Download latest cloud asset
|
||||
uses: bitwarden/gh-actions/download-artifacts@37ffa14164a7308bc273829edfe75c97cd562375
|
||||
@ -36,7 +36,7 @@ jobs:
|
||||
run: unzip web-*-cloud-QA.zip
|
||||
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
with:
|
||||
ref: cf-pages-qa
|
||||
path: deployment
|
||||
|
6
.github/workflows/release-web.yml
vendored
6
.github/workflows/release-web.yml
vendored
@ -24,7 +24,7 @@ jobs:
|
||||
tag_version: ${{ steps.version.outputs.tag }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Branch check
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
@ -65,7 +65,7 @@ jobs:
|
||||
echo "Github Release Option: $_RELEASE_OPTION"
|
||||
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
########## DockerHub ##########
|
||||
- name: Setup DCT
|
||||
@ -162,7 +162,7 @@ jobs:
|
||||
secrets: "github-pat-bitwarden-devops-bot-repo-scope"
|
||||
|
||||
- name: Checkout GH pages repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
with:
|
||||
repository: bitwarden/web-vault-pages
|
||||
path: ghpages-deployment
|
||||
|
4
.github/workflows/test.yml
vendored
4
.github/workflows/test.yml
vendored
@ -25,7 +25,7 @@ jobs:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
|
||||
@ -79,7 +79,7 @@ jobs:
|
||||
sudo apt-get install -y gnome-keyring dbus-x11
|
||||
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Install rust
|
||||
uses: actions-rs/toolchain@16499b5e05bf2e26879000db0c1d13f7e13fa3af # v1.0.7
|
||||
|
2
.github/workflows/version-auto-bump.yml
vendored
2
.github/workflows/version-auto-bump.yml
vendored
@ -18,7 +18,7 @@ jobs:
|
||||
version_number: ${{ steps.version.outputs.new-version }}
|
||||
steps:
|
||||
- name: Checkout Branch
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Calculate bumped version
|
||||
id: version
|
||||
|
2
.github/workflows/version-bump.yml
vendored
2
.github/workflows/version-bump.yml
vendored
@ -40,7 +40,7 @@ jobs:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout Branch
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
|
||||
- name: Login to Azure - Prod Subscription
|
||||
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
|
||||
|
@ -101,6 +101,7 @@ const preview: Preview = {
|
||||
},
|
||||
options: {
|
||||
storySort: {
|
||||
method: "alphabetical",
|
||||
order: ["Documentation", ["Introduction", "Colors", "Icons"], "Component Library"],
|
||||
},
|
||||
},
|
||||
|
@ -952,7 +952,7 @@
|
||||
"message": "Server URL"
|
||||
},
|
||||
"apiUrl": {
|
||||
"message": "API Server URL"
|
||||
"message": "API server URL"
|
||||
},
|
||||
"webVaultUrl": {
|
||||
"message": "Web vault server URL"
|
||||
|
@ -952,7 +952,7 @@
|
||||
"message": "Server URL"
|
||||
},
|
||||
"apiUrl": {
|
||||
"message": "API Server URL"
|
||||
"message": "API server URL"
|
||||
},
|
||||
"webVaultUrl": {
|
||||
"message": "Web vault server URL"
|
||||
|
@ -952,7 +952,7 @@
|
||||
"message": "Server URL"
|
||||
},
|
||||
"apiUrl": {
|
||||
"message": "API Server URL"
|
||||
"message": "API Server-URL"
|
||||
},
|
||||
"webVaultUrl": {
|
||||
"message": "URL des Web-Tresor-Servers"
|
||||
|
@ -952,7 +952,7 @@
|
||||
"message": "Server URL"
|
||||
},
|
||||
"apiUrl": {
|
||||
"message": "API Server URL"
|
||||
"message": "API server URL"
|
||||
},
|
||||
"webVaultUrl": {
|
||||
"message": "Web vault server URL"
|
||||
|
@ -2222,20 +2222,20 @@
|
||||
}
|
||||
},
|
||||
"region": {
|
||||
"message": "Region"
|
||||
"message": "منطقه"
|
||||
},
|
||||
"opensInANewWindow": {
|
||||
"message": "در پنجره جدید باز میشود"
|
||||
},
|
||||
"eu": {
|
||||
"message": "EU",
|
||||
"message": "اروپا",
|
||||
"description": "European Union"
|
||||
},
|
||||
"us": {
|
||||
"message": "US",
|
||||
"message": "امریکا",
|
||||
"description": "United States"
|
||||
},
|
||||
"accessDenied": {
|
||||
"message": "Access denied. You do not have permission to view this page."
|
||||
"message": "دسترسی رد شد. شما اجازه مشاهده این صفحه را ندارید."
|
||||
}
|
||||
}
|
||||
|
@ -952,7 +952,7 @@
|
||||
"message": "Server URL"
|
||||
},
|
||||
"apiUrl": {
|
||||
"message": "API Server URL"
|
||||
"message": "API server URL"
|
||||
},
|
||||
"webVaultUrl": {
|
||||
"message": "Web vault server URL"
|
||||
|
@ -952,7 +952,7 @@
|
||||
"message": "Server URL"
|
||||
},
|
||||
"apiUrl": {
|
||||
"message": "API Server URL"
|
||||
"message": "API server URL"
|
||||
},
|
||||
"webVaultUrl": {
|
||||
"message": "Web vault server URL"
|
||||
|
@ -952,7 +952,7 @@
|
||||
"message": "Server URL"
|
||||
},
|
||||
"apiUrl": {
|
||||
"message": "API Server URL"
|
||||
"message": "API server URL"
|
||||
},
|
||||
"webVaultUrl": {
|
||||
"message": "Web vault server URL"
|
||||
|
@ -952,7 +952,7 @@
|
||||
"message": "Server URL"
|
||||
},
|
||||
"apiUrl": {
|
||||
"message": "API Server URL"
|
||||
"message": "API server URL"
|
||||
},
|
||||
"webVaultUrl": {
|
||||
"message": "Web vault server URL"
|
||||
|
@ -952,7 +952,7 @@
|
||||
"message": "Server URL"
|
||||
},
|
||||
"apiUrl": {
|
||||
"message": "API Server URL"
|
||||
"message": "API server URL"
|
||||
},
|
||||
"webVaultUrl": {
|
||||
"message": "Web vault server URL"
|
||||
|
@ -952,7 +952,7 @@
|
||||
"message": "Server URL"
|
||||
},
|
||||
"apiUrl": {
|
||||
"message": "API Server URL"
|
||||
"message": "API server URL"
|
||||
},
|
||||
"webVaultUrl": {
|
||||
"message": "Web vault server URL"
|
||||
|
@ -952,7 +952,7 @@
|
||||
"message": "Server URL"
|
||||
},
|
||||
"apiUrl": {
|
||||
"message": "API Server URL"
|
||||
"message": "API server URL"
|
||||
},
|
||||
"webVaultUrl": {
|
||||
"message": "Web vault server URL"
|
||||
|
@ -678,7 +678,7 @@
|
||||
"message": "Esta exportação contém os dados do seu cofre num formato não encriptado. Não deve armazenar ou enviar o ficheiro exportado através de canais não seguros (como o e-mail). Elimine-o imediatamente após terminar a sua utilização."
|
||||
},
|
||||
"encExportKeyWarningDesc": {
|
||||
"message": "Esta exportação encripta os seus dados utilizando a chave de encriptação da sua conta. Se alguma vez alterar a chave de encriptação da sua conta, deve exportar novamente, uma vez que não conseguirá desencriptar este ficheiro de exportação."
|
||||
"message": "Esta exportação encripta os seus dados utilizando a chave de encriptação da sua conta. Se alguma vez regenerar a chave de encriptação da sua conta, deve exportar novamente, uma vez que não conseguirá desencriptar este ficheiro de exportação."
|
||||
},
|
||||
"encExportAccountWarningDesc": {
|
||||
"message": "As chaves de encriptação da conta são únicas para cada conta de utilizador Bitwarden, pelo que não é possível importar uma exportação encriptada para uma conta diferente."
|
||||
@ -1137,7 +1137,7 @@
|
||||
"message": "Sra."
|
||||
},
|
||||
"ms": {
|
||||
"message": "Sra."
|
||||
"message": "Menina"
|
||||
},
|
||||
"dr": {
|
||||
"message": "Dr."
|
||||
@ -2001,17 +2001,17 @@
|
||||
"message": "Tipo de nome de utilizador"
|
||||
},
|
||||
"plusAddressedEmail": {
|
||||
"message": "Plus addressed email",
|
||||
"message": "E-mail com subendereço",
|
||||
"description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com"
|
||||
},
|
||||
"plusAddressedEmailDesc": {
|
||||
"message": "Use your email provider's sub-addressing capabilities."
|
||||
"message": "Utilize as capacidades de subendereçamento do seu provedor de e-mail."
|
||||
},
|
||||
"catchallEmail": {
|
||||
"message": "Catch-all email"
|
||||
"message": "E-mail de captura geral"
|
||||
},
|
||||
"catchallEmailDesc": {
|
||||
"message": "Use your domain's configured catch-all inbox."
|
||||
"message": "Utilize a caixa de entrada de captura geral configurada para o seu domínio."
|
||||
},
|
||||
"random": {
|
||||
"message": "Aleatório"
|
||||
|
@ -952,7 +952,7 @@
|
||||
"message": "Server-URL"
|
||||
},
|
||||
"apiUrl": {
|
||||
"message": "API server-URL"
|
||||
"message": "API-server-URL"
|
||||
},
|
||||
"webVaultUrl": {
|
||||
"message": "Webbvalvsserver-URL"
|
||||
|
@ -952,7 +952,7 @@
|
||||
"message": "Server URL"
|
||||
},
|
||||
"apiUrl": {
|
||||
"message": "API Server URL"
|
||||
"message": "API server URL"
|
||||
},
|
||||
"webVaultUrl": {
|
||||
"message": "Web vault server URL"
|
||||
|
@ -2042,7 +2042,7 @@
|
||||
"description": "Part of a URL."
|
||||
},
|
||||
"apiAccessToken": {
|
||||
"message": "API erişim anahtarı"
|
||||
"message": "API erişim token'ı"
|
||||
},
|
||||
"apiKey": {
|
||||
"message": "API anahtarı"
|
||||
|
@ -952,7 +952,7 @@
|
||||
"message": "伺服器 URL"
|
||||
},
|
||||
"apiUrl": {
|
||||
"message": "API 伺服器 URL"
|
||||
"message": "API 伺服器網址"
|
||||
},
|
||||
"webVaultUrl": {
|
||||
"message": "網頁版密碼庫伺服器 URL"
|
||||
|
@ -7,8 +7,6 @@ import { NotificationsService as NotificationsServiceAbstraction } from "@bitwar
|
||||
import { SearchService as SearchServiceAbstraction } from "@bitwarden/common/abstractions/search.service";
|
||||
import { SettingsService as SettingsServiceAbstraction } from "@bitwarden/common/abstractions/settings.service";
|
||||
import { TotpService as TotpServiceAbstraction } from "@bitwarden/common/abstractions/totp.service";
|
||||
import { UserVerificationApiServiceAbstraction } from "@bitwarden/common/abstractions/userVerification/userVerification-api.service.abstraction";
|
||||
import { UserVerificationService as UserVerificationServiceAbstraction } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction";
|
||||
import { VaultTimeoutService as VaultTimeoutServiceAbstraction } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeout.service";
|
||||
import { VaultTimeoutSettingsService as VaultTimeoutSettingsServiceAbstraction } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeoutSettings.service";
|
||||
import { InternalOrganizationService as InternalOrganizationServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||
@ -21,6 +19,8 @@ import { AuthService as AuthServiceAbstraction } from "@bitwarden/common/auth/ab
|
||||
import { KeyConnectorService as KeyConnectorServiceAbstraction } from "@bitwarden/common/auth/abstractions/key-connector.service";
|
||||
import { TokenService as TokenServiceAbstraction } from "@bitwarden/common/auth/abstractions/token.service";
|
||||
import { TwoFactorService as TwoFactorServiceAbstraction } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
||||
import { UserVerificationApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/user-verification/user-verification-api.service.abstraction";
|
||||
import { UserVerificationService as UserVerificationServiceAbstraction } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||
import { AuthService } from "@bitwarden/common/auth/services/auth.service";
|
||||
import { KeyConnectorService } from "@bitwarden/common/auth/services/key-connector.service";
|
||||
import { TokenService } from "@bitwarden/common/auth/services/token.service";
|
||||
|
@ -15,7 +15,6 @@ import { NotificationsService } from "@bitwarden/common/abstractions/notificatio
|
||||
import { SearchService as SearchServiceAbstraction } from "@bitwarden/common/abstractions/search.service";
|
||||
import { SettingsService } from "@bitwarden/common/abstractions/settings.service";
|
||||
import { TotpService } from "@bitwarden/common/abstractions/totp.service";
|
||||
import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction";
|
||||
import { VaultTimeoutService } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeout.service";
|
||||
import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeoutSettings.service";
|
||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||
@ -31,6 +30,7 @@ import { KeyConnectorService } from "@bitwarden/common/auth/abstractions/key-con
|
||||
import { LoginService as LoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/login.service";
|
||||
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
||||
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
||||
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||
import { AuthService } from "@bitwarden/common/auth/services/auth.service";
|
||||
import { LoginService } from "@bitwarden/common/auth/services/login.service";
|
||||
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
||||
|
@ -5,8 +5,8 @@ import { Router } from "@angular/router";
|
||||
import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog";
|
||||
import { ExportComponent as BaseExportComponent } from "@bitwarden/angular/tools/export/components/export.component";
|
||||
import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service";
|
||||
import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction";
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
|
@ -55,7 +55,7 @@
|
||||
{{ "typeLogins" | i18n }}
|
||||
<span class="flex-right">{{ loginCiphers.length }}</span>
|
||||
</h2>
|
||||
<div class="box-content no-hover">
|
||||
<div class="box-content">
|
||||
<app-cipher-row
|
||||
*ngFor="let loginCipher of loginCiphers"
|
||||
[cipher]="loginCipher"
|
||||
|
@ -6,8 +6,8 @@ import { UntypedFormBuilder } from "@angular/forms";
|
||||
import { DialogServiceAbstraction, SimpleDialogType } from "@bitwarden/angular/services/dialog";
|
||||
import { ExportComponent as BaseExportComponent } from "@bitwarden/angular/tools/export/components/export.component";
|
||||
import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service";
|
||||
import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction";
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service";
|
||||
|
@ -2253,20 +2253,20 @@
|
||||
"message": "بهروز رسانی تنظیمات توصیه شده"
|
||||
},
|
||||
"region": {
|
||||
"message": "Region"
|
||||
"message": "منطقه"
|
||||
},
|
||||
"eu": {
|
||||
"message": "EU",
|
||||
"message": "اروپا",
|
||||
"description": "European Union"
|
||||
},
|
||||
"us": {
|
||||
"message": "US",
|
||||
"message": "امریکا",
|
||||
"description": "United States"
|
||||
},
|
||||
"selfHosted": {
|
||||
"message": "Self-hosted"
|
||||
"message": "خود میزبان"
|
||||
},
|
||||
"accessDenied": {
|
||||
"message": "Access denied. You do not have permission to view this page."
|
||||
"message": "دسترسی رد شد. شما اجازه مشاهده این صفحه را ندارید."
|
||||
}
|
||||
}
|
||||
|
@ -236,7 +236,7 @@
|
||||
"message": "Sra."
|
||||
},
|
||||
"ms": {
|
||||
"message": "Sra."
|
||||
"message": "Menina"
|
||||
},
|
||||
"mx": {
|
||||
"message": "Neutro"
|
||||
@ -1338,7 +1338,7 @@
|
||||
"message": "Esta exportação contém os dados do seu cofre num formato não encriptado. Não deve armazenar ou enviar o ficheiro exportado através de canais não seguros (como o e-mail). Elimine-o imediatamente após terminar a sua utilização."
|
||||
},
|
||||
"encExportKeyWarningDesc": {
|
||||
"message": "Esta exportação encripta os seus dados utilizando a chave de encriptação da sua conta. Se alguma vez alterar a chave de encriptação da sua conta, deve exportar novamente, uma vez que não conseguirá desencriptar este ficheiro de exportação."
|
||||
"message": "Esta exportação encripta os seus dados utilizando a chave de encriptação da sua conta. Se alguma vez regenerar a chave de encriptação da sua conta, deve exportar novamente, uma vez que não conseguirá desencriptar este ficheiro de exportação."
|
||||
},
|
||||
"encExportAccountWarningDesc": {
|
||||
"message": "As chaves de encriptação da conta são únicas para cada conta de utilizador Bitwarden, pelo que não é possível importar uma exportação encriptada para uma conta diferente."
|
||||
|
@ -542,7 +542,7 @@
|
||||
"message": "Yêu cầu nhập lại mật khẩu chính."
|
||||
},
|
||||
"masterPasswordMinlength": {
|
||||
"message": "Master password must be at least $VALUE$ characters long.",
|
||||
"message": "Mật khẩu chính phải có ít nhất $VALUE$ kí tự.",
|
||||
"description": "The Master Password must be at least a specific number of characters long.",
|
||||
"placeholders": {
|
||||
"value": {
|
||||
@ -771,7 +771,7 @@
|
||||
"message": "Liên hệ với chúng tôi"
|
||||
},
|
||||
"helpAndFeedback": {
|
||||
"message": "Help and feedback"
|
||||
"message": "Trợ giúp và phản hồi"
|
||||
},
|
||||
"getHelp": {
|
||||
"message": "Trợ giúp"
|
||||
@ -962,19 +962,19 @@
|
||||
"message": "Tự động bắt đầu khi đăng nhập"
|
||||
},
|
||||
"openAtLoginDesc": {
|
||||
"message": "Start the Bitwarden desktop application automatically on login."
|
||||
"message": "Tự động chạy ứng dụng máy tính Bitwarden khi đăng nhập."
|
||||
},
|
||||
"alwaysShowDock": {
|
||||
"message": "Always show in the Dock"
|
||||
"message": "Luôn hiện ở thanh Dock"
|
||||
},
|
||||
"alwaysShowDockDesc": {
|
||||
"message": "Show the Bitwarden icon in the Dock even when minimized to the menu bar."
|
||||
"message": "Hiện biểu tượng Bitwarden trong Dock ngày cả khi thu nhỏ về thanh hệ thống."
|
||||
},
|
||||
"confirmTrayTitle": {
|
||||
"message": "Xác nhận ẩn khay"
|
||||
},
|
||||
"confirmTrayDesc": {
|
||||
"message": "Turning off this setting will also turn off all other tray related settings."
|
||||
"message": "Việc tắt cài đặt này cũng sẽ tắt tất cả các cài đặt liên quan khác."
|
||||
},
|
||||
"language": {
|
||||
"message": "Ngôn ngữ"
|
||||
@ -1298,7 +1298,7 @@
|
||||
"description": "hCaptcha is the name of a website, should not be translated"
|
||||
},
|
||||
"loadAccessibilityCookie": {
|
||||
"message": "Load accessibility cookie"
|
||||
"message": "Tải cookie hỗ trợ tiếp cận"
|
||||
},
|
||||
"registerAccessibilityUser": {
|
||||
"message": "Register as an accessibility user at",
|
||||
|
@ -1,11 +0,0 @@
|
||||
{
|
||||
"urls": {
|
||||
"icons": "https://icons.eudevtest.bitwarden.pw",
|
||||
"notifications": "https://notifications.eudevtest.bitwarden.pw",
|
||||
"scim": "https://scim.eudevtest.bitwarden.pw"
|
||||
},
|
||||
"flags": {
|
||||
"secretsManager": true,
|
||||
"showPasswordless": true
|
||||
}
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
{
|
||||
"urls": {
|
||||
"icons": "https://icons.bitwarden.net",
|
||||
"notifications": "https://notifications.beta.bitwarden.net",
|
||||
"scim": "https://scim.beta.bitwarden.net"
|
||||
"icons": "https://icons.bitwarden.eu",
|
||||
"notifications": "https://notifications.bitwarden.eu",
|
||||
"scim": "https://scim.bitwarden.eu"
|
||||
},
|
||||
"flags": {
|
||||
"secretsManager": true,
|
||||
|
11
apps/web/config/euqa.json
Normal file
11
apps/web/config/euqa.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"urls": {
|
||||
"icons": "https://icons.euqa.bitwarden.pw",
|
||||
"notifications": "https://notifications.euqa.bitwarden.pw",
|
||||
"scim": "https://scim.euqa.bitwarden.pw"
|
||||
},
|
||||
"flags": {
|
||||
"secretsManager": true,
|
||||
"showPasswordless": true
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@
|
||||
"build:bit:dev:watch": "cross-env ENV=development npm run build:bit:watch",
|
||||
"build:bit:qa": "cross-env NODE_ENV=production ENV=qa npm run build:bit",
|
||||
"build:bit:euprd": "cross-env NODE_ENV=production ENV=euprd npm run build:bit",
|
||||
"build:bit:eudevtest": "cross-env NODE_ENV=production ENV=eudevtest npm run build:bit",
|
||||
"build:bit:euqa": "cross-env NODE_ENV=production ENV=euqa npm run build:bit",
|
||||
"build:bit:cloud": "cross-env NODE_ENV=production ENV=cloud npm run build:bit",
|
||||
"build:oss:selfhost:watch": "cross-env ENV=selfhosted npm run build:oss:watch",
|
||||
"build:bit:selfhost:watch": "cross-env ENV=selfhosted npm run build:bit:watch",
|
||||
|
@ -0,0 +1,46 @@
|
||||
<bit-dialog dialogSize="large">
|
||||
<span bitDialogTitle>{{ "enableSecretsManager" | i18n }}</span>
|
||||
<span bitDialogContent>
|
||||
<p>{{ "bulkEnableSecretsManagerDescription" | i18n }}</p>
|
||||
<bit-table [dataSource]="dataSource">
|
||||
<ng-container header>
|
||||
<tr>
|
||||
<th bitCell>{{ "member" | i18n }}</th>
|
||||
<th bitCell>{{ "role" | i18n }}</th>
|
||||
</tr>
|
||||
</ng-container>
|
||||
<ng-template body let-rows$>
|
||||
<tr bitRow *ngFor="let u of rows$ | async">
|
||||
<td bitCell>
|
||||
<div class="tw-flex tw-items-center">
|
||||
<bit-avatar
|
||||
size="small"
|
||||
[text]="u | userName"
|
||||
[id]="u.userId"
|
||||
[color]="u.avatarColor"
|
||||
class="tw-mr-3"
|
||||
></bit-avatar>
|
||||
<div class="tw-flex tw-flex-col">
|
||||
<div>
|
||||
{{ u | userName }}
|
||||
</div>
|
||||
<div class="tw-text-sm tw-text-muted" *ngIf="u.name">
|
||||
{{ u.email }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td bitCell>{{ u.type | userType }}</td>
|
||||
</tr>
|
||||
</ng-template>
|
||||
</bit-table>
|
||||
</span>
|
||||
<ng-container bitDialogFooter>
|
||||
<button type="button" bitButton buttonType="primary" [bitAction]="submit">
|
||||
{{ "enableAccess" | i18n }}
|
||||
</button>
|
||||
<button type="button" bitButton buttonType="secondary" bitDialogClose>
|
||||
{{ "close" | i18n }}
|
||||
</button>
|
||||
</ng-container>
|
||||
</bit-dialog>
|
@ -0,0 +1,53 @@
|
||||
import { DialogRef, DIALOG_DATA } from "@angular/cdk/dialog";
|
||||
import { Component, Inject, OnInit } from "@angular/core";
|
||||
|
||||
import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog";
|
||||
import { OrganizationUserService } from "@bitwarden/common/abstractions/organization-user/organization-user.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { TableDataSource } from "@bitwarden/components";
|
||||
|
||||
import { OrganizationUserView } from "../../../core";
|
||||
|
||||
export type BulkEnableSecretsManagerDialogData = {
|
||||
orgId: string;
|
||||
users: OrganizationUserView[];
|
||||
};
|
||||
|
||||
@Component({
|
||||
templateUrl: `bulk-enable-sm-dialog.component.html`,
|
||||
})
|
||||
export class BulkEnableSecretsManagerDialogComponent implements OnInit {
|
||||
protected dataSource = new TableDataSource<OrganizationUserView>();
|
||||
constructor(
|
||||
public dialogRef: DialogRef,
|
||||
@Inject(DIALOG_DATA) private data: BulkEnableSecretsManagerDialogData,
|
||||
private organizationUserService: OrganizationUserService,
|
||||
private platformUtilsService: PlatformUtilsService,
|
||||
private i18nService: I18nService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.dataSource.data = this.data.users;
|
||||
}
|
||||
|
||||
submit = async () => {
|
||||
await this.organizationUserService.putOrganizationUserBulkEnableSecretsManager(
|
||||
this.data.orgId,
|
||||
this.dataSource.data.map((u) => u.id)
|
||||
);
|
||||
this.platformUtilsService.showToast(
|
||||
"success",
|
||||
null,
|
||||
this.i18nService.t("enabledAccessToSecretsManager")
|
||||
);
|
||||
this.dialogRef.close();
|
||||
};
|
||||
|
||||
static open(dialogService: DialogServiceAbstraction, data: BulkEnableSecretsManagerDialogData) {
|
||||
return dialogService.open<unknown, BulkEnableSecretsManagerDialogData>(
|
||||
BulkEnableSecretsManagerDialogComponent,
|
||||
{ data }
|
||||
);
|
||||
}
|
||||
}
|
@ -255,7 +255,7 @@
|
||||
</ng-container>
|
||||
<ng-container *ngIf="canUseSecretsManager">
|
||||
<h3 class="mt-4">
|
||||
{{ "secretsManagerBeta" | i18n }}
|
||||
{{ "secretsManager" | i18n }}
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
@ -265,11 +265,11 @@
|
||||
<i class="bwi bwi-question-circle" aria-hidden="true"></i>
|
||||
</a>
|
||||
</h3>
|
||||
<p class="tw-text-muted">{{ "secretsManagerBetaDesc" | i18n }}</p>
|
||||
<p class="tw-text-muted">{{ "secretsManagerAccessDesc" | i18n }}</p>
|
||||
<bit-form-control>
|
||||
<input type="checkbox" bitCheckbox formControlName="accessSecretsManager" />
|
||||
<bit-label>
|
||||
{{ "userAccessSecretsManager" | i18n }}
|
||||
{{ "userAccessSecretsManagerGA" | i18n }}
|
||||
</bit-label>
|
||||
</bit-form-control>
|
||||
</ng-container>
|
||||
|
@ -4,6 +4,7 @@ import { LooseComponentsModule } from "../../../shared";
|
||||
import { SharedOrganizationModule } from "../shared";
|
||||
|
||||
import { BulkConfirmComponent } from "./components/bulk/bulk-confirm.component";
|
||||
import { BulkEnableSecretsManagerDialogComponent } from "./components/bulk/bulk-enable-sm-dialog.component";
|
||||
import { BulkRemoveComponent } from "./components/bulk/bulk-remove.component";
|
||||
import { BulkRestoreRevokeComponent } from "./components/bulk/bulk-restore-revoke.component";
|
||||
import { BulkStatusComponent } from "./components/bulk/bulk-status.component";
|
||||
@ -21,6 +22,7 @@ import { PeopleComponent } from "./people.component";
|
||||
],
|
||||
declarations: [
|
||||
BulkConfirmComponent,
|
||||
BulkEnableSecretsManagerDialogComponent,
|
||||
BulkRemoveComponent,
|
||||
BulkRestoreRevokeComponent,
|
||||
BulkStatusComponent,
|
||||
|
@ -99,6 +99,12 @@
|
||||
></button>
|
||||
|
||||
<bit-menu #headerMenu>
|
||||
<ng-container *ngIf="canUseSecretsManager$ | async">
|
||||
<button type="button" bitMenuItem (click)="bulkEnableSM()">
|
||||
{{ "enableSecretsManager" | i18n }}
|
||||
</button>
|
||||
<bit-menu-divider></bit-menu-divider>
|
||||
</ng-container>
|
||||
<button type="button" bitMenuItem (click)="bulkReinvite()">
|
||||
<i class="bwi bwi-fw bwi-envelope" aria-hidden="true"></i>
|
||||
{{ "reinviteSelected" | i18n }}
|
||||
|
@ -7,6 +7,7 @@ import {
|
||||
from,
|
||||
lastValueFrom,
|
||||
map,
|
||||
Observable,
|
||||
shareReplay,
|
||||
Subject,
|
||||
switchMap,
|
||||
@ -55,12 +56,14 @@ import { CollectionData } from "@bitwarden/common/vault/models/data/collection.d
|
||||
import { Collection } from "@bitwarden/common/vault/models/domain/collection";
|
||||
import { CollectionDetailsResponse } from "@bitwarden/common/vault/models/response/collection.response";
|
||||
|
||||
import { flagEnabled } from "../../../../utils/flags";
|
||||
import { openEntityEventsDialog } from "../../../admin-console/organizations/manage/entity-events.component";
|
||||
import { BasePeopleComponent } from "../../../common/base.people.component";
|
||||
import { GroupService } from "../core";
|
||||
import { OrganizationUserView } from "../core/views/organization-user.view";
|
||||
|
||||
import { BulkConfirmComponent } from "./components/bulk/bulk-confirm.component";
|
||||
import { BulkEnableSecretsManagerDialogComponent } from "./components/bulk/bulk-enable-sm-dialog.component";
|
||||
import { BulkRemoveComponent } from "./components/bulk/bulk-remove.component";
|
||||
import { BulkRestoreRevokeComponent } from "./components/bulk/bulk-restore-revoke.component";
|
||||
import { BulkStatusComponent } from "./components/bulk/bulk-status.component";
|
||||
@ -100,6 +103,7 @@ export class PeopleComponent
|
||||
status: OrganizationUserStatusType = null;
|
||||
orgResetPasswordPolicyEnabled = false;
|
||||
|
||||
protected canUseSecretsManager$: Observable<boolean>;
|
||||
private destroy$ = new Subject<void>();
|
||||
|
||||
constructor(
|
||||
@ -148,6 +152,10 @@ export class PeopleComponent
|
||||
shareReplay({ refCount: true, bufferSize: 1 })
|
||||
);
|
||||
|
||||
this.canUseSecretsManager$ = organization$.pipe(
|
||||
map((org) => org.useSecretsManager && flagEnabled("secretsManager"))
|
||||
);
|
||||
|
||||
const policies$ = organization$.pipe(
|
||||
switchMap((organization) => {
|
||||
if (organization.isProviderUser) {
|
||||
@ -511,6 +519,26 @@ export class PeopleComponent
|
||||
await this.load();
|
||||
}
|
||||
|
||||
async bulkEnableSM() {
|
||||
const users = this.getCheckedUsers();
|
||||
if (users.length === 0) {
|
||||
this.platformUtilsService.showToast(
|
||||
"error",
|
||||
this.i18nService.t("errorOccurred"),
|
||||
this.i18nService.t("noSelectedUsersApplicable")
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const dialogRef = BulkEnableSecretsManagerDialogComponent.open(this.dialogService, {
|
||||
orgId: this.organization.id,
|
||||
users,
|
||||
});
|
||||
|
||||
await lastValueFrom(dialogRef.closed);
|
||||
this.selectAll(false);
|
||||
}
|
||||
|
||||
async events(user: OrganizationUserView) {
|
||||
await openEntityEventsDialog(this.dialogService, {
|
||||
data: {
|
||||
|
@ -4,10 +4,10 @@ import { FormBuilder, FormControl, Validators } from "@angular/forms";
|
||||
import { combineLatest, Subject, takeUntil } from "rxjs";
|
||||
|
||||
import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog";
|
||||
import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction";
|
||||
import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction";
|
||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
@ -17,7 +17,7 @@ import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.servi
|
||||
import { CipherType } from "@bitwarden/common/vault/enums/cipher-type";
|
||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||
|
||||
import { UserVerificationModule } from "../../../../shared/components/user-verification";
|
||||
import { UserVerificationModule } from "../../../../auth/shared/components/user-verification";
|
||||
import { SharedModule } from "../../../../shared/shared.module";
|
||||
|
||||
class CountBasedLocalizationKey {
|
||||
|
@ -3,10 +3,9 @@ import { UntypedFormBuilder } from "@angular/forms";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
|
||||
import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog";
|
||||
import { ModalService } from "@bitwarden/angular/services/modal.service";
|
||||
import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service";
|
||||
import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction";
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||
import { EventType } from "@bitwarden/common/enums";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service";
|
||||
@ -35,7 +34,6 @@ export class OrganizationExportComponent extends ExportComponent {
|
||||
userVerificationService: UserVerificationService,
|
||||
formBuilder: UntypedFormBuilder,
|
||||
fileDownloadService: FileDownloadService,
|
||||
modalService: ModalService,
|
||||
dialogService: DialogServiceAbstraction
|
||||
) {
|
||||
super(
|
||||
@ -49,7 +47,6 @@ export class OrganizationExportComponent extends ExportComponent {
|
||||
userVerificationService,
|
||||
formBuilder,
|
||||
fileDownloadService,
|
||||
modalService,
|
||||
dialogService
|
||||
);
|
||||
}
|
||||
|
@ -4,9 +4,9 @@ import { ModalRef } from "@bitwarden/angular/components/modal/modal.ref";
|
||||
import { ModalConfig } from "@bitwarden/angular/services/modal.service";
|
||||
import { OrganizationUserService } from "@bitwarden/common/abstractions/organization-user/organization-user.service";
|
||||
import { OrganizationUserResetPasswordEnrollmentRequest } from "@bitwarden/common/abstractions/organization-user/requests";
|
||||
import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction";
|
||||
import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction";
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { ScrollingModule } from "@angular/cdk/scrolling";
|
||||
import { NgModule } from "@angular/core";
|
||||
|
||||
import { UserVerificationModule } from "../../../auth/shared/components/user-verification";
|
||||
import { LooseComponentsModule, SharedModule } from "../../../shared";
|
||||
import { UserVerificationModule } from "../../../shared/components/user-verification";
|
||||
|
||||
import { EnrollMasterPasswordReset } from "./enroll-master-password-reset.component";
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Component } from "@angular/core";
|
||||
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction";
|
||||
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
|
@ -2,7 +2,7 @@ import { Component, OnDestroy, OnInit } from "@angular/core";
|
||||
|
||||
import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction";
|
||||
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||
import { UpdateTwoFactorAuthenticatorRequest } from "@bitwarden/common/auth/models/request/update-two-factor-authenticator.request";
|
||||
import { TwoFactorAuthenticatorResponse } from "@bitwarden/common/auth/models/response/two-factor-authenticator.response";
|
||||
|
@ -2,7 +2,7 @@ import { Directive, EventEmitter, Output } from "@angular/core";
|
||||
|
||||
import { DialogServiceAbstraction, SimpleDialogType } from "@bitwarden/angular/services/dialog";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction";
|
||||
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||
import { VerificationType } from "@bitwarden/common/auth/enums/verification-type";
|
||||
import { SecretVerificationRequest } from "@bitwarden/common/auth/models/request/secret-verification.request";
|
||||
|
@ -2,7 +2,7 @@ import { Component } from "@angular/core";
|
||||
|
||||
import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction";
|
||||
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||
import { UpdateTwoFactorDuoRequest } from "@bitwarden/common/auth/models/request/update-two-factor-duo.request";
|
||||
import { TwoFactorDuoResponse } from "@bitwarden/common/auth/models/response/two-factor-duo.response";
|
||||
|
@ -2,7 +2,7 @@ import { Component } from "@angular/core";
|
||||
|
||||
import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction";
|
||||
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||
import { TwoFactorEmailRequest } from "@bitwarden/common/auth/models/request/two-factor-email.request";
|
||||
import { UpdateTwoFactorEmailRequest } from "@bitwarden/common/auth/models/request/update-two-factor-email.request";
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Component, EventEmitter, Input, Output } from "@angular/core";
|
||||
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction";
|
||||
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||
import { VerificationType } from "@bitwarden/common/auth/enums/verification-type";
|
||||
import { SecretVerificationRequest } from "@bitwarden/common/auth/models/request/secret-verification.request";
|
||||
|
@ -2,7 +2,7 @@ import { Component, NgZone } from "@angular/core";
|
||||
|
||||
import { DialogServiceAbstraction, SimpleDialogType } from "@bitwarden/angular/services/dialog";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction";
|
||||
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||
import { SecretVerificationRequest } from "@bitwarden/common/auth/models/request/secret-verification.request";
|
||||
import { UpdateTwoFactorWebAuthnDeleteRequest } from "@bitwarden/common/auth/models/request/update-two-factor-web-authn-delete.request";
|
||||
|
@ -2,7 +2,7 @@ import { Component } from "@angular/core";
|
||||
|
||||
import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction";
|
||||
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||
import { UpdateTwoFactorYubioOtpRequest } from "@bitwarden/common/auth/models/request/update-two-factor-yubio-otp.request";
|
||||
import { TwoFactorYubiKeyResponse } from "@bitwarden/common/auth/models/response/two-factor-yubi-key.response";
|
||||
|
@ -1,3 +1,3 @@
|
||||
export * from "./user-verification.module";
|
||||
export * from "./user-verification-prompt.component";
|
||||
export * from "./user-verification.component";
|
||||
export * from "./user-verification-prompt.component";
|
@ -0,0 +1,20 @@
|
||||
<form [formGroup]="formGroup" [bitSubmit]="submit">
|
||||
<bit-dialog>
|
||||
<span bitDialogTitle>{{ modalTitle | i18n }}</span>
|
||||
<ng-container bitDialogContent>
|
||||
<p bitTypography="body1">{{ confirmDescription | i18n }}</p>
|
||||
<app-user-verification
|
||||
[(invalidSecret)]="invalidSecret"
|
||||
formControlName="secret"
|
||||
></app-user-verification>
|
||||
</ng-container>
|
||||
<ng-container bitDialogFooter>
|
||||
<button type="submit" bitButton bitFormButton buttonType="primary">
|
||||
{{ confirmButtonText | i18n }}
|
||||
</button>
|
||||
<button type="button" bitButton bitFormButton buttonType="secondary" bitDialogClose>
|
||||
{{ "cancel" | i18n }}
|
||||
</button>
|
||||
</ng-container>
|
||||
</bit-dialog>
|
||||
</form>
|
@ -0,0 +1,60 @@
|
||||
import { DialogConfig, DialogRef, DIALOG_DATA } from "@angular/cdk/dialog";
|
||||
import { Component, Inject } from "@angular/core";
|
||||
import { FormBuilder } from "@angular/forms";
|
||||
|
||||
import { UserVerificationPromptComponent as BaseUserVerificationPrompt } from "@bitwarden/angular/auth/components/user-verification-prompt.component";
|
||||
import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog";
|
||||
import { ModalConfig } from "@bitwarden/angular/services/modal.service";
|
||||
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
|
||||
export interface UserVerificationPromptParams {
|
||||
confirmDescription: string;
|
||||
confirmButtonText: string;
|
||||
modalTitle: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
templateUrl: "user-verification-prompt.component.html",
|
||||
})
|
||||
export class UserVerificationPromptComponent extends BaseUserVerificationPrompt {
|
||||
constructor(
|
||||
@Inject(DIALOG_DATA) data: UserVerificationPromptParams,
|
||||
private dialogRef: DialogRef<boolean>,
|
||||
userVerificationService: UserVerificationService,
|
||||
formBuilder: FormBuilder,
|
||||
platformUtilsService: PlatformUtilsService,
|
||||
i18nService: I18nService
|
||||
) {
|
||||
// TODO: Remove when BaseUserVerificationPrompt has support for CL
|
||||
const modalConfig: ModalConfig = { data };
|
||||
super(
|
||||
null,
|
||||
modalConfig,
|
||||
userVerificationService,
|
||||
formBuilder,
|
||||
platformUtilsService,
|
||||
i18nService
|
||||
);
|
||||
}
|
||||
|
||||
override close(success: boolean) {
|
||||
this.dialogRef.close(success);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Strongly typed helper to open a UserVerificationPrompt
|
||||
* @param dialogService Instance of the dialog service that will be used to open the dialog
|
||||
* @param config Configuration for the dialog
|
||||
*/
|
||||
export const openUserVerificationPrompt = (
|
||||
dialogService: DialogServiceAbstraction,
|
||||
config: DialogConfig<UserVerificationPromptParams>
|
||||
) => {
|
||||
return dialogService.open<boolean, UserVerificationPromptParams>(
|
||||
UserVerificationPromptComponent,
|
||||
config
|
||||
);
|
||||
};
|
@ -0,0 +1,41 @@
|
||||
<ng-container *ngIf="!usesKeyConnector">
|
||||
<bit-form-field disableMargin>
|
||||
<bit-label>{{ "masterPass" | i18n }}</bit-label>
|
||||
<input
|
||||
bitInput
|
||||
id="masterPassword"
|
||||
type="password"
|
||||
name="MasterPasswordHash"
|
||||
[formControl]="secret"
|
||||
appAutofocus
|
||||
appInputVerbatim
|
||||
/>
|
||||
<button type="button" bitIconButton bitSuffix bitPasswordInputToggle></button>
|
||||
<bit-hint>{{ "confirmIdentity" | i18n }}</bit-hint>
|
||||
</bit-form-field>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="usesKeyConnector">
|
||||
<div class="tw-mb-6">
|
||||
<label class="tw-block">{{ "sendVerificationCode" | i18n }}</label>
|
||||
<button type="button" bitButton buttonType="secondary" [bitAction]="requestOTP" appAutofocus>
|
||||
{{ "sendCode" | i18n }}
|
||||
</button>
|
||||
<span class="tw-ml-2 tw-text-success" role="alert" @sent *ngIf="sentCode">
|
||||
<i class="bwi bwi-check-circle" aria-hidden="true"></i>
|
||||
{{ "codeSent" | i18n }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<bit-form-field disableMargin>
|
||||
<bit-label>{{ "verificationCode" | i18n }}</bit-label>
|
||||
<input
|
||||
bitInput
|
||||
type="text"
|
||||
id="verificationCode"
|
||||
name="verificationCode"
|
||||
[formControl]="secret"
|
||||
appInputVerbatim
|
||||
/>
|
||||
<bit-hint>{{ "confirmIdentity" | i18n }}</bit-hint>
|
||||
</bit-form-field>
|
||||
</ng-container>
|
@ -1,12 +1,13 @@
|
||||
import { NgModule } from "@angular/core";
|
||||
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
|
||||
|
||||
import { SharedModule } from "../../shared.module";
|
||||
import { SharedModule } from "../../../../shared/shared.module";
|
||||
|
||||
import { UserVerificationPromptComponent } from "./user-verification-prompt.component";
|
||||
import { UserVerificationComponent } from "./user-verification.component";
|
||||
|
||||
@NgModule({
|
||||
imports: [SharedModule],
|
||||
imports: [SharedModule, FormsModule, ReactiveFormsModule],
|
||||
declarations: [UserVerificationComponent, UserVerificationPromptComponent],
|
||||
exports: [UserVerificationComponent, UserVerificationPromptComponent],
|
||||
})
|
@ -4,8 +4,8 @@ import { Router } from "@angular/router";
|
||||
import { UpdatePasswordComponent as BaseUpdatePasswordComponent } from "@bitwarden/angular/auth/components/update-password.component";
|
||||
import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction";
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
|
@ -2,10 +2,10 @@ import { Component } from "@angular/core";
|
||||
|
||||
import { ModalConfig } from "@bitwarden/angular/services/modal.service";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction";
|
||||
import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction";
|
||||
import { OrganizationApiKeyType } from "@bitwarden/common/admin-console/enums";
|
||||
import { OrganizationApiKeyRequest } from "@bitwarden/common/admin-console/models/request/organization-api-key.request";
|
||||
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||
import { ApiKeyResponse } from "@bitwarden/common/auth/models/response/api-key.response";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { NgModule } from "@angular/core";
|
||||
|
||||
import { UserVerificationModule } from "../../auth/shared/components/user-verification";
|
||||
import { LooseComponentsModule, SharedModule } from "../../shared";
|
||||
import { UserVerificationModule } from "../../shared/components/user-verification";
|
||||
|
||||
import { AdjustSubscription } from "./adjust-subscription.component";
|
||||
import { BillingSyncApiKeyComponent } from "./billing-sync-api-key.component";
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Component } from "@angular/core";
|
||||
|
||||
import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction";
|
||||
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||
import { SecretVerificationRequest } from "@bitwarden/common/auth/models/request/secret-verification.request";
|
||||
import { ApiKeyResponse } from "@bitwarden/common/auth/models/response/api-key.response";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
|
@ -2,7 +2,7 @@ import { Component, Input } from "@angular/core";
|
||||
import { Router } from "@angular/router";
|
||||
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction";
|
||||
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
|
@ -1,26 +0,0 @@
|
||||
<div class="modal fade" role="dialog" aria-modal="true" aria-labelledby="confirmUserTitle">
|
||||
<div class="modal-dialog modal-dialog-scrollable" role="document">
|
||||
<form class="modal-content" #form (ngSubmit)="submit()">
|
||||
<h2 class="tw-my-6 tw-px-3.5 tw-font-semibold" id="modalTitle | i18n ">
|
||||
{{ modalTitle | i18n | uppercase }}
|
||||
</h2>
|
||||
<div class="tw-border-0 tw-border-t tw-border-solid tw-border-secondary-300 tw-p-3.5">
|
||||
{{ confirmDescription | i18n }}
|
||||
</div>
|
||||
<div class="tw-p-3.5">
|
||||
<app-user-verification ngDefaultControl [formControl]="secret" name="secret">
|
||||
</app-user-verification>
|
||||
</div>
|
||||
<div
|
||||
class="tw-border-0 tw-border-t tw-border-solid tw-border-secondary-300 tw-bg-background-alt tw-p-3.5"
|
||||
>
|
||||
<button type="button" bitButton buttonType="primary" type="submit" appBlurClick>
|
||||
<span>{{ confirmButtonText | i18n }}</span>
|
||||
</button>
|
||||
<button type="button" bitButton buttonType="secondary" data-dismiss="modal">
|
||||
{{ "cancel" | i18n }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
@ -1,8 +0,0 @@
|
||||
import { Component } from "@angular/core";
|
||||
|
||||
import { UserVerificationPromptComponent as BaseUserVerificationPrompt } from "@bitwarden/angular/auth/components/user-verification-prompt.component";
|
||||
|
||||
@Component({
|
||||
templateUrl: "user-verification-prompt.component.html",
|
||||
})
|
||||
export class UserVerificationPromptComponent extends BaseUserVerificationPrompt {}
|
@ -1,46 +0,0 @@
|
||||
<ng-container *ngIf="!usesKeyConnector">
|
||||
<label for="masterPassword">{{ "masterPass" | i18n }}</label>
|
||||
<input
|
||||
id="masterPassword"
|
||||
type="password"
|
||||
name="MasterPasswordHash"
|
||||
class="form-control"
|
||||
[formControl]="secret"
|
||||
required
|
||||
appAutofocus
|
||||
appInputVerbatim
|
||||
/>
|
||||
<small class="form-text text-muted">{{ "confirmIdentity" | i18n }}</small>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="usesKeyConnector">
|
||||
<div class="form-group">
|
||||
<label class="d-block">{{ "sendVerificationCode" | i18n }}</label>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-outline-secondary"
|
||||
(click)="requestOTP()"
|
||||
[disabled]="disableRequestOTP"
|
||||
>
|
||||
{{ "sendCode" | i18n }}
|
||||
</button>
|
||||
<span class="ml-2 text-success" role="alert" @sent *ngIf="sentCode">
|
||||
<i class="bwi bwi-check-circle" aria-hidden="true"></i>
|
||||
{{ "codeSent" | i18n }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="verificationCode">{{ "verificationCode" | i18n }}</label>
|
||||
<input
|
||||
id="verificationCode"
|
||||
type="input"
|
||||
name="verificationCode"
|
||||
class="form-control"
|
||||
[formControl]="secret"
|
||||
required
|
||||
appAutofocus
|
||||
appInputVerbatim
|
||||
/>
|
||||
<small class="form-text text-muted">{{ "confirmIdentity" | i18n }}</small>
|
||||
</div>
|
||||
</ng-container>
|
@ -43,6 +43,7 @@ import { TwoFactorVerifyComponent } from "../auth/settings/two-factor-verify.com
|
||||
import { TwoFactorWebAuthnComponent } from "../auth/settings/two-factor-webauthn.component";
|
||||
import { TwoFactorYubiKeyComponent } from "../auth/settings/two-factor-yubikey.component";
|
||||
import { VerifyEmailComponent } from "../auth/settings/verify-email.component";
|
||||
import { UserVerificationModule } from "../auth/shared/components/user-verification";
|
||||
import { SsoComponent } from "../auth/sso.component";
|
||||
import { TwoFactorOptionsComponent } from "../auth/two-factor-options.component";
|
||||
import { TwoFactorComponent } from "../auth/two-factor.component";
|
||||
@ -108,7 +109,6 @@ import { AttachmentsComponent as OrgAttachmentsComponent } from "../vault/org-va
|
||||
import { CollectionsComponent as OrgCollectionsComponent } from "../vault/org-vault/collections.component";
|
||||
|
||||
import { AccountFingerprintComponent } from "./components/account-fingerprint/account-fingerprint.component";
|
||||
import { UserVerificationModule } from "./components/user-verification";
|
||||
import { SharedModule } from "./shared.module";
|
||||
|
||||
// Please do not add to this list of declarations - we should refactor these into modules when doing so makes sense until there are none left.
|
||||
@ -230,6 +230,7 @@ import { SharedModule } from "./shared.module";
|
||||
LowKdfComponent,
|
||||
],
|
||||
exports: [
|
||||
UserVerificationModule,
|
||||
PremiumBadgeComponent,
|
||||
AcceptEmergencyComponent,
|
||||
AcceptOrganizationComponent,
|
||||
|
@ -1,45 +1,32 @@
|
||||
<!-- Please remove this disable statement when editing this file! -->
|
||||
<!-- eslint-disable tailwindcss/no-custom-classname -->
|
||||
<div
|
||||
class="modal fade"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
[attr.aria-labelledby]="'confirmVaultImport' | i18n"
|
||||
>
|
||||
<div class="modal-dialog modal-dialog-scrollable" role="document">
|
||||
<form #form (ngSubmit)="submit()">
|
||||
<div class="form-group modal-content">
|
||||
<h2 class="tw-my-6 tw-ml-3.5 tw-font-semibold" id="confirmVaultImport">
|
||||
{{ "confirmVaultImport" | i18n | uppercase }}
|
||||
</h2>
|
||||
<div
|
||||
class="tw-border-0 tw-border-t tw-border-solid tw-border-secondary-300 tw-px-3.5 tw-pt-3.5"
|
||||
>
|
||||
{{ "confirmVaultImportDesc" | i18n }}
|
||||
<bit-form-field class="tw-pt-3.5">
|
||||
<bit-label>{{ "confirmFilePassword" | i18n }}</bit-label>
|
||||
<input
|
||||
bitInput
|
||||
type="password"
|
||||
name="filePassword"
|
||||
[formControl]="filePassword"
|
||||
appAutofocus
|
||||
appInputVerbatim
|
||||
/>
|
||||
<button type="button" bitSuffix bitIconButton bitPasswordInputToggle></button>
|
||||
</bit-form-field>
|
||||
</div>
|
||||
<div
|
||||
class="tw-flex tw-w-full tw-flex-wrap tw-items-center tw-border-0 tw-border-t tw-border-solid tw-border-secondary-300 tw-bg-background-alt tw-px-3.5 tw-pb-3.5 tw-pt-4"
|
||||
>
|
||||
<button bitButton buttonType="primary" class="tw-mr-2" type="submit" appBlurClick>
|
||||
<span>{{ "importData" | i18n }}</span>
|
||||
</button>
|
||||
<button bitButton buttonType="secondary" type="button" (click)="cancel()">
|
||||
<span>{{ "cancel" | i18n }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<form (submit)="submit()">
|
||||
<bit-dialog>
|
||||
<span bitDialogTitle>
|
||||
{{ "confirmVaultImport" | i18n }}
|
||||
</span>
|
||||
|
||||
<div bitDialogContent>
|
||||
{{ "confirmVaultImportDesc" | i18n }}
|
||||
<bit-form-field class="tw-mt-6">
|
||||
<bit-label>{{ "confirmFilePassword" | i18n }}</bit-label>
|
||||
<input
|
||||
bitInput
|
||||
type="password"
|
||||
name="filePassword"
|
||||
[formControl]="filePassword"
|
||||
appAutofocus
|
||||
appInputVerbatim
|
||||
/>
|
||||
<button type="button" bitSuffix bitIconButton bitPasswordInputToggle></button>
|
||||
</bit-form-field>
|
||||
</div>
|
||||
|
||||
<ng-container bitDialogFooter>
|
||||
<button bitButton buttonType="primary" type="submit">
|
||||
<span>{{ "importData" | i18n }}</span>
|
||||
</button>
|
||||
<button bitButton bitDialogClose buttonType="secondary" type="button">
|
||||
<span>{{ "cancel" | i18n }}</span>
|
||||
</button>
|
||||
</ng-container>
|
||||
</bit-dialog>
|
||||
</form>
|
||||
|
@ -1,26 +1,20 @@
|
||||
import { DialogRef } from "@angular/cdk/dialog";
|
||||
import { Component } from "@angular/core";
|
||||
import { FormControl, Validators } from "@angular/forms";
|
||||
|
||||
import { ModalRef } from "@bitwarden/angular/components/modal/modal.ref";
|
||||
|
||||
@Component({
|
||||
templateUrl: "file-password-prompt.component.html",
|
||||
})
|
||||
export class FilePasswordPromptComponent {
|
||||
filePassword = new FormControl("", Validators.required);
|
||||
|
||||
constructor(private modalRef: ModalRef) {}
|
||||
constructor(public dialogRef: DialogRef) {}
|
||||
|
||||
submit() {
|
||||
this.filePassword.markAsTouched();
|
||||
if (!this.filePassword.valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.modalRef.close(this.filePassword.value);
|
||||
}
|
||||
|
||||
cancel() {
|
||||
this.modalRef.close(null);
|
||||
this.dialogRef.close(this.filePassword.value);
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { Component } from "@angular/core";
|
||||
import { UntypedFormBuilder } from "@angular/forms";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog";
|
||||
import { ModalService } from "@bitwarden/angular/services/modal.service";
|
||||
import { ExportComponent as BaseExportComponent } from "@bitwarden/angular/tools/export/components/export.component";
|
||||
import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service";
|
||||
import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction";
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||
import { EncryptedExportType } from "@bitwarden/common/enums";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service";
|
||||
@ -15,7 +15,7 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service"
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { VaultExportServiceAbstraction } from "@bitwarden/exporter/vault-export";
|
||||
|
||||
import { UserVerificationPromptComponent } from "../../shared/components/user-verification";
|
||||
import { openUserVerificationPrompt } from "../../auth/shared/components/user-verification";
|
||||
|
||||
@Component({
|
||||
selector: "app-export",
|
||||
@ -37,7 +37,6 @@ export class ExportComponent extends BaseExportComponent {
|
||||
userVerificationService: UserVerificationService,
|
||||
formBuilder: UntypedFormBuilder,
|
||||
fileDownloadService: FileDownloadService,
|
||||
private modalService: ModalService,
|
||||
dialogService: DialogServiceAbstraction
|
||||
) {
|
||||
super(
|
||||
@ -101,8 +100,7 @@ export class ExportComponent extends BaseExportComponent {
|
||||
confirmDescription = "encExportKeyWarningDesc";
|
||||
}
|
||||
|
||||
const ref = this.modalService.open(UserVerificationPromptComponent, {
|
||||
allowMultipleModals: true,
|
||||
const ref = openUserVerificationPrompt(this.dialogService, {
|
||||
data: {
|
||||
confirmDescription: confirmDescription,
|
||||
confirmButtonText: "exportVault",
|
||||
@ -114,7 +112,7 @@ export class ExportComponent extends BaseExportComponent {
|
||||
return;
|
||||
}
|
||||
|
||||
return ref.onClosedPromise();
|
||||
return firstValueFrom(ref.closed);
|
||||
}
|
||||
|
||||
get isFileEncryptedExport() {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Component, OnDestroy, OnInit } from "@angular/core";
|
||||
import { Router } from "@angular/router";
|
||||
import * as JSZip from "jszip";
|
||||
import { Subject } from "rxjs";
|
||||
import { Subject, lastValueFrom } from "rxjs";
|
||||
import { takeUntil } from "rxjs/operators";
|
||||
import Swal, { SweetAlertIcon } from "sweetalert2";
|
||||
|
||||
@ -270,15 +270,11 @@ export class ImportComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
async getFilePassword(): Promise<string> {
|
||||
const ref = this.modalService.open(FilePasswordPromptComponent, {
|
||||
allowMultipleModals: true,
|
||||
const dialog = this.dialogService.open<string>(FilePasswordPromptComponent, {
|
||||
ariaModal: true,
|
||||
});
|
||||
|
||||
if (ref == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return await ref.onClosedPromise();
|
||||
return await lastValueFrom(dialog.closed);
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
|
@ -22,6 +22,19 @@
|
||||
<input bitInput appAutofocus formControlName="name" />
|
||||
</bit-form-field>
|
||||
|
||||
<bit-form-field *ngIf="showOrgSelector">
|
||||
<bit-label>{{ "organization" | i18n }}</bit-label>
|
||||
<bit-select bitInput formControlName="selectedOrg">
|
||||
<bit-option
|
||||
*ngFor="let org of organizations$ | async"
|
||||
icon="bwi-business"
|
||||
[value]="org.id"
|
||||
[label]="org.name"
|
||||
>
|
||||
</bit-option>
|
||||
</bit-select>
|
||||
</bit-form-field>
|
||||
|
||||
<bit-form-field>
|
||||
<bit-label>{{ "externalId" | i18n }}</bit-label>
|
||||
<input bitInput formControlName="externalId" />
|
||||
|
@ -1,7 +1,16 @@
|
||||
import { DIALOG_DATA, DialogConfig, DialogRef } from "@angular/cdk/dialog";
|
||||
import { Component, Inject, OnDestroy, OnInit } from "@angular/core";
|
||||
import { FormBuilder, Validators } from "@angular/forms";
|
||||
import { combineLatest, of, shareReplay, Subject, switchMap, takeUntil } from "rxjs";
|
||||
import {
|
||||
combineLatest,
|
||||
map,
|
||||
Observable,
|
||||
of,
|
||||
shareReplay,
|
||||
Subject,
|
||||
switchMap,
|
||||
takeUntil,
|
||||
} from "rxjs";
|
||||
|
||||
import { DialogServiceAbstraction, SimpleDialogType } from "@bitwarden/angular/services/dialog";
|
||||
import { OrganizationUserService } from "@bitwarden/common/abstractions/organization-user/organization-user.service";
|
||||
@ -10,6 +19,8 @@ import { OrganizationService } from "@bitwarden/common/admin-console/abstraction
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { CollectionResponse } from "@bitwarden/common/vault/models/response/collection.response";
|
||||
import { CollectionView } from "@bitwarden/common/vault/models/view/collection.view";
|
||||
import { BitValidators } from "@bitwarden/components";
|
||||
|
||||
@ -35,9 +46,16 @@ export interface CollectionDialogParams {
|
||||
organizationId: string;
|
||||
initialTab?: CollectionDialogTabType;
|
||||
parentCollectionId?: string;
|
||||
showOrgSelector?: boolean;
|
||||
collectionIds?: string[];
|
||||
}
|
||||
|
||||
export enum CollectionDialogResult {
|
||||
export interface CollectionDialogResult {
|
||||
action: CollectionDialogAction;
|
||||
collection: CollectionResponse;
|
||||
}
|
||||
|
||||
export enum CollectionDialogAction {
|
||||
Saved = "saved",
|
||||
Canceled = "canceled",
|
||||
Deleted = "deleted",
|
||||
@ -48,6 +66,7 @@ export enum CollectionDialogResult {
|
||||
})
|
||||
export class CollectionDialogComponent implements OnInit, OnDestroy {
|
||||
private destroy$ = new Subject<void>();
|
||||
protected organizations$: Observable<Organization[]>;
|
||||
|
||||
protected tabIndex: CollectionDialogTabType;
|
||||
protected loading = true;
|
||||
@ -56,11 +75,13 @@ export class CollectionDialogComponent implements OnInit, OnDestroy {
|
||||
protected nestOptions: CollectionView[] = [];
|
||||
protected accessItems: AccessItemView[] = [];
|
||||
protected deletedParentName: string | undefined;
|
||||
protected showOrgSelector = false;
|
||||
protected formGroup = this.formBuilder.group({
|
||||
name: ["", [Validators.required, BitValidators.forbiddenCharacters(["/"])]],
|
||||
externalId: "",
|
||||
parent: undefined as string | undefined,
|
||||
access: [[] as AccessItemValue[]],
|
||||
selectedOrg: "",
|
||||
});
|
||||
protected PermissionMode = PermissionMode;
|
||||
|
||||
@ -79,8 +100,31 @@ export class CollectionDialogComponent implements OnInit, OnDestroy {
|
||||
this.tabIndex = params.initialTab ?? CollectionDialogTabType.Info;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
const organization$ = of(this.organizationService.get(this.params.organizationId)).pipe(
|
||||
async ngOnInit() {
|
||||
// Opened from the individual vault
|
||||
if (this.params.showOrgSelector) {
|
||||
this.showOrgSelector = true;
|
||||
this.formGroup.controls.selectedOrg.valueChanges
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe((id) => this.loadOrg(id, this.params.collectionIds));
|
||||
this.organizations$ = this.organizationService.organizations$.pipe(
|
||||
map((orgs) =>
|
||||
orgs
|
||||
.filter((o) => o.canCreateNewCollections)
|
||||
.sort(Utils.getSortFunction(this.i18nService, "name"))
|
||||
)
|
||||
);
|
||||
// patchValue will trigger a call to loadOrg() in this case, so no need to call it again here
|
||||
this.formGroup.patchValue({ selectedOrg: this.params.organizationId });
|
||||
} else {
|
||||
// Opened from the org vault
|
||||
this.formGroup.patchValue({ selectedOrg: this.params.organizationId });
|
||||
this.loadOrg(this.params.organizationId, this.params.collectionIds);
|
||||
}
|
||||
}
|
||||
|
||||
async loadOrg(orgId: string, collectionIds: string[]) {
|
||||
const organization$ = of(this.organizationService.get(orgId)).pipe(
|
||||
shareReplay({ refCount: true, bufferSize: 1 })
|
||||
);
|
||||
const groups$ = organization$.pipe(
|
||||
@ -89,20 +133,19 @@ export class CollectionDialogComponent implements OnInit, OnDestroy {
|
||||
return of([] as GroupView[]);
|
||||
}
|
||||
|
||||
return this.groupService.getAll(this.params.organizationId);
|
||||
return this.groupService.getAll(orgId);
|
||||
})
|
||||
);
|
||||
|
||||
combineLatest({
|
||||
organization: organization$,
|
||||
collections: this.collectionService.getAll(this.params.organizationId),
|
||||
collections: this.collectionService.getAll(orgId),
|
||||
collectionDetails: this.params.collectionId
|
||||
? this.collectionService.get(this.params.organizationId, this.params.collectionId)
|
||||
? this.collectionService.get(orgId, this.params.collectionId)
|
||||
: of(null),
|
||||
groups: groups$,
|
||||
users: this.organizationUserService.getAllUsers(this.params.organizationId),
|
||||
users: this.organizationUserService.getAllUsers(orgId),
|
||||
})
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.pipe(takeUntil(this.formGroup.controls.selectedOrg.valueChanges), takeUntil(this.destroy$))
|
||||
.subscribe(({ organization, collections, collectionDetails, groups, users }) => {
|
||||
this.organization = organization;
|
||||
this.accessItems = [].concat(
|
||||
@ -110,6 +153,10 @@ export class CollectionDialogComponent implements OnInit, OnDestroy {
|
||||
users.data.map(mapUserToAccessItemView)
|
||||
);
|
||||
|
||||
if (collectionIds) {
|
||||
collections = collections.filter((c) => collectionIds.includes(c.id));
|
||||
}
|
||||
|
||||
if (this.params.collectionId) {
|
||||
this.collection = collections.find((c) => c.id === this.collectionId);
|
||||
this.nestOptions = collections.filter((c) => c.id !== this.collectionId);
|
||||
@ -149,7 +196,7 @@ export class CollectionDialogComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
protected async cancel() {
|
||||
this.close(CollectionDialogResult.Canceled);
|
||||
this.close(CollectionDialogAction.Canceled);
|
||||
}
|
||||
|
||||
protected submit = async () => {
|
||||
@ -168,7 +215,7 @@ export class CollectionDialogComponent implements OnInit, OnDestroy {
|
||||
|
||||
const collectionView = new CollectionAdminView();
|
||||
collectionView.id = this.params.collectionId;
|
||||
collectionView.organizationId = this.params.organizationId;
|
||||
collectionView.organizationId = this.formGroup.controls.selectedOrg.value;
|
||||
collectionView.externalId = this.formGroup.controls.externalId.value;
|
||||
collectionView.groups = this.formGroup.controls.access.value
|
||||
.filter((v) => v.type === AccessItemType.Group)
|
||||
@ -184,7 +231,7 @@ export class CollectionDialogComponent implements OnInit, OnDestroy {
|
||||
collectionView.name = this.formGroup.controls.name.value;
|
||||
}
|
||||
|
||||
await this.collectionService.save(collectionView);
|
||||
const savedCollection = await this.collectionService.save(collectionView);
|
||||
|
||||
this.platformUtilsService.showToast(
|
||||
"success",
|
||||
@ -195,7 +242,7 @@ export class CollectionDialogComponent implements OnInit, OnDestroy {
|
||||
)
|
||||
);
|
||||
|
||||
this.close(CollectionDialogResult.Saved);
|
||||
this.close(CollectionDialogAction.Saved, savedCollection);
|
||||
};
|
||||
|
||||
protected delete = async () => {
|
||||
@ -217,7 +264,7 @@ export class CollectionDialogComponent implements OnInit, OnDestroy {
|
||||
this.i18nService.t("deletedCollectionId", this.collection?.name)
|
||||
);
|
||||
|
||||
this.close(CollectionDialogResult.Deleted);
|
||||
this.close(CollectionDialogAction.Deleted);
|
||||
};
|
||||
|
||||
ngOnDestroy(): void {
|
||||
@ -225,8 +272,8 @@ export class CollectionDialogComponent implements OnInit, OnDestroy {
|
||||
this.destroy$.complete();
|
||||
}
|
||||
|
||||
private close(result: CollectionDialogResult) {
|
||||
this.dialogRef.close(result);
|
||||
private close(action: CollectionDialogAction, collection?: CollectionResponse) {
|
||||
this.dialogRef.close({ action, collection } as CollectionDialogResult);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ export class CollectionAdminService {
|
||||
return view;
|
||||
}
|
||||
|
||||
async save(collection: CollectionAdminView): Promise<unknown> {
|
||||
async save(collection: CollectionAdminView): Promise<CollectionResponse> {
|
||||
const request = await this.encrypt(collection);
|
||||
|
||||
let response: CollectionResponse;
|
||||
@ -61,9 +61,7 @@ export class CollectionAdminService {
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: Implement upsert when in PS-1083: Collection Service refactors
|
||||
// await this.collectionService.upsert(data);
|
||||
return;
|
||||
return response;
|
||||
}
|
||||
|
||||
async delete(organizationId: string, collectionId: string): Promise<void> {
|
||||
|
@ -32,7 +32,6 @@ import { OrganizationOptionsComponent } from "./organization-options.component";
|
||||
export class VaultFilterComponent implements OnInit, OnDestroy {
|
||||
filters?: VaultFilterList;
|
||||
@Input() activeFilter: VaultFilter = new VaultFilter();
|
||||
@Output() onAddFolder = new EventEmitter<never>();
|
||||
@Output() onEditFolder = new EventEmitter<FolderFilter>();
|
||||
|
||||
@Input() searchText = "";
|
||||
@ -142,10 +141,6 @@ export class VaultFilterComponent implements OnInit, OnDestroy {
|
||||
filter.selectedCollectionNode = collectionNode;
|
||||
};
|
||||
|
||||
addFolder = async (): Promise<void> => {
|
||||
this.onAddFolder.emit();
|
||||
};
|
||||
|
||||
editFolder = async (folder: FolderFilter): Promise<void> => {
|
||||
this.onEditFolder.emit(folder);
|
||||
};
|
||||
@ -249,10 +244,6 @@ export class VaultFilterComponent implements OnInit, OnDestroy {
|
||||
text: "editFolder",
|
||||
action: this.editFolder,
|
||||
},
|
||||
add: {
|
||||
text: "Add Folder",
|
||||
action: this.addFolder,
|
||||
},
|
||||
};
|
||||
return folderFilterSection;
|
||||
}
|
||||
|
@ -34,16 +34,6 @@
|
||||
<h3 *ngIf="!headerInfo.isSelectable" class="filter-title">
|
||||
{{ headerNode.node.name | i18n }}
|
||||
</h3>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
*ngIf="showAddButton"
|
||||
(click)="onAdd()"
|
||||
class="text-muted ml-auto add-button"
|
||||
appA11yTitle="{{ addInfo.text | i18n }}"
|
||||
>
|
||||
<i class="bwi bwi-plus bwi-fw" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
<ul
|
||||
id="{{ headerNode.node.name }}-filters"
|
||||
|
@ -87,10 +87,6 @@ export class VaultFilterSectionComponent implements OnInit, OnDestroy {
|
||||
return this.section.add;
|
||||
}
|
||||
|
||||
get showAddButton() {
|
||||
return this.section.add && !this.section.add.route;
|
||||
}
|
||||
|
||||
get showAddLink() {
|
||||
return this.section.add && this.section.add.route;
|
||||
}
|
||||
|
@ -40,9 +40,31 @@
|
||||
</div>
|
||||
|
||||
<div *ngIf="filter.type !== 'trash'" class="tw-shrink-0">
|
||||
<button type="button" bitButton buttonType="primary" (click)="addCipher()">
|
||||
<i class="bwi bwi-plus bwi-fw" aria-hidden="true"></i>
|
||||
{{ "newItem" | i18n }}
|
||||
</button>
|
||||
<div appListDropdown>
|
||||
<button
|
||||
bitButton
|
||||
buttonType="primary"
|
||||
type="button"
|
||||
[bitMenuTriggerFor]="addOptions"
|
||||
id="newItemDropdown"
|
||||
appA11yTitle="{{ 'new' | i18n }}"
|
||||
>
|
||||
{{ "new" | i18n }}<i class="bwi bwi-angle-down tw-ml-2" aria-hidden="true"></i>
|
||||
</button>
|
||||
<bit-menu #addOptions aria-labelledby="newItemDropdown">
|
||||
<button type="button" bitMenuItem (click)="addCipher()">
|
||||
<i class="bwi bwi-fw bwi-globe" aria-hidden="true"></i>
|
||||
{{ "item" | i18n }}
|
||||
</button>
|
||||
<button type="button" bitMenuItem (click)="addFolder()">
|
||||
<i class="bwi bwi-fw bwi-folder" aria-hidden="true"></i>
|
||||
{{ "folder" | i18n }}
|
||||
</button>
|
||||
<button *ngIf="canCreateCollections" type="button" bitMenuItem (click)="addCollection()">
|
||||
<i class="bwi bwi-fw bwi-collection" aria-hidden="true"></i>
|
||||
{{ "collection" | i18n }}
|
||||
</button>
|
||||
</bit-menu>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -39,11 +39,26 @@ export class VaultHeaderComponent {
|
||||
*/
|
||||
@Input() collection?: TreeNode<CollectionView>;
|
||||
|
||||
/**
|
||||
* Whether 'Collection' option is shown in the 'New' dropdown
|
||||
*/
|
||||
@Input() canCreateCollections: boolean;
|
||||
|
||||
/**
|
||||
* Emits an event when the new item button is clicked in the header
|
||||
*/
|
||||
@Output() onAddCipher = new EventEmitter<void>();
|
||||
|
||||
/**
|
||||
* Emits an event when the new collection button is clicked in the 'New' dropdown menu
|
||||
*/
|
||||
@Output() onAddCollection = new EventEmitter<null>();
|
||||
|
||||
/**
|
||||
* Emits an event when the new folder button is clicked in the 'New' dropdown menu
|
||||
*/
|
||||
@Output() onAddFolder = new EventEmitter<null>();
|
||||
|
||||
constructor(private i18nService: I18nService) {}
|
||||
|
||||
/**
|
||||
@ -115,4 +130,12 @@ export class VaultHeaderComponent {
|
||||
protected addCipher() {
|
||||
this.onAddCipher.emit();
|
||||
}
|
||||
|
||||
async addFolder(): Promise<void> {
|
||||
this.onAddFolder.emit();
|
||||
}
|
||||
|
||||
async addCollection(): Promise<void> {
|
||||
this.onAddCollection.emit();
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,6 @@
|
||||
[activeFilter]="activeFilter"
|
||||
[searchText]="currentSearchText$ | async"
|
||||
(searchTextChanged)="filterSearchText($event)"
|
||||
(onAddFolder)="addFolder()"
|
||||
(onEditFolder)="editFolder($event)"
|
||||
></app-vault-filter>
|
||||
</div>
|
||||
@ -21,8 +20,11 @@
|
||||
[filter]="filter"
|
||||
[loading]="refreshing && !performingInitialLoad"
|
||||
[organizations]="allOrganizations"
|
||||
[canCreateCollections]="canCreateCollections"
|
||||
[collection]="selectedCollection"
|
||||
(onAddCipher)="addCipher()"
|
||||
(onAddCollection)="addCollection()"
|
||||
(onAddFolder)="addFolder()"
|
||||
></app-vault-header>
|
||||
<app-callout type="warning" *ngIf="activeFilter.isDeleted" icon="bwi-exclamation-triangle">
|
||||
{{ trashCleanupWarning }}
|
||||
|
@ -54,11 +54,14 @@ import { CollectionService } from "@bitwarden/common/vault/abstractions/collecti
|
||||
import { PasswordRepromptService } from "@bitwarden/common/vault/abstractions/password-reprompt.service";
|
||||
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
|
||||
import { CipherRepromptType } from "@bitwarden/common/vault/enums/cipher-reprompt-type";
|
||||
import { CollectionData } from "@bitwarden/common/vault/models/data/collection.data";
|
||||
import { CollectionDetailsResponse } from "@bitwarden/common/vault/models/response/collection.response";
|
||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||
import { CollectionView } from "@bitwarden/common/vault/models/view/collection.view";
|
||||
import { Icons } from "@bitwarden/components";
|
||||
|
||||
import { UpdateKeyComponent } from "../../settings/update-key.component";
|
||||
import { CollectionDialogAction, openCollectionDialog } from "../components/collection-dialog";
|
||||
import { VaultItemEvent } from "../components/vault-items/vault-item-event";
|
||||
import { getNestedCollectionTree } from "../utils/collection-utils";
|
||||
|
||||
@ -140,6 +143,7 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
protected collections: CollectionView[];
|
||||
protected isEmpty: boolean;
|
||||
protected selectedCollection: TreeNode<CollectionView> | undefined;
|
||||
protected canCreateCollections = false;
|
||||
protected currentSearchText$: Observable<string>;
|
||||
|
||||
private searchText$ = new Subject<string>();
|
||||
@ -234,12 +238,9 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
const canAccessPremium$ = Utils.asyncToObservable(() =>
|
||||
this.stateService.getCanAccessPremium()
|
||||
).pipe(shareReplay({ refCount: true, bufferSize: 1 }));
|
||||
const allCollections$ = Utils.asyncToObservable(() =>
|
||||
this.collectionService.getAllDecrypted()
|
||||
).pipe(shareReplay({ refCount: true, bufferSize: 1 }));
|
||||
const allCollections$ = Utils.asyncToObservable(() => this.collectionService.getAllDecrypted());
|
||||
const nestedCollections$ = allCollections$.pipe(
|
||||
map((collections) => getNestedCollectionTree(collections)),
|
||||
shareReplay({ refCount: true, bufferSize: 1 })
|
||||
map((collections) => getNestedCollectionTree(collections))
|
||||
);
|
||||
|
||||
this.searchText$
|
||||
@ -384,6 +385,8 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
this.collections = collections;
|
||||
this.selectedCollection = selectedCollection;
|
||||
|
||||
this.canCreateCollections = allOrganizations?.some((o) => o.canCreateNewCollections);
|
||||
|
||||
this.showBulkMove =
|
||||
filter.type !== "trash" &&
|
||||
(filter.organizationId === undefined || filter.organizationId === Unassigned);
|
||||
@ -639,6 +642,32 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
return childComponent;
|
||||
}
|
||||
|
||||
async addCollection() {
|
||||
const dialog = openCollectionDialog(this.dialogService, {
|
||||
data: {
|
||||
organizationId: this.allOrganizations
|
||||
.filter((o) => o.canCreateNewCollections)
|
||||
.sort(Utils.getSortFunction(this.i18nService, "name"))[0].id,
|
||||
parentCollectionId: this.filter.collectionId,
|
||||
showOrgSelector: true,
|
||||
collectionIds: this.allCollections.map((c) => c.id),
|
||||
},
|
||||
});
|
||||
const result = await lastValueFrom(dialog.closed);
|
||||
if (result.action === CollectionDialogAction.Saved) {
|
||||
if (result.collection) {
|
||||
// Update CollectionService with the new collection
|
||||
const c = new CollectionData(result.collection as CollectionDetailsResponse);
|
||||
await this.collectionService.upsert(c);
|
||||
}
|
||||
this.refresh();
|
||||
} else if (result.action === CollectionDialogAction.Deleted) {
|
||||
// TODO: Remove collection from collectionService when collection
|
||||
// deletion is implemented in the individual vault in AC-1347
|
||||
this.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
async cloneCipher(cipher: CipherView) {
|
||||
const component = await this.editCipher(cipher);
|
||||
component.cloneMode = true;
|
||||
|
@ -60,7 +60,7 @@ import { openEntityEventsDialog } from "../../admin-console/organizations/manage
|
||||
import { VaultFilterService } from "../../vault/individual-vault/vault-filter/services/abstractions/vault-filter.service";
|
||||
import { VaultFilter } from "../../vault/individual-vault/vault-filter/shared/models/vault-filter.model";
|
||||
import {
|
||||
CollectionDialogResult,
|
||||
CollectionDialogAction,
|
||||
CollectionDialogTabType,
|
||||
openCollectionDialog,
|
||||
} from "../components/collection-dialog";
|
||||
@ -866,7 +866,10 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
|
||||
const result = await lastValueFrom(dialog.closed);
|
||||
if (result === CollectionDialogResult.Saved || result === CollectionDialogResult.Deleted) {
|
||||
if (
|
||||
result.action === CollectionDialogAction.Saved ||
|
||||
result.action === CollectionDialogAction.Deleted
|
||||
) {
|
||||
this.refresh();
|
||||
}
|
||||
}
|
||||
@ -877,7 +880,10 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
|
||||
const result = await lastValueFrom(dialog.closed);
|
||||
if (result === CollectionDialogResult.Saved || result === CollectionDialogResult.Deleted) {
|
||||
if (
|
||||
result.action === CollectionDialogAction.Saved ||
|
||||
result.action === CollectionDialogAction.Deleted
|
||||
) {
|
||||
this.refresh();
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user