mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-22 11:45:59 +01:00
merging master into feature branch
This commit is contained in:
parent
a7eaa26c74
commit
e287715251
@ -1,5 +1,6 @@
|
||||
**/build
|
||||
**/dist
|
||||
.angular
|
||||
|
||||
**/node_modules
|
||||
|
||||
|
4
.github/workflows/build-browser.yml
vendored
4
.github/workflows/build-browser.yml
vendored
@ -16,7 +16,7 @@ on:
|
||||
branches:
|
||||
- 'master'
|
||||
- 'rc'
|
||||
- 'hotfix-rc/**'
|
||||
- 'hotfix-rc'
|
||||
paths:
|
||||
- 'apps/browser/**'
|
||||
- 'libs/**'
|
||||
@ -347,7 +347,7 @@ jobs:
|
||||
|
||||
trigger-desktop-build:
|
||||
name: Trigger desktop build
|
||||
if: ${{ (github.ref == 'refs/heads/master') || (github.ref == 'refs/heads/rc') || contains(github.ref, 'hotfix-rc') }}
|
||||
if: ${{ (github.ref == 'refs/heads/master') || (github.ref == 'refs/heads/rc') || github.ref != 'refs/heads/hotfix-rc' }}
|
||||
runs-on: ubuntu-20.04
|
||||
needs:
|
||||
- build
|
||||
|
2
.github/workflows/build-cli.yml
vendored
2
.github/workflows/build-cli.yml
vendored
@ -17,7 +17,7 @@ on:
|
||||
branches:
|
||||
- 'master'
|
||||
- 'rc'
|
||||
- 'hotfix-rc/**'
|
||||
- 'hotfix-rc'
|
||||
paths:
|
||||
- 'apps/cli/**'
|
||||
- 'libs/**'
|
||||
|
134
.github/workflows/build-desktop.yml
vendored
134
.github/workflows/build-desktop.yml
vendored
@ -159,7 +159,7 @@ jobs:
|
||||
- name: Set up environment
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install pkg-config libxss-dev libsecret-1-dev rpm
|
||||
sudo apt-get -y install pkg-config libxss-dev libsecret-1-dev rpm musl-dev musl-tools
|
||||
|
||||
- name: Set up Snap
|
||||
run: sudo snap install snapcraft --classic
|
||||
@ -175,6 +175,27 @@ jobs:
|
||||
run: npm ci
|
||||
working-directory: ./
|
||||
|
||||
- name: Cache Native Module
|
||||
uses: actions/cache@48af2dc4a9e8278b89d7fa154b955c30c6aaab09 # v3.0.2
|
||||
id: cache
|
||||
with:
|
||||
path: |
|
||||
apps/desktop/desktop_native/*.node
|
||||
${{ env.RUNNER_TEMP }}/.cargo/registry
|
||||
${{ env.RUNNER_TEMP }}/.cargo/git
|
||||
key: rust-${{ runner.os }}-${{ hashFiles('apps/desktop/desktop_native/**/*') }}
|
||||
|
||||
- name: Build Native Module
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
working-directory: apps/desktop/desktop_native
|
||||
env:
|
||||
PKG_CONFIG_ALLOW_CROSS: true
|
||||
PKG_CONFIG_ALL_STATIC: true
|
||||
TARGET: musl
|
||||
run: |
|
||||
rustup target add x86_64-unknown-linux-musl
|
||||
npm run build:cross-platform
|
||||
|
||||
- name: Build application
|
||||
run: npm run dist:lin
|
||||
|
||||
@ -256,11 +277,18 @@ jobs:
|
||||
- name: Set up environment
|
||||
run: choco install checksum --no-progress
|
||||
|
||||
- name: Rust
|
||||
shell: pwsh
|
||||
run: |
|
||||
rustup target install i686-pc-windows-msvc
|
||||
rustup target install aarch64-pc-windows-msvc
|
||||
|
||||
- name: Print environment
|
||||
run: |
|
||||
node --version
|
||||
npm --version
|
||||
choco --version
|
||||
rustup show
|
||||
|
||||
- name: Login to Azure
|
||||
uses: Azure/login@1f63701bf3e6892515f1b7ce2d2bf1708b46beaf
|
||||
@ -282,6 +310,19 @@ jobs:
|
||||
run: npm ci
|
||||
working-directory: ./
|
||||
|
||||
- name: Cache Native Module
|
||||
uses: actions/cache@48af2dc4a9e8278b89d7fa154b955c30c6aaab09 # v3.0.2
|
||||
id: cache
|
||||
with:
|
||||
path: apps/desktop/desktop_native/*.node
|
||||
key: rust-${{ runner.os }}-${{ hashFiles('apps/desktop/desktop_native/**/*') }}
|
||||
|
||||
- name: Build Native Module
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
working-directory: apps/desktop/desktop_native
|
||||
run: |
|
||||
npm run build:cross-platform
|
||||
|
||||
- name: Build & Sign (dev)
|
||||
env:
|
||||
ELECTRON_BUILDER_SIGN: 1
|
||||
@ -443,10 +484,15 @@ jobs:
|
||||
npm install -g node-gyp
|
||||
node-gyp install $(node -v)
|
||||
|
||||
- name: Rust
|
||||
shell: pwsh
|
||||
run: rustup target install aarch64-apple-darwin
|
||||
|
||||
- name: Print environment
|
||||
run: |
|
||||
node --version
|
||||
npm --version
|
||||
rustup show
|
||||
echo "GitHub ref: $GITHUB_REF"
|
||||
echo "GitHub event: $GITHUB_EVENT"
|
||||
|
||||
@ -536,6 +582,19 @@ jobs:
|
||||
run: npm ci
|
||||
working-directory: ./
|
||||
|
||||
- name: Cache Native Module
|
||||
uses: actions/cache@48af2dc4a9e8278b89d7fa154b955c30c6aaab09 # v3.0.2
|
||||
id: cache
|
||||
with:
|
||||
path: apps/desktop/desktop_native/*.node
|
||||
key: rust-${{ runner.os }}-${{ hashFiles('apps/desktop/desktop_native/**/*') }}
|
||||
|
||||
- name: Build Native Module
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
working-directory: apps/desktop/desktop_native
|
||||
run: |
|
||||
npm run build:cross-platform
|
||||
|
||||
- name: Build application (dev)
|
||||
run: npm run build
|
||||
|
||||
@ -570,10 +629,15 @@ jobs:
|
||||
npm install -g node-gyp
|
||||
node-gyp install $(node -v)
|
||||
|
||||
- name: Rust
|
||||
shell: pwsh
|
||||
run: rustup target install aarch64-apple-darwin
|
||||
|
||||
- name: Print environment
|
||||
run: |
|
||||
node --version
|
||||
npm --version
|
||||
rustup show
|
||||
echo "GitHub ref: $GITHUB_REF"
|
||||
echo "GitHub event: $GITHUB_EVENT"
|
||||
|
||||
@ -663,23 +727,30 @@ jobs:
|
||||
run: npm ci
|
||||
working-directory: ./
|
||||
|
||||
- name: Cache Native Module
|
||||
uses: actions/cache@48af2dc4a9e8278b89d7fa154b955c30c6aaab09 # v3.0.2
|
||||
id: cache
|
||||
with:
|
||||
path: apps/desktop/desktop_native/*.node
|
||||
key: rust-${{ runner.os }}-${{ hashFiles('apps/desktop/desktop_native/**/*') }}
|
||||
|
||||
- name: Build Native Module
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
working-directory: apps/desktop/desktop_native
|
||||
run: |
|
||||
npm run build:cross-platform
|
||||
|
||||
- name: Build
|
||||
if: steps.build-cache.outputs.cache-hit != 'true'
|
||||
run: npm run build
|
||||
|
||||
- name: Extract branch name
|
||||
if: contains(github.ref, 'hotfix-rc')
|
||||
id: extract_branch
|
||||
shell: bash
|
||||
run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
|
||||
|
||||
- name: Download artifact from hotfix-rc
|
||||
if: contains(github.ref, 'hotfix-rc')
|
||||
if: github.ref == 'refs/heads/hotfix-rc'
|
||||
uses: dawidd6/action-download-artifact@b2abf1705491048a2d7074f7d90513044fd25d39 # v2.19.0
|
||||
with:
|
||||
workflow: build-browser.yml
|
||||
workflow_conclusion: success
|
||||
branch: ${{ steps.extract_branch.outputs.branch }}
|
||||
branch: hotfix-rc
|
||||
path: ${{ github.workspace }}/browser-build-artifacts
|
||||
|
||||
- name: Download artifact from rc
|
||||
@ -692,7 +763,7 @@ jobs:
|
||||
path: ${{ github.workspace }}/browser-build-artifacts
|
||||
|
||||
- name: Download artifact from master
|
||||
if: ${{ github.ref != 'refs/heads/rc' && !contains(github.ref, 'hotfix-rc') }}
|
||||
if: ${{ github.ref != 'refs/heads/rc' && github.ref != 'refs/heads/hotfix-rc' }}
|
||||
uses: dawidd6/action-download-artifact@b2abf1705491048a2d7074f7d90513044fd25d39 # v2.19.0
|
||||
with:
|
||||
workflow: build-browser.yml
|
||||
@ -776,10 +847,15 @@ jobs:
|
||||
npm install -g node-gyp
|
||||
node-gyp install $(node -v)
|
||||
|
||||
- name: Rust
|
||||
shell: pwsh
|
||||
run: rustup target install aarch64-apple-darwin
|
||||
|
||||
- name: Print environment
|
||||
run: |
|
||||
node --version
|
||||
npm --version
|
||||
rustup show
|
||||
echo "GitHub ref: $GITHUB_REF"
|
||||
echo "GitHub event: $GITHUB_EVENT"
|
||||
|
||||
@ -869,23 +945,30 @@ jobs:
|
||||
run: npm ci
|
||||
working-directory: ./
|
||||
|
||||
- name: Cache Native Module
|
||||
uses: actions/cache@48af2dc4a9e8278b89d7fa154b955c30c6aaab09 # v3.0.2
|
||||
id: cache
|
||||
with:
|
||||
path: apps/desktop/desktop_native/*.node
|
||||
key: rust-${{ runner.os }}-${{ hashFiles('apps/desktop/desktop_native/**/*') }}
|
||||
|
||||
- name: Build Native Module
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
working-directory: apps/desktop/desktop_native
|
||||
run: |
|
||||
npm run build:cross-platform
|
||||
|
||||
- name: Build
|
||||
if: steps.build-cache.outputs.cache-hit != 'true'
|
||||
run: npm run build
|
||||
|
||||
- name: Extract branch name
|
||||
if: contains(github.ref, 'hotfix-rc')
|
||||
id: extract_branch
|
||||
shell: bash
|
||||
run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
|
||||
|
||||
- name: Download artifact from hotfix-rc
|
||||
if: contains(github.ref, 'hotfix-rc')
|
||||
if: github.ref == 'refs/heads/hotfix-rc'
|
||||
uses: dawidd6/action-download-artifact@b2abf1705491048a2d7074f7d90513044fd25d39 # v2.19.0
|
||||
with:
|
||||
workflow: build-browser.yml
|
||||
workflow_conclusion: success
|
||||
branch: ${{ steps.extract_branch.outputs.branch }}
|
||||
branch: hotfix-rc
|
||||
path: ${{ github.workspace }}/browser-build-artifacts
|
||||
|
||||
- name: Download artifact from rc
|
||||
@ -898,7 +981,7 @@ jobs:
|
||||
path: ${{ github.workspace }}/browser-build-artifacts
|
||||
|
||||
- name: Download artifact from master
|
||||
if: ${{ github.ref != 'refs/heads/rc' && !contains(github.ref, 'hotfix-rc') }}
|
||||
if: ${{ github.ref != 'refs/heads/rc' && github.ref != 'refs/heads/hotfix-rc' }}
|
||||
uses: dawidd6/action-download-artifact@b2abf1705491048a2d7074f7d90513044fd25d39 # v2.19.0
|
||||
with:
|
||||
workflow: build-browser.yml
|
||||
@ -1067,6 +1150,19 @@ jobs:
|
||||
run: npm ci
|
||||
working-directory: ./
|
||||
|
||||
- name: Cache Native Module
|
||||
uses: actions/cache@48af2dc4a9e8278b89d7fa154b955c30c6aaab09 # v3.0.2
|
||||
id: cache
|
||||
with:
|
||||
path: apps/desktop/desktop_native/*.node
|
||||
key: rust-${{ runner.os }}-${{ hashFiles('apps/desktop/desktop_native/**/*') }}
|
||||
|
||||
- name: Build Native Module
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
working-directory: apps/desktop/desktop_native
|
||||
run: |
|
||||
npm run build:cross-platform
|
||||
|
||||
- name: Build
|
||||
if: steps.build-cache.outputs.cache-hit != 'true'
|
||||
run: npm run build
|
||||
|
2
.github/workflows/build-web.yml
vendored
2
.github/workflows/build-web.yml
vendored
@ -17,7 +17,7 @@ on:
|
||||
branches:
|
||||
- 'master'
|
||||
- 'rc'
|
||||
- 'hotfix-rc/**'
|
||||
- 'hotfix-rc'
|
||||
paths:
|
||||
- 'apps/web/**'
|
||||
- 'libs/**'
|
||||
|
36
.github/workflows/release-browser.yml
vendored
36
.github/workflows/release-browser.yml
vendored
@ -31,9 +31,9 @@ jobs:
|
||||
- name: Branch check
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
run: |
|
||||
if [[ "$GITHUB_REF" != "refs/heads/rc" ]] && [[ $GITHUB_REF != refs/heads/hotfix-rc/* ]]; then
|
||||
if [[ "$GITHUB_REF" != "refs/heads/rc" ]] && [[ $GITHUB_REF != refs/heads/hotfix-rc ]]; then
|
||||
echo "==================================="
|
||||
echo "[!] Can only release from the 'rc' or 'hotfix-rc/*' branches"
|
||||
echo "[!] Can only release from the 'rc' or 'hotfix-rc' branches"
|
||||
echo "==================================="
|
||||
exit 1
|
||||
fi
|
||||
@ -90,6 +90,22 @@ jobs:
|
||||
- setup
|
||||
- locales-test
|
||||
steps:
|
||||
- name: Create GitHub deployment
|
||||
uses: chrnorm/deployment-action@1b599fe41a0ef1f95191e7f2eec4743f2d7dfc48
|
||||
id: deployment
|
||||
with:
|
||||
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
environment: 'Browser - Production'
|
||||
description: 'Deployment ${{ needs.setup.outputs.release-version }} from branch ${{ github.ref_name }}'
|
||||
task: release
|
||||
|
||||
- name: Update deployment status to In Progress
|
||||
uses: chrnorm/deployment-status@07b3930847f65e71c9c6802ff5a402f6dfb46b86
|
||||
with:
|
||||
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
state: 'in_progress'
|
||||
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
|
||||
|
||||
- name: Download latest Release build artifacts
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
uses: bitwarden/gh-actions/download-artifacts@c1fa8e09871a860862d6bbe36184b06d2c7e35a8
|
||||
@ -141,3 +157,19 @@ jobs:
|
||||
body: "<insert release notes here>"
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
draft: true
|
||||
|
||||
- name: Update deployment status to Success
|
||||
if: success()
|
||||
uses: chrnorm/deployment-status@07b3930847f65e71c9c6802ff5a402f6dfb46b86
|
||||
with:
|
||||
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
state: 'success'
|
||||
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
|
||||
|
||||
- name: Update deployment status to Failure
|
||||
if: failure()
|
||||
uses: chrnorm/deployment-status@07b3930847f65e71c9c6802ff5a402f6dfb46b86
|
||||
with:
|
||||
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
state: 'failure'
|
||||
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
|
||||
|
38
.github/workflows/release-cli.yml
vendored
38
.github/workflows/release-cli.yml
vendored
@ -47,9 +47,9 @@ jobs:
|
||||
- name: Branch check
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
run: |
|
||||
if [[ "$GITHUB_REF" != "refs/heads/rc" ]] && [[ $GITHUB_REF != refs/heads/hotfix-rc/* ]]; then
|
||||
if [[ "$GITHUB_REF" != "refs/heads/rc" ]] && [[ $GITHUB_REF != refs/heads/hotfix-rc ]]; then
|
||||
echo "==================================="
|
||||
echo "[!] Can only release from the 'rc' or 'hotfix-rc/*' branches"
|
||||
echo "[!] Can only release from the 'rc' or 'hotfix-rc' branches"
|
||||
echo "==================================="
|
||||
exit 1
|
||||
fi
|
||||
@ -64,6 +64,22 @@ jobs:
|
||||
monorepo: true
|
||||
monorepo-project: cli
|
||||
|
||||
- name: Create GitHub deployment for Snap
|
||||
uses: chrnorm/deployment-action@1b599fe41a0ef1f95191e7f2eec4743f2d7dfc48
|
||||
id: deployment
|
||||
with:
|
||||
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
environment: 'CLI - Production'
|
||||
description: 'Deployment ${{ steps.version.outputs.version }} from branch ${{ github.ref_name }}'
|
||||
task: release
|
||||
|
||||
- name: Update deployment status to In Progress
|
||||
uses: chrnorm/deployment-status@07b3930847f65e71c9c6802ff5a402f6dfb46b86
|
||||
with:
|
||||
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
state: 'in_progress'
|
||||
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
|
||||
|
||||
- name: Download all Release artifacts
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
uses: bitwarden/gh-actions/download-artifacts@c1fa8e09871a860862d6bbe36184b06d2c7e35a8
|
||||
@ -104,6 +120,21 @@ jobs:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
draft: true
|
||||
|
||||
- name: Update deployment status to Success
|
||||
if: success()
|
||||
uses: chrnorm/deployment-status@07b3930847f65e71c9c6802ff5a402f6dfb46b86
|
||||
with:
|
||||
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
state: 'success'
|
||||
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
|
||||
|
||||
- name: Update deployment status to Failure
|
||||
if: failure()
|
||||
uses: chrnorm/deployment-status@07b3930847f65e71c9c6802ff5a402f6dfb46b86
|
||||
with:
|
||||
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
state: 'failure'
|
||||
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
|
||||
|
||||
snap:
|
||||
name: Deploy Snap
|
||||
@ -159,7 +190,6 @@ jobs:
|
||||
snapcraft push bw_${{ env._PKG_VERSION }}_amd64.snap --release stable
|
||||
snapcraft logout
|
||||
|
||||
|
||||
choco:
|
||||
name: Deploy Choco
|
||||
runs-on: windows-2019
|
||||
@ -219,7 +249,6 @@ jobs:
|
||||
cd dist
|
||||
choco push
|
||||
|
||||
|
||||
npm:
|
||||
name: Publish NPM
|
||||
runs-on: ubuntu-20.04
|
||||
@ -274,3 +303,4 @@ jobs:
|
||||
- name: Publish NPM
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
run: npm publish --access public
|
||||
|
||||
|
155
.github/workflows/release-desktop-beta.yml
vendored
155
.github/workflows/release-desktop-beta.yml
vendored
@ -19,18 +19,19 @@ jobs:
|
||||
outputs:
|
||||
release-version: ${{ steps.version.outputs.version }}
|
||||
release-channel: ${{ steps.release-channel.outputs.channel }}
|
||||
branch-name: ${{ steps.branch.outputs.branch-name }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # v3.0.2
|
||||
|
||||
# - name: Branch check
|
||||
# run: |
|
||||
# if [[ "$GITHUB_REF" != "refs/heads/master" ]] && [[ "$GITHUB_REF" != "refs/heads/rc" ]] && [[ $GITHUB_REF != refs/heads/hotfix-rc/* ]]; then
|
||||
# echo "==================================="
|
||||
# echo "[!] Can only release from the 'master', 'rc' or 'hotfix-rc/*' branches"
|
||||
# echo "==================================="
|
||||
# exit 1
|
||||
# fi
|
||||
- name: Branch check
|
||||
run: |
|
||||
if [[ "$GITHUB_REF" != "refs/heads/master" ]] && [[ "$GITHUB_REF" != "refs/heads/rc" ]] && [[ $GITHUB_REF != "refs/heads/hotfix-rc" ]]; then
|
||||
echo "==================================="
|
||||
echo "[!] Can only release from the 'master', 'rc' or 'hotfix-rc' branches"
|
||||
echo "==================================="
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Bump Desktop Version - Root
|
||||
env:
|
||||
@ -70,18 +71,45 @@ jobs:
|
||||
;;
|
||||
esac
|
||||
|
||||
- name: Setup git config
|
||||
run: |
|
||||
git config --global user.name "GitHub Action Bot"
|
||||
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
git config --global url."https://github.com/".insteadOf ssh://git@github.com/
|
||||
git config --global url."https://".insteadOf ssh://
|
||||
|
||||
- name: Create desktop-beta-release branch
|
||||
id: branch
|
||||
env:
|
||||
VERSION: ${{ github.event.inputs.version_number }}
|
||||
run: |
|
||||
find="."
|
||||
replace="_"
|
||||
ver=${VERSION//$find/$replace}
|
||||
branch_name=desktop-beta-release-$ver-beta
|
||||
|
||||
git switch -c $branch_name
|
||||
git add .
|
||||
git commit -m "Bump desktop version to $VERSION-beta"
|
||||
|
||||
git push -u origin $branch_name
|
||||
|
||||
echo "::set-output name=branch-name::$branch_name"
|
||||
|
||||
linux:
|
||||
name: Linux Build
|
||||
runs-on: ubuntu-20.04
|
||||
needs: setup
|
||||
env:
|
||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.release-version }}
|
||||
defaults:
|
||||
run:
|
||||
working-directory: apps/desktop
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
|
||||
with:
|
||||
ref: ${{ needs.setup.outputs.branch-name }}
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@9ced9a43a244f3ac94f13bfd896db8c8f30da67a # v3.0.0
|
||||
@ -158,8 +186,8 @@ jobs:
|
||||
- name: Upload auto-update artifact
|
||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
||||
with:
|
||||
name: ${{ needs.setup.outputs.release_channel }}-linux.yml
|
||||
path: apps/desktop/dist/${{ needs.setup.outputs.release_channel }}-linux.yml
|
||||
name: ${{ needs.setup.outputs.release-channel }}-linux.yml
|
||||
path: apps/desktop/dist/${{ needs.setup.outputs.release-channel }}-linux.yml
|
||||
if-no-files-found: error
|
||||
|
||||
|
||||
@ -172,10 +200,12 @@ jobs:
|
||||
shell: pwsh
|
||||
working-directory: apps/desktop
|
||||
env:
|
||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.release-version }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
|
||||
with:
|
||||
ref: ${{ needs.setup.outputs.branch-name }}
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@9ced9a43a244f3ac94f13bfd896db8c8f30da67a # v3.0.0
|
||||
@ -352,8 +382,8 @@ jobs:
|
||||
- name: Upload auto-update artifact
|
||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
||||
with:
|
||||
name: ${{ needs.setup.outputs.release_channel }}.yml
|
||||
path: apps/desktop/dist/nsis-web/${{ needs.setup.outputs.release_channel }}.yml
|
||||
name: ${{ needs.setup.outputs.release-channel }}.yml
|
||||
path: apps/desktop/dist/nsis-web/${{ needs.setup.outputs.release-channel }}.yml
|
||||
if-no-files-found: error
|
||||
|
||||
|
||||
@ -362,13 +392,15 @@ jobs:
|
||||
runs-on: macos-11
|
||||
needs: setup
|
||||
env:
|
||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.release-version }}
|
||||
defaults:
|
||||
run:
|
||||
working-directory: apps/desktop
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
|
||||
with:
|
||||
ref: ${{ needs.setup.outputs.branch-name }}
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@9ced9a43a244f3ac94f13bfd896db8c8f30da67a # v3.0.0
|
||||
@ -489,13 +521,15 @@ jobs:
|
||||
- setup
|
||||
- macos-build
|
||||
env:
|
||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.release-version }}
|
||||
defaults:
|
||||
run:
|
||||
working-directory: apps/desktop
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
|
||||
with:
|
||||
ref: ${{ needs.setup.outputs.branch-name }}
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@9ced9a43a244f3ac94f13bfd896db8c8f30da67a # v3.0.0
|
||||
@ -609,19 +643,13 @@ jobs:
|
||||
if: steps.build-cache.outputs.cache-hit != 'true'
|
||||
run: npm run build
|
||||
|
||||
- name: Extract branch name
|
||||
if: contains(github.ref, 'hotfix-rc')
|
||||
id: extract_branch
|
||||
shell: bash
|
||||
run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
|
||||
|
||||
- name: Download artifact from hotfix-rc
|
||||
if: contains(github.ref, 'hotfix-rc')
|
||||
if: github.ref == 'refs/heads/hotfix-rc')
|
||||
uses: dawidd6/action-download-artifact@b2abf1705491048a2d7074f7d90513044fd25d39 # v2.19.0
|
||||
with:
|
||||
workflow: build-browser.yml
|
||||
workflow_conclusion: success
|
||||
branch: ${{ steps.extract_branch.outputs.branch }}
|
||||
branch: hotfix-rc
|
||||
path: ${{ github.workspace }}/browser-build-artifacts
|
||||
|
||||
- name: Download artifact from rc
|
||||
@ -634,7 +662,7 @@ jobs:
|
||||
path: ${{ github.workspace }}/browser-build-artifacts
|
||||
|
||||
- name: Download artifact from master
|
||||
if: ${{ github.ref != 'refs/heads/rc' && !contains(github.ref, 'hotfix-rc') }}
|
||||
if: ${{ github.ref != 'refs/heads/rc' && github.ref != 'refs/heads/hotfix-rc' }}
|
||||
uses: dawidd6/action-download-artifact@b2abf1705491048a2d7074f7d90513044fd25d39 # v2.19.0
|
||||
with:
|
||||
workflow: build-browser.yml
|
||||
@ -683,8 +711,8 @@ jobs:
|
||||
- name: Upload auto-update artifact
|
||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
||||
with:
|
||||
name: ${{ needs.setup.outputs.release_channel }}-mac.yml
|
||||
path: apps/desktop/dist/${{ needs.setup.outputs.release_channel }}-mac.yml
|
||||
name: ${{ needs.setup.outputs.release-channel }}-mac.yml
|
||||
path: apps/desktop/dist/${{ needs.setup.outputs.release-channel }}-mac.yml
|
||||
if-no-files-found: error
|
||||
|
||||
|
||||
@ -695,13 +723,15 @@ jobs:
|
||||
- setup
|
||||
- macos-build
|
||||
env:
|
||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.release-version }}
|
||||
defaults:
|
||||
run:
|
||||
working-directory: apps/desktop
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
|
||||
with:
|
||||
ref: ${{ needs.setup.outputs.branch-name }}
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@9ced9a43a244f3ac94f13bfd896db8c8f30da67a # v3.0.0
|
||||
@ -815,19 +845,13 @@ jobs:
|
||||
if: steps.build-cache.outputs.cache-hit != 'true'
|
||||
run: npm run build
|
||||
|
||||
- name: Extract branch name
|
||||
if: contains(github.ref, 'hotfix-rc')
|
||||
id: extract_branch
|
||||
shell: bash
|
||||
run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
|
||||
|
||||
- name: Download artifact from hotfix-rc
|
||||
if: contains(github.ref, 'hotfix-rc')
|
||||
if: github.ref == 'refs/heads/hotfix-rc')
|
||||
uses: dawidd6/action-download-artifact@b2abf1705491048a2d7074f7d90513044fd25d39 # v2.19.0
|
||||
with:
|
||||
workflow: build-browser.yml
|
||||
workflow_conclusion: success
|
||||
branch: ${{ steps.extract_branch.outputs.branch }}
|
||||
branch: hotfix-rc
|
||||
path: ${{ github.workspace }}/browser-build-artifacts
|
||||
|
||||
- name: Download artifact from rc
|
||||
@ -840,7 +864,7 @@ jobs:
|
||||
path: ${{ github.workspace }}/browser-build-artifacts
|
||||
|
||||
- name: Download artifact from master
|
||||
if: ${{ github.ref != 'refs/heads/rc' && !contains(github.ref, 'hotfix-rc') }}
|
||||
if: ${{ github.ref != 'refs/heads/rc' && github.ref != 'refs/heads/hotfix-rc' }}
|
||||
uses: dawidd6/action-download-artifact@b2abf1705491048a2d7074f7d90513044fd25d39 # v2.19.0
|
||||
with:
|
||||
workflow: build-browser.yml
|
||||
@ -873,7 +897,7 @@ jobs:
|
||||
if-no-files-found: error
|
||||
|
||||
release:
|
||||
name: MacOS Package Prod Release Asset
|
||||
name: Release beta channel to S3
|
||||
runs-on: ubuntu-20.04
|
||||
needs:
|
||||
- setup
|
||||
@ -896,7 +920,7 @@ jobs:
|
||||
secrets: "aws-electron-access-id, aws-electron-access-key, aws-electron-bucket-name"
|
||||
|
||||
- name: Download all artifacts
|
||||
uses: bitwarden/gh-actions/download-artifacts@23433be15ed6fd046ce12b6889c5184a8d9c8783
|
||||
uses: actions/download-artifact@fb598a63ae348fa914e94cd0ff38f362e927b741 # v3.0.0
|
||||
with:
|
||||
path: apps/desktop/artifacts
|
||||
|
||||
@ -906,15 +930,44 @@ jobs:
|
||||
working-directory: apps/desktop/artifacts
|
||||
run: mv Bitwarden-${{ env.PKG_VERSION }}-universal.pkg Bitwarden-${{ env.PKG_VERSION }}-universal.pkg.archive
|
||||
|
||||
# - name: Publish artifacts to S3
|
||||
# env:
|
||||
# AWS_ACCESS_KEY_ID: ${{ steps.retrieve-secrets.outputs.aws-electron-access-id }}
|
||||
# AWS_SECRET_ACCESS_KEY: ${{ steps.retrieve-secrets.outputs.aws-electron-access-key }}
|
||||
# AWS_DEFAULT_REGION: 'us-west-2'
|
||||
# AWS_S3_BUCKET_NAME: ${{ steps.retrieve-secrets.outputs.aws-electron-bucket-name }}
|
||||
# working-directory: apps/desktop/artifacts
|
||||
# run: |
|
||||
# aws s3 cp ./ $AWS_S3_BUCKET_NAME/desktop/ \
|
||||
# --acl "public-read" \
|
||||
# --recursive \
|
||||
# --quiet
|
||||
- name: Publish artifacts to S3
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: ${{ steps.retrieve-secrets.outputs.aws-electron-access-id }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ steps.retrieve-secrets.outputs.aws-electron-access-key }}
|
||||
AWS_DEFAULT_REGION: 'us-west-2'
|
||||
AWS_S3_BUCKET_NAME: ${{ steps.retrieve-secrets.outputs.aws-electron-bucket-name }}
|
||||
working-directory: apps/desktop/artifacts
|
||||
run: |
|
||||
aws s3 cp ./ $AWS_S3_BUCKET_NAME/desktop/ \
|
||||
--acl "public-read" \
|
||||
--recursive \
|
||||
--quiet
|
||||
|
||||
|
||||
remove-branch:
|
||||
name: Remove branch
|
||||
runs-on: ubuntu-20.04
|
||||
if: always()
|
||||
needs:
|
||||
- setup
|
||||
- linux
|
||||
- windows
|
||||
- macos-build
|
||||
- macos-package-github
|
||||
- macos-package-mas
|
||||
- release
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
|
||||
|
||||
- name: Setup git config
|
||||
run: |
|
||||
git config --global user.name "GitHub Action Bot"
|
||||
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
git config --global url."https://github.com/".insteadOf ssh://git@github.com/
|
||||
git config --global url."https://".insteadOf ssh://
|
||||
- name: Remove branch
|
||||
env:
|
||||
BRANCH: ${{ needs.setup.outputs.branch-name }}
|
||||
run: git push origin --delete $BRANCH
|
||||
|
||||
|
35
.github/workflows/release-desktop.yml
vendored
35
.github/workflows/release-desktop.yml
vendored
@ -42,9 +42,9 @@ jobs:
|
||||
- name: Branch check
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
run: |
|
||||
if [[ "$GITHUB_REF" != "refs/heads/rc" ]] && [[ $GITHUB_REF != refs/heads/hotfix-rc/* ]]; then
|
||||
if [[ "$GITHUB_REF" != "refs/heads/rc" ]] && [[ $GITHUB_REF != refs/heads/hotfix-rc ]]; then
|
||||
echo "==================================="
|
||||
echo "[!] Can only release from the 'rc' or 'hotfix-rc/*' branches"
|
||||
echo "[!] Can only release from the 'rc' or 'hotfix-rc' branches"
|
||||
echo "==================================="
|
||||
exit 1
|
||||
fi
|
||||
@ -76,6 +76,22 @@ jobs:
|
||||
;;
|
||||
esac
|
||||
|
||||
- name: Create GitHub deployment
|
||||
uses: chrnorm/deployment-action@1b599fe41a0ef1f95191e7f2eec4743f2d7dfc48
|
||||
id: deployment
|
||||
with:
|
||||
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
environment: 'Desktop - Production'
|
||||
description: 'Deployment ${{ steps.version.outputs.version }} to channel ${{ steps.release-channel.outputs.channel }} from branch ${{ github.ref_name }}'
|
||||
task: release
|
||||
|
||||
- name: Update deployment status to In Progress
|
||||
uses: chrnorm/deployment-status@1b599fe41a0ef1f95191e7f2eec4743f2d7dfc48
|
||||
with:
|
||||
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
state: 'failure'
|
||||
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
|
||||
|
||||
- name: Login to Azure
|
||||
uses: Azure/login@ec3c14589bd3e9312b3cc8c41e6860e258df9010
|
||||
with:
|
||||
@ -164,6 +180,21 @@ jobs:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
draft: true
|
||||
|
||||
- name: Update deployment status to Success
|
||||
if: success()
|
||||
uses: chrnorm/deployment-status@07b3930847f65e71c9c6802ff5a402f6dfb46b86
|
||||
with:
|
||||
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
state: 'success'
|
||||
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
|
||||
|
||||
- name: Update deployment status to Failure
|
||||
if: failure()
|
||||
uses: chrnorm/deployment-status@07b3930847f65e71c9c6802ff5a402f6dfb46b86
|
||||
with:
|
||||
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
state: 'failure'
|
||||
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
|
||||
|
||||
snap:
|
||||
name: Deploy Snap
|
||||
|
35
.github/workflows/release-qa-web.yml
vendored
35
.github/workflows/release-qa-web.yml
vendored
@ -72,6 +72,23 @@ jobs:
|
||||
name: Deploy Web Vault to QA CloudFlare Pages branch
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Create GitHub deployment
|
||||
uses: chrnorm/deployment-action@1b599fe41a0ef1f95191e7f2eec4743f2d7dfc48
|
||||
id: deployment
|
||||
with:
|
||||
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
environment-url: http://vault.qa.bitwarden.pw
|
||||
environment: 'Web Vault - QA'
|
||||
description: 'Deployment from branch ${{ github.ref_name }}'
|
||||
|
||||
- name: Update deployment status to In Progress
|
||||
uses: chrnorm/deployment-status@07b3930847f65e71c9c6802ff5a402f6dfb46b86
|
||||
with:
|
||||
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
environment-url: http://vault.qa.bitwarden.pw
|
||||
state: 'in_progress'
|
||||
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
|
||||
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # v3.0.2
|
||||
|
||||
@ -118,3 +135,21 @@ jobs:
|
||||
echo "No changes to commit!";
|
||||
fi
|
||||
working-directory: deployment
|
||||
|
||||
- name: Update deployment status to Success
|
||||
if: success()
|
||||
uses: chrnorm/deployment-status@07b3930847f65e71c9c6802ff5a402f6dfb46b86
|
||||
with:
|
||||
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
environment-url: http://vault.qa.bitwarden.pw
|
||||
state: 'success'
|
||||
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
|
||||
|
||||
- name: Update deployment status to Failure
|
||||
if: failure()
|
||||
uses: chrnorm/deployment-status@07b3930847f65e71c9c6802ff5a402f6dfb46b86
|
||||
with:
|
||||
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
environment-url: http://vault.qa.bitwarden.pw
|
||||
state: 'failure'
|
||||
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
|
||||
|
46
.github/workflows/release-web.yml
vendored
46
.github/workflows/release-web.yml
vendored
@ -28,9 +28,9 @@ jobs:
|
||||
- name: Branch check
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
run: |
|
||||
if [[ "$GITHUB_REF" != "refs/heads/rc" ]] && [[ $GITHUB_REF != refs/heads/hotfix-rc/* ]]; then
|
||||
if [[ "$GITHUB_REF" != "refs/heads/rc" ]] && [[ $GITHUB_REF != "refs/heads/hotfix-rc" ]]; then
|
||||
echo "==================================="
|
||||
echo "[!] Can only release from the 'rc' or 'hotfix-rc/*' branches"
|
||||
echo "[!] Can only release from the 'rc' or 'hotfix-rc' branches"
|
||||
echo "==================================="
|
||||
exit 1
|
||||
fi
|
||||
@ -147,7 +147,7 @@ jobs:
|
||||
- self-host
|
||||
env:
|
||||
_RELEASE_VERSION: ${{ needs.setup.outputs.release_version }}
|
||||
_TAG_VERSION: ${{ needs.setup.outputs.tag_version }}
|
||||
_TAG_VERSION: ${{ needs.setup.outputs.release_version }}
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # v3.0.2
|
||||
@ -227,6 +227,24 @@ jobs:
|
||||
- self-host
|
||||
- cfpages-deploy
|
||||
steps:
|
||||
- name: Create GitHub deployment
|
||||
uses: chrnorm/deployment-action@1b599fe41a0ef1f95191e7f2eec4743f2d7dfc48
|
||||
id: deployment
|
||||
with:
|
||||
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
environment-url: http://vault.bitwarden.com
|
||||
environment: 'Web Vault - Production'
|
||||
description: 'Deployment ${{ needs.setup.outputs.release_version }} from branch ${{ github.ref_name }}'
|
||||
task: release
|
||||
|
||||
- name: Update deployment status to In Progress
|
||||
uses: chrnorm/deployment-status@07b3930847f65e71c9c6802ff5a402f6dfb46b86
|
||||
with:
|
||||
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
environment-url: http://vault.bitwarden.com
|
||||
state: 'in_progress'
|
||||
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
|
||||
|
||||
- name: Download latest build artifacts
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
uses: bitwarden/gh-actions/download-artifacts@c1fa8e09871a860862d6bbe36184b06d2c7e35a8
|
||||
@ -259,11 +277,29 @@ jobs:
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
uses: ncipollo/release-action@58ae73b360456532aafd58ee170c045abbeaee37 # v1.10.0
|
||||
with:
|
||||
name: "Version v${{ needs.setup.outputs.release_version }}"
|
||||
name: "Web v${{ needs.setup.outputs.release_version }}"
|
||||
commit: ${{ github.sha }}
|
||||
tag: web-v${{ needs.setup.outputs.tag_version }}
|
||||
tag: web-v${{ needs.setup.outputs.release_version }}
|
||||
body: "<insert release notes here>"
|
||||
artifacts: "apps/web/artifacts/web-${{ needs.setup.outputs.release_version }}-selfhosted-COMMERCIAL.zip,
|
||||
apps/web/artifacts/web-${{ needs.setup.outputs.release_version }}-selfhosted-open-source.zip"
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
draft: true
|
||||
|
||||
- name: Update deployment status to Success
|
||||
if: success()
|
||||
uses: chrnorm/deployment-status@07b3930847f65e71c9c6802ff5a402f6dfb46b86
|
||||
with:
|
||||
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
environment-url: http://vault.bitwarden.com
|
||||
state: 'success'
|
||||
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
|
||||
|
||||
- name: Update deployment status to Failure
|
||||
if: failure()
|
||||
uses: chrnorm/deployment-status@07b3930847f65e71c9c6802ff5a402f6dfb46b86
|
||||
with:
|
||||
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
environment-url: http://vault.bitwarden.com
|
||||
state: 'failure'
|
||||
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
|
||||
|
68
.github/workflows/version-auto-bump.yml
vendored
Normal file
68
.github/workflows/version-auto-bump.yml
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
---
|
||||
name: Version Auto Bump
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
setup:
|
||||
name: "Setup"
|
||||
runs-on: ubuntu-20.04
|
||||
outputs:
|
||||
version_number: ${{ steps.version.outputs.new-version }}
|
||||
if: contains(github.event.release.tag, 'desktop')
|
||||
steps:
|
||||
- name: Checkout Branch
|
||||
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
|
||||
|
||||
- name: Get version to bump
|
||||
id: version
|
||||
env:
|
||||
RELEASE_TAG: ${{ github.event.release.tag }}
|
||||
run: |
|
||||
|
||||
CURR_MAJOR=$(echo $RELEASE_TAG | sed -r 's/desktop-v([0-9]{4}\.[0-9]\.)([0-9])/\1/')
|
||||
CURR_VER=$(echo $RELEASE_TAG | sed -r 's/desktop-v([0-9]{4}\.[0-9]\.)([0-9])/\2/')
|
||||
echo $CURR_VER
|
||||
((CURR_VER++))
|
||||
NEW_VER=$CURR_MAJOR$CURR_VER
|
||||
echo "::set-output name=new-version::$NEW_VER"
|
||||
|
||||
trigger_version_bump:
|
||||
name: "Trigger desktop version bump workflow"
|
||||
runs-on: ubuntu-20.04
|
||||
needs:
|
||||
- setup
|
||||
steps:
|
||||
- name: Login to Azure
|
||||
uses: Azure/login@ec3c14589bd3e9312b3cc8c41e6860e258df9010
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }}
|
||||
|
||||
- name: Retrieve secrets
|
||||
id: retrieve-secrets
|
||||
env:
|
||||
KEYVAULT: bitwarden-prod-kv
|
||||
SECRET: "github-pat-bitwarden-devops-bot-repo-scope"
|
||||
run: |
|
||||
VALUE=$(az keyvault secret show --vault-name $KEYVAULT --name $SECRET --query value --output tsv)
|
||||
echo "::add-mask::$VALUE"
|
||||
echo "::set-output name=$SECRET::$VALUE"
|
||||
|
||||
- name: Call GitHub API to trigger workflow bump
|
||||
env:
|
||||
TOKEN: ${{ steps.retrieve-secrets.outputs.github-pat-bitwarden-devops-bot-repo-scope }}
|
||||
VERSION: ${{ needs.setup.outputs.version_number}}
|
||||
run: |
|
||||
JSON_STRING=$(printf '{"ref":"master", "inputs": { "client":"Desktop", "version_number":"%s"}}' "$VERSION")
|
||||
curl \
|
||||
-X POST \
|
||||
-i -u bitwarden-devops-bot:$TOKEN \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
https://api.github.com/repos/bitwarden/clients/actions/workflows/version-bump.yml/dispatches \
|
||||
-d $JSON_STRING
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -26,6 +26,7 @@ npm-debug.log
|
||||
# Build directories
|
||||
dist
|
||||
build
|
||||
.angular/cache
|
||||
|
||||
# Testing
|
||||
coverage
|
||||
|
@ -2,6 +2,7 @@
|
||||
**/build
|
||||
**/dist
|
||||
**/coverage
|
||||
.angular
|
||||
|
||||
# External libraries / auto synced locales
|
||||
apps/browser/src/_locales
|
||||
|
@ -4,7 +4,10 @@
|
||||
"types": ["node"],
|
||||
"allowSyntheticDefaultImports": true
|
||||
},
|
||||
"exclude": ["../src/test.setup.ts", "../src/**/*.spec.ts", "../projects/**/*.spec.ts"],
|
||||
"include": ["../src/**/*", "../projects/**/*"],
|
||||
"files": ["./typings.d.ts"]
|
||||
"exclude": ["../src/test.setup.ts", "../apps/src/**/*.spec.ts", "../libs/**/*.spec.ts"],
|
||||
"files": [
|
||||
"./typings.d.ts",
|
||||
"../libs/components/src/main.ts",
|
||||
"../libs/components/src/polyfills.ts"
|
||||
]
|
||||
}
|
||||
|
129
angular.json
129
angular.json
@ -3,6 +3,83 @@
|
||||
"version": 1,
|
||||
"newProjectRoot": "apps",
|
||||
"projects": {
|
||||
"web": {
|
||||
"projectType": "application",
|
||||
"schematics": {
|
||||
"@schematics/angular:application": {
|
||||
"strict": true
|
||||
}
|
||||
},
|
||||
"root": "apps/web",
|
||||
"sourceRoot": "apps/web/src",
|
||||
"prefix": "app",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"options": {
|
||||
"outputPath": "dist/web",
|
||||
"index": "apps/web/src/index.html",
|
||||
"main": "apps/web/src/app/main.ts",
|
||||
"polyfills": "apps/web/src/app/polyfills.ts",
|
||||
"tsConfig": "apps/web/tsconfig.json",
|
||||
"assets": ["apps/web/src/favicon.ico"],
|
||||
"styles": [],
|
||||
"scripts": []
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"browser": {
|
||||
"projectType": "application",
|
||||
"schematics": {
|
||||
"@schematics/angular:application": {
|
||||
"strict": true
|
||||
}
|
||||
},
|
||||
"root": "apps/browser",
|
||||
"sourceRoot": "apps/browser/src",
|
||||
"prefix": "app",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"options": {
|
||||
"outputPath": "dist/browser",
|
||||
"index": "apps/browser/src/popup/index.html",
|
||||
"main": "apps/browser/src/popup/main.ts",
|
||||
"polyfills": "apps/browser/src/popup/polyfills.ts",
|
||||
"tsConfig": "apps/browser/tsconfig.json",
|
||||
"assets": [],
|
||||
"styles": [],
|
||||
"scripts": []
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"desktop": {
|
||||
"projectType": "application",
|
||||
"schematics": {
|
||||
"@schematics/angular:application": {
|
||||
"strict": true
|
||||
}
|
||||
},
|
||||
"root": "apps/desktop",
|
||||
"sourceRoot": "apps/desktop/src",
|
||||
"prefix": "app",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"options": {
|
||||
"outputPath": "dist/desktop",
|
||||
"index": "apps/desktop/src/index.html",
|
||||
"main": "apps/desktop/src/app/main.ts",
|
||||
"tsConfig": "apps/desktop/tsconfig.json",
|
||||
"assets": [],
|
||||
"styles": [],
|
||||
"scripts": []
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"projectType": "application",
|
||||
"schematics": {
|
||||
@ -10,9 +87,9 @@
|
||||
"strict": true
|
||||
}
|
||||
},
|
||||
"root": "./libs/components",
|
||||
"root": "libs/components",
|
||||
"sourceRoot": "libs/components/src",
|
||||
"prefix": "components",
|
||||
"prefix": "bit",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
@ -31,18 +108,6 @@
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"budgets": [
|
||||
{
|
||||
"type": "initial",
|
||||
"maximumWarning": "500kb",
|
||||
"maximumError": "1mb"
|
||||
},
|
||||
{
|
||||
"type": "anyComponentStyle",
|
||||
"maximumWarning": "2kb",
|
||||
"maximumError": "4kb"
|
||||
}
|
||||
],
|
||||
"outputHashing": "all"
|
||||
},
|
||||
"development": {
|
||||
@ -60,22 +125,42 @@
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"configurations": {
|
||||
"production": {
|
||||
"browserTarget": "components:build:production"
|
||||
"browserTarget": "test-storybook:build:production"
|
||||
},
|
||||
"development": {
|
||||
"browserTarget": "components:build:development"
|
||||
"browserTarget": "test-storybook:build:development"
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "development"
|
||||
},
|
||||
"extract-i18n": {
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||
}
|
||||
}
|
||||
},
|
||||
"storybook": {
|
||||
"projectType": "application",
|
||||
"root": "libs/components",
|
||||
"sourceRoot": "libs/components/src",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"options": {
|
||||
"browserTarget": "components:build"
|
||||
"tsConfig": ".storybook/tsconfig.json",
|
||||
"styles": ["libs/components/src/styles.scss", "libs/components/src/styles.css"],
|
||||
"scripts": []
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"angular": {
|
||||
"projectType": "library",
|
||||
"root": "libs/angular",
|
||||
"sourceRoot": "libs/angular/src",
|
||||
"prefix": "app",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:ng-packagr",
|
||||
"defaultConfiguration": "production"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultProject": "components"
|
||||
}
|
||||
}
|
||||
|
@ -1339,7 +1339,7 @@
|
||||
"description": "ex. A good password. Scale: Weak -> Good -> Strong"
|
||||
},
|
||||
"weak": {
|
||||
"message": "Biguna",
|
||||
"message": "Ahula",
|
||||
"description": "ex. A weak password. Scale: Weak -> Good -> Strong"
|
||||
},
|
||||
"weakMasterPassword": {
|
||||
@ -1415,7 +1415,7 @@
|
||||
"message": "Berreskuratu elementua"
|
||||
},
|
||||
"restoreItemConfirmation": {
|
||||
"message": "Ziur zaude elementu hau ezabatu nahi duzula?"
|
||||
"message": "Ziur zaude elementu hau berreskuratu nahi duzula?"
|
||||
},
|
||||
"restoredItem": {
|
||||
"message": "Elementua berreskuratua"
|
||||
@ -1580,15 +1580,15 @@
|
||||
}
|
||||
},
|
||||
"send": {
|
||||
"message": "Bidalketa",
|
||||
"message": "Send",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"searchSends": {
|
||||
"message": "Bildalketak bilatu",
|
||||
"message": "Send-ak bilatu",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"addSend": {
|
||||
"message": "Gehitu Bidalketa",
|
||||
"message": "Gehitu Send-a",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"sendTypeText": {
|
||||
@ -1598,7 +1598,7 @@
|
||||
"message": "Fitxategia"
|
||||
},
|
||||
"allSends": {
|
||||
"message": "Bidalketa guztiak",
|
||||
"message": "Send guztiak",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"maxAccessCountReached": {
|
||||
@ -1615,7 +1615,7 @@
|
||||
"message": "Pasahitz babestua"
|
||||
},
|
||||
"copySendLink": {
|
||||
"message": "Bidalketa esteka kopiatu",
|
||||
"message": "Send esteka kopiatu",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"removePassword": {
|
||||
@ -1628,11 +1628,11 @@
|
||||
"message": "Pasahitza kendua"
|
||||
},
|
||||
"deletedSend": {
|
||||
"message": "Bidalketa ezabatua",
|
||||
"message": "Send-a ezabatua",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"sendLink": {
|
||||
"message": "Bidalketa esteka",
|
||||
"message": "Send esteka",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"disabled": {
|
||||
@ -1642,23 +1642,23 @@
|
||||
"message": "Ziur zaude pasahitz hau ezabatu nahi duzula?"
|
||||
},
|
||||
"deleteSend": {
|
||||
"message": "Ezabatu Bidalketa",
|
||||
"message": "Ezabatu Send-a",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"deleteSendConfirmation": {
|
||||
"message": "Ziur al zaude Bidalketa hau ezabatu nahi duzula?",
|
||||
"message": "Ziur al zaude Send hau ezabatu nahi duzula?",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"editSend": {
|
||||
"message": "Bidalketa editatu",
|
||||
"message": "Editatu Send-a",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"sendTypeHeader": {
|
||||
"message": "Zein Bidalketa mota da hau?",
|
||||
"message": "Zein Send mota da hau?",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"sendNameDesc": {
|
||||
"message": "Bidalketa hau deskribatzeko izena.",
|
||||
"message": "Send hau deskribatzeko izena.",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"sendFileDesc": {
|
||||
@ -1668,14 +1668,14 @@
|
||||
"message": "Ezabatze data"
|
||||
},
|
||||
"deletionDateDesc": {
|
||||
"message": "Bidalketa betiko ezabatuko da zehaztutako datan eta orduan.",
|
||||
"message": "Send-a betiko ezabatuko da zehaztutako datan eta orduan.",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"expirationDate": {
|
||||
"message": "Iraungitze data"
|
||||
},
|
||||
"expirationDateDesc": {
|
||||
"message": "Hala ezartzen bada, Bidalketa honetarako sarbidea zehaztutako egunean eta orduan amaituko da.",
|
||||
"message": "Hala ezartzen bada, Send honetarako sarbidea zehaztutako egunean eta orduan amaituko da.",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"oneDay": {
|
||||
@ -1697,56 +1697,56 @@
|
||||
"message": "Sarbide kopuru maximoa"
|
||||
},
|
||||
"maximumAccessCountDesc": {
|
||||
"message": "Hala ezartzen bada, erabiltzaileak ezin izango dira Bidalketa honetara sartu gehienezko sarbide kopurura iritsi ondoren.",
|
||||
"message": "Hala ezartzen bada, erabiltzaileak ezin izango dira Send honetara sartu gehienezko sarbide kopurura iritsi ondoren.",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"sendPasswordDesc": {
|
||||
"message": "Nahi izanez gero, pasahitza eskatu erabiltzaileak bidalketa honetara sar daitezen.",
|
||||
"message": "Nahi izanez gero, pasahitza eskatu erabiltzaileak Send honetara sar daitezen.",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"sendNotesDesc": {
|
||||
"message": "Bidalketa honi buruzko ohar pribatuak.",
|
||||
"message": "Send honi buruzko ohar pribatuak.",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"sendDisableDesc": {
|
||||
"message": "Desgaitu Bidalketa hau inor sar ez dadin.",
|
||||
"message": "Desgaitu Send hau inor sar ez dadin.",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"sendShareDesc": {
|
||||
"message": "Gordetzean, kopiatu Bidalketa honen esteka arbelean.",
|
||||
"message": "Gordetzean, kopiatu Send honen esteka arbelean.",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"sendTextDesc": {
|
||||
"message": "Bidali nahi duzun testua."
|
||||
},
|
||||
"sendHideText": {
|
||||
"message": "Ezkutatu Bidalketako testu hau, modu lehenetsian.",
|
||||
"message": "Ezkutatu Send-eko testu hau, modu lehenetsian.",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"currentAccessCount": {
|
||||
"message": "Uneko sarbide kopurua"
|
||||
},
|
||||
"createSend": {
|
||||
"message": "Sortu Bidalketa berria",
|
||||
"message": "Sortu Send berria",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Pasahitz berria"
|
||||
},
|
||||
"sendDisabled": {
|
||||
"message": "Bidalketa desgaituta",
|
||||
"message": "Send-a desgaitua",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"sendDisabledWarning": {
|
||||
"message": "Enpresa-politika baten ondorioz, lehendik dagoen Bidalketa bakarrik ezaba dezakezu.",
|
||||
"message": "Enpresa-politika baten ondorioz, lehendik dagoen Send-a bakarrik ezaba dezakezu.",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"createdSend": {
|
||||
"message": "Bidalketa sortua",
|
||||
"message": "Send-a sortua",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"editedSend": {
|
||||
"message": "Bidalketa editatua",
|
||||
"message": "Send-a editatua",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"sendLinuxChromiumFileWarning": {
|
||||
@ -1792,7 +1792,7 @@
|
||||
"message": "Ezkutatu nire helbide elektronikoa hartzaileei."
|
||||
},
|
||||
"sendOptionsPolicyInEffect": {
|
||||
"message": "Erakundeko politika batek edo gehiagok Bidalketa aukerei eragiten diote."
|
||||
"message": "Erakundeko politika batek edo gehiagok Send-eko aukerei eragiten diote."
|
||||
},
|
||||
"passwordPrompt": {
|
||||
"message": "Berriro eskatu pasahitz nagusia"
|
||||
|
@ -367,7 +367,7 @@
|
||||
"message": "Blokowanie sejfu"
|
||||
},
|
||||
"lockNow": {
|
||||
"message": "Zablokuj teraz"
|
||||
"message": "Zablokuj"
|
||||
},
|
||||
"immediately": {
|
||||
"message": "Natychmiast"
|
||||
|
@ -517,7 +517,7 @@ export default class MainBackground {
|
||||
}
|
||||
|
||||
async bootstrap() {
|
||||
this.containerService.attachToWindow(window);
|
||||
this.containerService.attachToGlobal(window);
|
||||
|
||||
await this.stateService.init();
|
||||
|
||||
|
@ -156,7 +156,7 @@ export class BrowserApi {
|
||||
|
||||
static reloadExtension(win: Window) {
|
||||
if (win != null) {
|
||||
return win.location.reload(true);
|
||||
return (win.location as any).reload(true);
|
||||
} else {
|
||||
return chrome.runtime.reload();
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ button.neutral {
|
||||
}
|
||||
}
|
||||
|
||||
@media (print) {
|
||||
@media print {
|
||||
body {
|
||||
display: none;
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
<form #form (ngSubmit)="submit()">
|
||||
<header>
|
||||
<div class="left">
|
||||
<a routerLink="/home">{{ "close" | i18n }}</a>
|
||||
<button type="button" routerLink="/home">{{ "close" | i18n }}</button>
|
||||
</div>
|
||||
<h1 class="center">
|
||||
<span class="title">{{ "appName" | i18n }}</span>
|
||||
</h1>
|
||||
<div class="right">
|
||||
<button type="submit" appBlurClick [disabled]="form.loading">
|
||||
<button type="submit" [disabled]="form.loading">
|
||||
<span [hidden]="form.loading">{{ "save" | i18n }}</span>
|
||||
<i class="bwi bwi-spinner bwi-lg bwi-spin" [hidden]="!form.loading" aria-hidden="true"></i>
|
||||
</button>
|
||||
|
@ -1,13 +1,13 @@
|
||||
<form #form (ngSubmit)="submit()" [appApiAction]="formPromise">
|
||||
<header>
|
||||
<div class="left">
|
||||
<a routerLink="/login">{{ "cancel" | i18n }}</a>
|
||||
<button type="button" routerLink="/login">{{ "cancel" | i18n }}</button>
|
||||
</div>
|
||||
<h1 class="center">
|
||||
<span class="title">{{ "passwordHint" | i18n }}</span>
|
||||
</h1>
|
||||
<div class="right">
|
||||
<button type="submit" appBlurClick [disabled]="form.loading">
|
||||
<button type="submit" [disabled]="form.loading">
|
||||
<span [hidden]="form.loading">{{ "submit" | i18n }}</span>
|
||||
<i class="bwi bwi-spinner bwi-lg bwi-spin" [hidden]="!form.loading" aria-hidden="true"></i>
|
||||
</button>
|
||||
|
@ -2,15 +2,17 @@
|
||||
<div class="content">
|
||||
<div class="logo-image"></div>
|
||||
<p class="lead text-center">{{ "loginOrCreateNewAccount" | i18n }}</p>
|
||||
<a class="btn primary block" routerLink="/login"
|
||||
><b>{{ "login" | i18n }}</b></a
|
||||
>
|
||||
<button type="button" class="btn primary block" routerLink="/login">
|
||||
<b>{{ "login" | i18n }}</b>
|
||||
</button>
|
||||
<button type="button" (click)="launchSsoBrowser()" class="btn block">
|
||||
<i class="bwi bwi-bank" aria-hidden="true"></i> {{ "enterpriseSingleSignOn" | i18n }}
|
||||
</button>
|
||||
<a class="btn block" routerLink="/register">{{ "createAccount" | i18n }}</a>
|
||||
<button type="button" class="btn block" routerLink="/register">
|
||||
{{ "createAccount" | i18n }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<a routerLink="/environment" class="settings-icon">
|
||||
<button type="button" routerLink="/environment" class="settings-icon">
|
||||
<i class="bwi bwi-cog-f bwi-lg" aria-hidden="true"></i><span> {{ "settings" | i18n }}</span>
|
||||
</a>
|
||||
</button>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<span class="title">{{ "verifyIdentity" | i18n }}</span>
|
||||
</h1>
|
||||
<div class="right">
|
||||
<button type="submit" appBlurClick *ngIf="!hideInput">{{ "unlock" | i18n }}</button>
|
||||
<button type="submit" *ngIf="!hideInput">{{ "unlock" | i18n }}</button>
|
||||
</div>
|
||||
</header>
|
||||
<main tabindex="-1">
|
||||
@ -41,7 +41,6 @@
|
||||
type="button"
|
||||
class="row-btn"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
appA11yTitle="{{ 'toggleVisibility' | i18n }}"
|
||||
(click)="togglePassword()"
|
||||
[attr.aria-pressed]="showPassword"
|
||||
|
@ -1,13 +1,13 @@
|
||||
<form #form (ngSubmit)="submit()" [appApiAction]="formPromise">
|
||||
<header>
|
||||
<div class="left">
|
||||
<a routerLink="/home">{{ "cancel" | i18n }}</a>
|
||||
<button type="button" routerLink="/home">{{ "cancel" | i18n }}</button>
|
||||
</div>
|
||||
<h1 class="center">
|
||||
<span class="title">{{ "appName" | i18n }}</span>
|
||||
</h1>
|
||||
<div class="right">
|
||||
<button type="submit" appBlurClick [disabled]="form.loading">
|
||||
<button type="submit" [disabled]="form.loading">
|
||||
<span [hidden]="form.loading">{{ "login" | i18n }}</span>
|
||||
<i class="bwi bwi-spinner bwi-lg bwi-spin" [hidden]="!form.loading" aria-hidden="true"></i>
|
||||
</button>
|
||||
@ -46,7 +46,6 @@
|
||||
type="button"
|
||||
class="row-btn"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
appA11yTitle="{{ 'toggleVisibility' | i18n }}"
|
||||
(click)="togglePassword()"
|
||||
[attr.aria-pressed]="showPassword"
|
||||
@ -65,7 +64,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-center">
|
||||
<a routerLink="/hint">{{ "getMasterPasswordHint" | i18n }}</a>
|
||||
<button type="button" routerLink="/hint">{{ "getMasterPasswordHint" | i18n }}</button>
|
||||
</p>
|
||||
<app-private-mode-warning></app-private-mode-warning>
|
||||
</main>
|
||||
|
@ -1,13 +1,13 @@
|
||||
<form #form (ngSubmit)="submit()" [appApiAction]="formPromise" [formGroup]="formGroup">
|
||||
<header>
|
||||
<div class="left">
|
||||
<a routerLink="/home">{{ "cancel" | i18n }}</a>
|
||||
<button type="button" routerLink="/home">{{ "cancel" | i18n }}</button>
|
||||
</div>
|
||||
<h1 class="center">
|
||||
<span class="title">{{ "createAccount" | i18n }}</span>
|
||||
</h1>
|
||||
<div class="right">
|
||||
<button type="submit" appBlurClick [disabled]="form.loading">
|
||||
<button type="submit" [disabled]="form.loading">
|
||||
<span [hidden]="form.loading">{{ "submit" | i18n }}</span>
|
||||
<i class="bwi bwi-spinner bwi-lg bwi-spin" [hidden]="!form.loading" aria-hidden="true"></i>
|
||||
</button>
|
||||
@ -25,11 +25,8 @@
|
||||
<div class="row-main">
|
||||
<label for="masterPassword">
|
||||
{{ "masterPass" | i18n }}
|
||||
<strong
|
||||
class="sub-label text-{{ masterPasswordScoreColor }}"
|
||||
*ngIf="masterPasswordScoreText"
|
||||
>
|
||||
{{ masterPasswordScoreText }}
|
||||
<strong class="sub-label text-{{ color }}" *ngIf="text">
|
||||
{{ text }}
|
||||
</strong>
|
||||
</label>
|
||||
<input
|
||||
@ -38,7 +35,6 @@
|
||||
class="monospaced"
|
||||
formControlName="masterPassword"
|
||||
appInputVerbatim
|
||||
(input)="updatePasswordStrength()"
|
||||
/>
|
||||
</div>
|
||||
<div class="action-buttons">
|
||||
@ -46,7 +42,6 @@
|
||||
type="button"
|
||||
class="row-btn"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
appA11yTitle="{{ 'toggleVisibility' | i18n }}"
|
||||
(click)="togglePassword()"
|
||||
[attr.aria-pressed]="showPassword"
|
||||
@ -59,17 +54,14 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress">
|
||||
<div
|
||||
class="progress-bar bg-{{ masterPasswordScoreColor }}"
|
||||
role="progressbar"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
[ngStyle]="{ width: masterPasswordScoreWidth + '%' }"
|
||||
attr.aria-valuenow="{{ masterPasswordScoreWidth }}"
|
||||
></div>
|
||||
</div>
|
||||
<app-password-strength
|
||||
[password]="formGroup.get('masterPassword')?.value"
|
||||
[email]="formGroup.get('email')?.value"
|
||||
[name]="formGroup.get('name')?.value"
|
||||
(passwordStrengthResult)="getStrengthResult($event)"
|
||||
(passwordScoreColor)="getPasswordScoreText($event)"
|
||||
>
|
||||
</app-password-strength>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
@ -94,7 +86,6 @@
|
||||
type="button"
|
||||
class="row-btn"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
appA11yTitle="{{ 'toggleVisibility' | i18n }}"
|
||||
(click)="togglePassword()"
|
||||
[attr.aria-pressed]="showPassword"
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Component } from "@angular/core";
|
||||
import { FormBuilder } from "@angular/forms";
|
||||
import { UntypedFormBuilder } from "@angular/forms";
|
||||
import { Router } from "@angular/router";
|
||||
|
||||
import { RegisterComponent as BaseRegisterComponent } from "@bitwarden/angular/components/register.component";
|
||||
@ -19,9 +19,12 @@ import { StateService } from "@bitwarden/common/abstractions/state.service";
|
||||
templateUrl: "register.component.html",
|
||||
})
|
||||
export class RegisterComponent extends BaseRegisterComponent {
|
||||
color: string;
|
||||
text: string;
|
||||
|
||||
constructor(
|
||||
formValidationErrorService: FormValidationErrorsService,
|
||||
formBuilder: FormBuilder,
|
||||
formBuilder: UntypedFormBuilder,
|
||||
authService: AuthService,
|
||||
router: Router,
|
||||
i18nService: I18nService,
|
||||
|
@ -1,13 +1,13 @@
|
||||
<form #form (ngSubmit)="submit()" [appApiAction]="formPromise">
|
||||
<header>
|
||||
<div class="left">
|
||||
<a routerLink="/home">{{ "cancel" | i18n }}</a>
|
||||
<button type="button" routerLink="/home">{{ "cancel" | i18n }}</button>
|
||||
</div>
|
||||
<h1 class="center">
|
||||
<span class="title">{{ "setMasterPassword" | i18n }}</span>
|
||||
</h1>
|
||||
<div class="right">
|
||||
<button type="submit" appBlurClick [disabled]="form.loading">
|
||||
<button type="submit" [disabled]="form.loading">
|
||||
<span [hidden]="form.loading">{{ "submit" | i18n }}</span>
|
||||
<i class="bwi bwi-spinner bwi-lg bwi-spin" [hidden]="!form.loading" aria-hidden="true"></i>
|
||||
</button>
|
||||
@ -42,10 +42,10 @@
|
||||
<label for="masterPassword"
|
||||
>{{ "masterPass" | i18n }}
|
||||
<strong
|
||||
class="sub-label text-{{ masterPasswordScoreColor }}"
|
||||
*ngIf="masterPasswordScoreText"
|
||||
class="sub-label text-{{ passwordStrengthComponent?.masterPasswordScoreColor }}"
|
||||
*ngIf="passwordStrengthComponent?.masterPasswordScoreText"
|
||||
>
|
||||
{{ masterPasswordScoreText }}
|
||||
{{ passwordStrengthComponent?.masterPasswordScoreText }}
|
||||
</strong>
|
||||
</label>
|
||||
<input
|
||||
@ -55,7 +55,6 @@
|
||||
class="monospaced"
|
||||
[(ngModel)]="masterPassword"
|
||||
required
|
||||
(input)="updatePasswordStrength()"
|
||||
appInputVerbatim
|
||||
/>
|
||||
</div>
|
||||
@ -64,7 +63,6 @@
|
||||
type="button"
|
||||
class="row-btn"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
appA11yTitle="{{ 'toggleVisibility' | i18n }}"
|
||||
(click)="togglePassword(false)"
|
||||
[attr.aria-pressed]="showPassword"
|
||||
@ -77,17 +75,14 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress">
|
||||
<div
|
||||
class="progress-bar bg-{{ masterPasswordScoreColor }}"
|
||||
role="progressbar"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
[ngStyle]="{ width: masterPasswordScoreWidth + '%' }"
|
||||
attr.aria-valuenow="{{ masterPasswordScoreWidth }}"
|
||||
></div>
|
||||
</div>
|
||||
|
||||
<app-password-strength
|
||||
[password]="masterPassword"
|
||||
[email]="email"
|
||||
(passwordStrengthResult)="getStrengthResult($event)"
|
||||
(passwordScoreColor)="getPasswordScoreText($event)"
|
||||
>
|
||||
</app-password-strength>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
@ -116,7 +111,6 @@
|
||||
type="button"
|
||||
class="row-btn"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
appA11yTitle="{{ 'toggleVisibility' | i18n }}"
|
||||
(click)="togglePassword(true)"
|
||||
[attr.aria-pressed]="showPassword"
|
||||
|
@ -44,34 +44,4 @@ export class SetPasswordComponent extends BaseSetPasswordComponent {
|
||||
stateService
|
||||
);
|
||||
}
|
||||
|
||||
get masterPasswordScoreWidth() {
|
||||
return this.masterPasswordScore == null ? 0 : (this.masterPasswordScore + 1) * 20;
|
||||
}
|
||||
|
||||
get masterPasswordScoreColor() {
|
||||
switch (this.masterPasswordScore) {
|
||||
case 4:
|
||||
return "success";
|
||||
case 3:
|
||||
return "primary";
|
||||
case 2:
|
||||
return "warning";
|
||||
default:
|
||||
return "danger";
|
||||
}
|
||||
}
|
||||
|
||||
get masterPasswordScoreText() {
|
||||
switch (this.masterPasswordScore) {
|
||||
case 4:
|
||||
return this.i18nService.t("strong");
|
||||
case 3:
|
||||
return this.i18nService.t("good");
|
||||
case 2:
|
||||
return this.i18nService.t("weak");
|
||||
default:
|
||||
return this.masterPasswordScore != null ? this.i18nService.t("weak") : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
<header>
|
||||
<div class="left">
|
||||
<a routerLink="/2fa">{{ "close" | i18n }}</a>
|
||||
<button type="button" routerLink="/2fa">{{ "close" | i18n }}</button>
|
||||
</div>
|
||||
<h1 class="center">
|
||||
<span class="title">{{ "twoStepOptions" | i18n }}</span>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<form id="two-factor-page" #form (ngSubmit)="submit()" [appApiAction]="formPromise">
|
||||
<header>
|
||||
<div class="left">
|
||||
<a routerLink="/login">{{ "back" | i18n }}</a>
|
||||
<button type="button" routerLink="/login">{{ "back" | i18n }}</button>
|
||||
</div>
|
||||
<h1 class="center">
|
||||
<span class="title">{{ title }}</span>
|
||||
@ -9,7 +9,6 @@
|
||||
<div class="right">
|
||||
<button
|
||||
type="submit"
|
||||
appBlurClick
|
||||
[disabled]="form.loading"
|
||||
*ngIf="
|
||||
selectedProviderType != null &&
|
||||
|
@ -7,7 +7,7 @@
|
||||
<span class="title">{{ "updateMasterPassword" | i18n }}</span>
|
||||
</h1>
|
||||
<div class="right">
|
||||
<button type="submit" appBlurClick [disabled]="form.loading">
|
||||
<button type="submit" [disabled]="form.loading">
|
||||
<span [hidden]="form.loading">{{ "submit" | i18n }}</span>
|
||||
<i class="bwi bwi-spinner bwi-lg bwi-spin" [hidden]="!form.loading" aria-hidden="true"></i>
|
||||
</button>
|
||||
@ -30,11 +30,8 @@
|
||||
<div class="row-main">
|
||||
<label for="masterPassword">
|
||||
{{ "masterPass" | i18n }}
|
||||
<strong
|
||||
class="sub-label text-{{ masterPasswordScoreStyle.Color }}"
|
||||
*ngIf="masterPasswordScoreStyle.Text"
|
||||
>
|
||||
{{ masterPasswordScoreStyle.Text }}
|
||||
<strong class="sub-label text-{{ color }}" *ngIf="text">
|
||||
{{ text }}
|
||||
</strong>
|
||||
</label>
|
||||
<input
|
||||
@ -45,7 +42,6 @@
|
||||
[(ngModel)]="masterPassword"
|
||||
required
|
||||
appInputVerbatim
|
||||
(input)="updatePasswordStrength()"
|
||||
/>
|
||||
</div>
|
||||
<div class="action-buttons">
|
||||
@ -53,7 +49,6 @@
|
||||
type="button"
|
||||
class="row-btn"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
appA11yTitle="{{ 'toggleVisibility' | i18n }}"
|
||||
(click)="togglePassword(false)"
|
||||
[attr.aria-pressed]="showPassword"
|
||||
@ -66,17 +61,13 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress">
|
||||
<div
|
||||
class="progress-bar bg-{{ masterPasswordScoreStyle.Color }}"
|
||||
role="progressbar"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
[ngStyle]="{ width: masterPasswordScoreStyle.Width + '%' }"
|
||||
attr.aria-valuenow="{{ masterPasswordScoreStyle.Width }}"
|
||||
></div>
|
||||
</div>
|
||||
<app-password-strength
|
||||
[password]="masterPassword"
|
||||
[email]="email"
|
||||
(passwordStrengthResult)="getStrengthResult($event)"
|
||||
(passwordScoreColor)="getPasswordScoreText($event)"
|
||||
>
|
||||
</app-password-strength>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -100,7 +91,6 @@
|
||||
type="button"
|
||||
class="row-btn"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
appA11yTitle="{{ 'toggleVisibility' | i18n }}"
|
||||
(click)="togglePassword(true)"
|
||||
[attr.aria-pressed]="showPassword"
|
||||
|
@ -12,47 +12,11 @@ import { PolicyService } from "@bitwarden/common/abstractions/policy.service";
|
||||
import { StateService } from "@bitwarden/common/abstractions/state.service";
|
||||
import { SyncService } from "@bitwarden/common/abstractions/sync.service";
|
||||
|
||||
interface MasterPasswordScore {
|
||||
Color: string;
|
||||
Text: string;
|
||||
Width: number;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: "app-update-temp-password",
|
||||
templateUrl: "update-temp-password.component.html",
|
||||
})
|
||||
export class UpdateTempPasswordComponent extends BaseUpdateTempPasswordComponent {
|
||||
get masterPasswordScoreStyle(): MasterPasswordScore {
|
||||
const scoreWidth = this.masterPasswordScore == null ? 0 : (this.masterPasswordScore + 1) * 20;
|
||||
switch (this.masterPasswordScore) {
|
||||
case 4:
|
||||
return {
|
||||
Color: "bg-success",
|
||||
Text: "strong",
|
||||
Width: scoreWidth,
|
||||
};
|
||||
case 3:
|
||||
return {
|
||||
Color: "bg-primary",
|
||||
Text: "good",
|
||||
Width: scoreWidth,
|
||||
};
|
||||
case 2:
|
||||
return {
|
||||
Color: "bg-warning",
|
||||
Text: "weak",
|
||||
Width: scoreWidth,
|
||||
};
|
||||
default:
|
||||
return {
|
||||
Color: "bg-danger",
|
||||
Text: "weak",
|
||||
Width: scoreWidth,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
constructor(
|
||||
i18nService: I18nService,
|
||||
platformUtilsService: PlatformUtilsService,
|
||||
|
@ -239,7 +239,6 @@ registerLocaleData(localeZhTw, "zh-TW");
|
||||
RemovePasswordComponent,
|
||||
VaultSelectComponent,
|
||||
],
|
||||
entryComponents: [],
|
||||
providers: [CurrencyPipe, DatePipe],
|
||||
bootstrap: [AppComponent],
|
||||
})
|
||||
|
@ -23,7 +23,6 @@
|
||||
type="button"
|
||||
class="row-btn"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
appA11yTitle="{{ 'toggleVisibility' | i18n }}"
|
||||
(click)="togglePassword()"
|
||||
[attr.aria-pressed]="showPassword"
|
||||
@ -43,7 +42,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" class="btn btn-primary btn-submit" appBlurClick>
|
||||
<button type="submit" class="btn btn-primary btn-submit">
|
||||
<span>{{ "ok" | i18n }}</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-secondary" data-dismiss="modal">
|
||||
|
@ -25,7 +25,6 @@
|
||||
type="button"
|
||||
class="row-btn"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
appA11yTitle="{{ 'toggleVisibility' | i18n }}"
|
||||
(click)="toggleVisibility()"
|
||||
[attr.aria-pressed]="showPin"
|
||||
@ -53,7 +52,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" class="btn btn-primary btn-submit" appBlurClick>
|
||||
<button type="submit" class="btn btn-primary btn-submit">
|
||||
<span>{{ "ok" | i18n }}</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-secondary" data-dismiss="modal">
|
||||
|
@ -1,7 +1,7 @@
|
||||
<header>
|
||||
<div class="left">
|
||||
<app-pop-out [show]="!comingFromAddEdit"></app-pop-out>
|
||||
<button type="button" appBlurClick (click)="close()" *ngIf="comingFromAddEdit">
|
||||
<button type="button" (click)="close()" *ngIf="comingFromAddEdit">
|
||||
{{ "cancel" | i18n }}
|
||||
</button>
|
||||
</div>
|
||||
@ -9,7 +9,7 @@
|
||||
<span class="title">{{ "generator" | i18n }}</span>
|
||||
</h1>
|
||||
<div class="right">
|
||||
<button type="button" appBlurClick (click)="select()" *ngIf="comingFromAddEdit">
|
||||
<button type="button" (click)="select()" *ngIf="comingFromAddEdit">
|
||||
{{ "select" | i18n }}
|
||||
</button>
|
||||
</div>
|
||||
@ -33,7 +33,6 @@
|
||||
<button
|
||||
type="button"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
appA11yTitle="{{ 'regeneratePassword' | i18n }}"
|
||||
(click)="regenerate()"
|
||||
>
|
||||
@ -56,7 +55,6 @@
|
||||
<button
|
||||
type="button"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
appA11yTitle="{{ 'regenerateUsername' | i18n }}"
|
||||
(click)="regenerate()"
|
||||
[disabled]="form.loading"
|
||||
|
@ -1,6 +1,6 @@
|
||||
<header>
|
||||
<div class="left">
|
||||
<button type="button" appBlurClick type="button" (click)="close()">
|
||||
<button type="button" type="button" (click)="close()">
|
||||
<span class="header-icon" aria-hidden="true"><i class="bwi bwi-angle-left"></i></span>
|
||||
<span>{{ "back" | i18n }}</span>
|
||||
</button>
|
||||
@ -9,7 +9,7 @@
|
||||
<span class="title">{{ "passwordHistory" | i18n }}</span>
|
||||
</h1>
|
||||
<div class="right">
|
||||
<button type="button" appBlurClick type="button" (click)="clear()">
|
||||
<button type="button" type="button" (click)="clear()">
|
||||
{{ "clear" | i18n }}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -1,4 +1,3 @@
|
||||
import "core-js/stable";
|
||||
import "date-input-polyfill";
|
||||
import "web-animations-js";
|
||||
import "zone.js/dist/zone";
|
||||
|
@ -56,7 +56,7 @@ app-home {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
a.settings-icon {
|
||||
button.settings-icon {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
|
@ -11,4 +11,4 @@
|
||||
@import "plugins.scss";
|
||||
@import "environment.scss";
|
||||
@import "pages.scss";
|
||||
@import "~@angular/cdk/overlay-prebuilt.css";
|
||||
@import "@angular/cdk/overlay-prebuilt.css";
|
||||
|
@ -1,13 +1,13 @@
|
||||
<form #form (ngSubmit)="submit()" [appApiAction]="formPromise">
|
||||
<header>
|
||||
<div class="left">
|
||||
<button type="button" appBlurClick (click)="cancel()">{{ "cancel" | i18n }}</button>
|
||||
<button type="button" (click)="cancel()">{{ "cancel" | i18n }}</button>
|
||||
</div>
|
||||
<h1 class="center">
|
||||
<span class="title">{{ title }}</span>
|
||||
</h1>
|
||||
<div class="right">
|
||||
<button type="submit" appBlurClick [disabled]="form.loading || disableSend">
|
||||
<button type="submit" [disabled]="form.loading || disableSend">
|
||||
<span [hidden]="form.loading">{{ "save" | i18n }}</span>
|
||||
<i class="bwi bwi-spinner bwi-lg bwi-spin" [hidden]="!form.loading" aria-hidden="true"></i>
|
||||
</button>
|
||||
@ -226,7 +226,6 @@
|
||||
type="button"
|
||||
class="row-btn"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
appA11yTitle="{{ 'toggleVisibility' | i18n }}"
|
||||
(click)="togglePasswordVisible()"
|
||||
[attr.aria-pressed]="showPassword"
|
||||
@ -300,7 +299,6 @@
|
||||
type="button"
|
||||
class="box-content-row"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="delete()"
|
||||
[appApiAction]="deletePromise"
|
||||
#deleteBtn
|
||||
|
@ -18,7 +18,6 @@
|
||||
<div class="right">
|
||||
<button
|
||||
type="button"
|
||||
appBlurClick
|
||||
(click)="addSend()"
|
||||
appA11yTitle="{{ 'addSend' | i18n }}"
|
||||
[disabled]="disableSend"
|
||||
@ -56,7 +55,6 @@
|
||||
type="button"
|
||||
class="box-content-row"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="selectType(sendType.Text)"
|
||||
>
|
||||
<div class="row-main">
|
||||
@ -70,7 +68,6 @@
|
||||
type="button"
|
||||
class="box-content-row"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="selectType(sendType.File)"
|
||||
>
|
||||
<div class="row-main">
|
||||
|
@ -1,6 +1,6 @@
|
||||
<header>
|
||||
<div class="left">
|
||||
<button type="button" appBlurClick (click)="back()">
|
||||
<button type="button" (click)="back()">
|
||||
<span class="header-icon"><i class="bwi bwi-angle-left" aria-hidden="true"></i></span>
|
||||
<span>{{ "back" | i18n }}</span>
|
||||
</button>
|
||||
@ -21,7 +21,6 @@
|
||||
<div class="right">
|
||||
<button
|
||||
type="button"
|
||||
appBlurClick
|
||||
(click)="addSend()"
|
||||
appA11yTitle="{{ 'addSend' | i18n }}"
|
||||
[disabled]="disableSend"
|
||||
|
@ -1,16 +1,16 @@
|
||||
<form #form (ngSubmit)="submit()">
|
||||
<header>
|
||||
<div class="left">
|
||||
<a routerLink="/tabs/settings">
|
||||
<button type="button" routerLink="/tabs/settings">
|
||||
<span class="header-icon"><i class="bwi bwi-angle-left" aria-hidden="true"></i></span>
|
||||
<span>{{ "back" | i18n }}</span>
|
||||
</a>
|
||||
</button>
|
||||
</div>
|
||||
<h1 class="center">
|
||||
<span class="title">{{ "excludedDomains" | i18n }}</span>
|
||||
</h1>
|
||||
<div class="right">
|
||||
<button type="submit" appBlurClick>{{ "save" | i18n }}</button>
|
||||
<button type="submit">{{ "save" | i18n }}</button>
|
||||
</div>
|
||||
</header>
|
||||
<main tabindex="-1">
|
||||
@ -73,7 +73,6 @@
|
||||
<button
|
||||
type="button"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="addUri()"
|
||||
class="box-content-row box-content-row-newmulti"
|
||||
>
|
||||
|
@ -22,6 +22,7 @@ const BroadcasterSubscriptionId = "excludedDomains";
|
||||
})
|
||||
export class ExcludedDomainsComponent implements OnInit, OnDestroy {
|
||||
excludedDomains: ExcludedDomain[] = [];
|
||||
existingExcludedDomains: ExcludedDomain[] = [];
|
||||
currentUris: string[];
|
||||
loadCurrentUrisTimeout: number;
|
||||
|
||||
@ -39,6 +40,7 @@ export class ExcludedDomainsComponent implements OnInit, OnDestroy {
|
||||
if (savedDomains) {
|
||||
for (const uri of Object.keys(savedDomains)) {
|
||||
this.excludedDomains.push({ uri: uri, showCurrentUris: false });
|
||||
this.existingExcludedDomains.push({ uri: uri, showCurrentUris: false });
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,20 +80,27 @@ export class ExcludedDomainsComponent implements OnInit, OnDestroy {
|
||||
|
||||
async submit() {
|
||||
const savedDomains: { [name: string]: null } = {};
|
||||
const newExcludedDomains = this.getNewlyAddedDomians(this.excludedDomains);
|
||||
for (const domain of this.excludedDomains) {
|
||||
if (domain.uri && domain.uri !== "") {
|
||||
const validDomain = Utils.getHostname(domain.uri);
|
||||
if (!validDomain) {
|
||||
this.platformUtilsService.showToast(
|
||||
"error",
|
||||
null,
|
||||
this.i18nService.t("excludedDomainsInvalidDomain", domain.uri)
|
||||
);
|
||||
return;
|
||||
const resp = newExcludedDomains.filter((e) => e.uri === domain.uri);
|
||||
if (resp.length === 0) {
|
||||
savedDomains[domain.uri] = null;
|
||||
} else {
|
||||
if (domain.uri && domain.uri !== "") {
|
||||
const validDomain = Utils.getHostname(domain.uri);
|
||||
if (!validDomain) {
|
||||
this.platformUtilsService.showToast(
|
||||
"error",
|
||||
null,
|
||||
this.i18nService.t("excludedDomainsInvalidDomain", domain.uri)
|
||||
);
|
||||
return;
|
||||
}
|
||||
savedDomains[validDomain] = null;
|
||||
}
|
||||
savedDomains[validDomain] = null;
|
||||
}
|
||||
}
|
||||
|
||||
await this.stateService.setNeverDomains(savedDomains);
|
||||
this.router.navigate(["/tabs/settings"]);
|
||||
}
|
||||
@ -100,6 +109,14 @@ export class ExcludedDomainsComponent implements OnInit, OnDestroy {
|
||||
return index;
|
||||
}
|
||||
|
||||
getNewlyAddedDomians(domain: ExcludedDomain[]): ExcludedDomain[] {
|
||||
const result = this.excludedDomains.filter(
|
||||
(newDomain) =>
|
||||
!this.existingExcludedDomains.some((oldDomain) => newDomain.uri === oldDomain.uri)
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
||||
toggleUriInput(domain: ExcludedDomain) {
|
||||
domain.showCurrentUris = !domain.showCurrentUris;
|
||||
}
|
||||
|
@ -1,16 +1,16 @@
|
||||
<form (ngSubmit)="submit()" [formGroup]="exportForm">
|
||||
<header>
|
||||
<div class="left">
|
||||
<a routerLink="/tabs/settings">
|
||||
<button type="button" routerLink="/tabs/settings">
|
||||
<span class="header-icon" aria-hidden="true"><i class="bwi bwi-angle-left"></i></span>
|
||||
<span>{{ "back" | i18n }}</span>
|
||||
</a>
|
||||
</button>
|
||||
</div>
|
||||
<h1 class="center">
|
||||
<span class="title">{{ "exportVault" | i18n }}</span>
|
||||
</h1>
|
||||
<div class="right">
|
||||
<button appBlurClick type="submit" [disabled]="!exportForm.enabled">
|
||||
<button type="submit" [disabled]="!exportForm.enabled">
|
||||
{{ "submit" | i18n }}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Component } from "@angular/core";
|
||||
import { FormBuilder } from "@angular/forms";
|
||||
import { UntypedFormBuilder } from "@angular/forms";
|
||||
import { Router } from "@angular/router";
|
||||
|
||||
import { ExportComponent as BaseExportComponent } from "@bitwarden/angular/components/export.component";
|
||||
@ -28,7 +28,7 @@ export class ExportComponent extends BaseExportComponent {
|
||||
private router: Router,
|
||||
logService: LogService,
|
||||
userVerificationService: UserVerificationService,
|
||||
formBuilder: FormBuilder,
|
||||
formBuilder: UntypedFormBuilder,
|
||||
fileDownloadService: FileDownloadService
|
||||
) {
|
||||
super(
|
||||
|
@ -1,13 +1,13 @@
|
||||
<form #form (ngSubmit)="submit()" [appApiAction]="formPromise">
|
||||
<header>
|
||||
<div class="left">
|
||||
<a routerLink="/folders">{{ "cancel" | i18n }}</a>
|
||||
<button type="button" routerLink="/folders">{{ "cancel" | i18n }}</button>
|
||||
</div>
|
||||
<h1 class="center">
|
||||
<span class="title">{{ title }}</span>
|
||||
</h1>
|
||||
<div class="right">
|
||||
<button type="submit" appBlurClick [disabled]="form.loading">
|
||||
<button type="submit" [disabled]="form.loading">
|
||||
<span [hidden]="form.loading">{{ "save" | i18n }}</span>
|
||||
<i class="bwi bwi-spinner bwi-lg bwi-spin" [hidden]="!form.loading" aria-hidden="true"></i>
|
||||
</button>
|
||||
@ -34,7 +34,6 @@
|
||||
type="button"
|
||||
class="box-content-row"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="delete()"
|
||||
[appApiAction]="deletePromise"
|
||||
#deleteBtn
|
||||
|
@ -1,20 +1,15 @@
|
||||
<header>
|
||||
<div class="left">
|
||||
<a routerLink="/tabs/settings">
|
||||
<button type="button" routerLink="/tabs/settings">
|
||||
<span class="header-icon"><i class="bwi bwi-angle-left" aria-hidden="true"></i></span>
|
||||
<span>{{ "back" | i18n }}</span>
|
||||
</a>
|
||||
</button>
|
||||
</div>
|
||||
<h1 class="center">
|
||||
<span class="title">{{ "folders" | i18n }}</span>
|
||||
</h1>
|
||||
<div class="right">
|
||||
<button
|
||||
type="button"
|
||||
appBlurClick
|
||||
(click)="addFolder()"
|
||||
appA11yTitle="{{ 'addFolder' | i18n }}"
|
||||
>
|
||||
<button type="button" (click)="addFolder()" appA11yTitle="{{ 'addFolder' | i18n }}">
|
||||
<i class="bwi bwi-plus bwi-lg bwi-fw" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -1,9 +1,9 @@
|
||||
<header>
|
||||
<div class="left">
|
||||
<a routerLink="/tabs/settings">
|
||||
<button type="button" routerLink="/tabs/settings">
|
||||
<span class="header-icon"><i class="bwi bwi-angle-left" aria-hidden="true"></i></span>
|
||||
<span>{{ "back" | i18n }}</span>
|
||||
</a>
|
||||
</button>
|
||||
</div>
|
||||
<h1 class="center">
|
||||
<span class="title">{{ "options" | i18n }}</span>
|
||||
|
@ -1,9 +1,9 @@
|
||||
<header>
|
||||
<div class="left">
|
||||
<a routerLink="/tabs/settings">
|
||||
<button type="button" routerLink="/tabs/settings">
|
||||
<span class="header-icon"><i class="bwi bwi-angle-left" aria-hidden="true"></i></span>
|
||||
<span>{{ "back" | i18n }}</span>
|
||||
</a>
|
||||
</button>
|
||||
</div>
|
||||
<h1 class="center">
|
||||
<span class="title">{{ "premiumMembership" | i18n }}</span>
|
||||
@ -42,13 +42,12 @@
|
||||
</li>
|
||||
</ul>
|
||||
<p class="text-center lead">{{ priceString }}</p>
|
||||
<button type="button" class="btn primary block" appBlurClick (click)="purchase()">
|
||||
<button type="button" class="btn primary block" (click)="purchase()">
|
||||
<b>{{ "premiumPurchase" | i18n }}</b>
|
||||
</button>
|
||||
<button
|
||||
#refreshBtn
|
||||
type="button"
|
||||
appBlurClick
|
||||
(click)="refresh()"
|
||||
[disabled]="refreshBtn.loading"
|
||||
[appApiAction]="refreshPromise"
|
||||
@ -65,7 +64,7 @@
|
||||
<ng-container *ngIf="isPremium">
|
||||
<p class="text-center lead">{{ "premiumCurrentMember" | i18n }}</p>
|
||||
<p class="text-center">{{ "premiumCurrentMemberThanks" | i18n }}</p>
|
||||
<button type="button" class="btn block primary" appBlurClick (click)="manage()">
|
||||
<button type="button" class="btn block primary" (click)="manage()">
|
||||
<b>{{ "premiumManage" | i18n }}</b>
|
||||
</button>
|
||||
</ng-container>
|
||||
|
@ -11,18 +11,30 @@
|
||||
<div class="box list">
|
||||
<h2 class="box-header">{{ "manage" | i18n }}</h2>
|
||||
<div class="box-content single-line">
|
||||
<a class="box-content-row box-content-row-flex text-default" routerLink="/folders">
|
||||
<button
|
||||
type="button"
|
||||
class="box-content-row box-content-row-flex text-default"
|
||||
routerLink="/folders"
|
||||
>
|
||||
<div class="row-main">{{ "folders" | i18n }}</div>
|
||||
<i class="bwi bwi-angle-right bwi-lg row-sub-icon" aria-hidden="true"></i>
|
||||
</a>
|
||||
<a class="box-content-row box-content-row-flex text-default" routerLink="/sync">
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="box-content-row box-content-row-flex text-default"
|
||||
routerLink="/sync"
|
||||
>
|
||||
<div class="row-main">{{ "sync" | i18n }}</div>
|
||||
<i class="bwi bwi-angle-right bwi-lg row-sub-icon" aria-hidden="true"></i>
|
||||
</a>
|
||||
<a class="box-content-row box-content-row-flex text-default" routerLink="/excluded-domains">
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="box-content-row box-content-row-flex text-default"
|
||||
routerLink="/excluded-domains"
|
||||
>
|
||||
<div class="row-main">{{ "excludedDomains" | i18n }}</div>
|
||||
<i class="bwi bwi-angle-right bwi-lg row-sub-icon" aria-hidden="true"></i>
|
||||
</a>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box list">
|
||||
@ -77,7 +89,6 @@
|
||||
type="button"
|
||||
class="box-content-row box-content-row-flex text-default"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="lock()"
|
||||
>
|
||||
<div class="row-main">{{ "lockNow" | i18n }}</div>
|
||||
@ -87,7 +98,6 @@
|
||||
type="button"
|
||||
class="box-content-row box-content-row-flex text-default"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="twoStep()"
|
||||
>
|
||||
<div class="row-main">{{ "twoStepLogin" | i18n }}</div>
|
||||
@ -98,7 +108,7 @@
|
||||
<div class="box list">
|
||||
<h2 class="box-header">{{ "account" | i18n }}</h2>
|
||||
<div class="box-content single-line">
|
||||
<a class="box-content-row" routerLink="/premium">
|
||||
<button type="button" class="box-content-row" routerLink="/premium">
|
||||
<div class="row-main">
|
||||
<div class="icon text-primary">
|
||||
<i class="bwi bwi-fw bwi-lg bwi-star-f" aria-hidden="true"></i>
|
||||
@ -108,12 +118,11 @@
|
||||
>
|
||||
</div>
|
||||
<span><i class="bwi bwi-angle-right bwi-lg row-sub-icon" aria-hidden="true"></i></span>
|
||||
</a>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="box-content-row box-content-row-flex text-default"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="changePassword()"
|
||||
*ngIf="showChangeMasterPass"
|
||||
>
|
||||
@ -124,7 +133,6 @@
|
||||
type="button"
|
||||
class="box-content-row box-content-row-flex text-default"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="fingerprint()"
|
||||
>
|
||||
<div class="row-main">{{ "fingerprintPhrase" | i18n }}</div>
|
||||
@ -134,7 +142,6 @@
|
||||
type="button"
|
||||
class="box-content-row box-content-row-flex text-default"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="logOut()"
|
||||
>
|
||||
<div class="row-main">{{ "logOut" | i18n }}</div>
|
||||
@ -149,7 +156,6 @@
|
||||
type="button"
|
||||
class="box-content-row box-content-row-flex text-default"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="import()"
|
||||
>
|
||||
<div class="row-main">{{ "importItems" | i18n }}</div>
|
||||
@ -159,7 +165,6 @@
|
||||
type="button"
|
||||
class="box-content-row box-content-row-flex text-default"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="export()"
|
||||
>
|
||||
<div class="row-main">{{ "exportVault" | i18n }}</div>
|
||||
@ -169,7 +174,6 @@
|
||||
type="button"
|
||||
class="box-content-row box-content-row-flex text-default"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="webVault()"
|
||||
>
|
||||
<div class="row-main">{{ "bitWebVault" | i18n }}</div>
|
||||
@ -180,15 +184,18 @@
|
||||
<div class="box list">
|
||||
<h2 class="box-header">{{ "other" | i18n }}</h2>
|
||||
<div class="box-content single-line">
|
||||
<a class="box-content-row box-content-row-flex text-default" routerLink="/options">
|
||||
<button
|
||||
type="button"
|
||||
class="box-content-row box-content-row-flex text-default"
|
||||
routerLink="/options"
|
||||
>
|
||||
<div class="row-main">{{ "options" | i18n }}</div>
|
||||
<i class="bwi bwi-angle-right bwi-lg row-sub-icon" aria-hidden="true"></i>
|
||||
</a>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="box-content-row box-content-row-flex text-default"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="about()"
|
||||
>
|
||||
<div class="row-main">{{ "about" | i18n }}</div>
|
||||
@ -198,7 +205,6 @@
|
||||
type="button"
|
||||
class="box-content-row box-content-row-flex text-default"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="share()"
|
||||
>
|
||||
<div class="row-main">{{ "learnOrg" | i18n }}</div>
|
||||
@ -208,7 +214,6 @@
|
||||
type="button"
|
||||
class="box-content-row box-content-row-flex text-default"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="help()"
|
||||
>
|
||||
<div class="row-main">{{ "helpFeedback" | i18n }}</div>
|
||||
@ -218,7 +223,6 @@
|
||||
type="button"
|
||||
class="box-content-row box-content-row-flex text-default"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="rate()"
|
||||
>
|
||||
<div class="row-main">{{ "rateExtension" | i18n }}</div>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Component, ElementRef, OnInit, ViewChild } from "@angular/core";
|
||||
import { FormControl } from "@angular/forms";
|
||||
import { UntypedFormControl } from "@angular/forms";
|
||||
import { Router } from "@angular/router";
|
||||
import Swal from "sweetalert2";
|
||||
|
||||
@ -50,7 +50,7 @@ export class SettingsComponent implements OnInit {
|
||||
previousVaultTimeout: number = null;
|
||||
showChangeMasterPass = true;
|
||||
|
||||
vaultTimeout: FormControl = new FormControl(null);
|
||||
vaultTimeout: UntypedFormControl = new UntypedFormControl(null);
|
||||
|
||||
constructor(
|
||||
private platformUtilsService: PlatformUtilsService,
|
||||
|
@ -1,9 +1,9 @@
|
||||
<header>
|
||||
<div class="left">
|
||||
<a routerLink="/tabs/settings">
|
||||
<button type="button" routerLink="/tabs/settings">
|
||||
<span class="header-icon"><i class="bwi bwi-angle-left" aria-hidden="true"></i></span>
|
||||
<span>{{ "back" | i18n }}</span>
|
||||
</a>
|
||||
</button>
|
||||
</div>
|
||||
<h1 class="center">
|
||||
<span class="title">{{ "sync" | i18n }}</span>
|
||||
|
@ -4,6 +4,7 @@
|
||||
<ul>
|
||||
<li routerLinkActive="active" #rlaCurrentTab="routerLinkActive" *ngIf="showCurrentTab">
|
||||
<button
|
||||
type="button"
|
||||
routerLink="current"
|
||||
appA11yTitle="{{ 'currentTab' | i18n }}"
|
||||
[attr.aria-pressed]="rlaCurrentTab.isActive"
|
||||
@ -13,6 +14,7 @@
|
||||
</li>
|
||||
<li routerLinkActive="active" #rlaMyVault="routerLinkActive">
|
||||
<button
|
||||
type="button"
|
||||
routerLink="vault"
|
||||
appA11yTitle="{{ 'myVault' | i18n }}"
|
||||
[attr.aria-pressed]="rlaMyVault.isActive"
|
||||
@ -22,6 +24,7 @@
|
||||
</li>
|
||||
<li routerLinkActive="active" #rlaSend="routerLinkActive">
|
||||
<button
|
||||
type="button"
|
||||
routerLink="send"
|
||||
appA11yTitle="{{ 'send' | i18n }}"
|
||||
[attr.aria-pressed]="rlaSend.isActive"
|
||||
@ -31,6 +34,7 @@
|
||||
</li>
|
||||
<li routerLinkActive="active" #rlaGenerator="routerLinkActive">
|
||||
<button
|
||||
type="button"
|
||||
routerLink="generator"
|
||||
appA11yTitle="{{ 'passGen' | i18n }}"
|
||||
[attr.aria-pressed]="rlaGenerator.isActive"
|
||||
@ -40,6 +44,7 @@
|
||||
</li>
|
||||
<li routerLinkActive="active" #rlaSettings="routerLinkActive">
|
||||
<button
|
||||
type="button"
|
||||
routerLink="settings"
|
||||
appA11yTitle="{{ 'settings' | i18n }}"
|
||||
[attr.aria-pressed]="rlaSettings.isActive"
|
||||
|
@ -83,7 +83,6 @@
|
||||
type="button"
|
||||
class="row-btn"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
appA11yTitle="{{ 'toggleVisibility' | i18n }}"
|
||||
(click)="toggleFieldValue(f)"
|
||||
[attr.aria-pressed]="f.showValue"
|
||||
|
@ -1,13 +1,13 @@
|
||||
<form #form (ngSubmit)="submit()" [appApiAction]="formPromise">
|
||||
<header>
|
||||
<div class="left">
|
||||
<button type="button" appBlurClick (click)="cancel()">{{ "cancel" | i18n }}</button>
|
||||
<button type="button" (click)="cancel()">{{ "cancel" | i18n }}</button>
|
||||
</div>
|
||||
<h1 class="center">
|
||||
<span class="title">{{ title }}</span>
|
||||
</h1>
|
||||
<div class="right">
|
||||
<button type="submit" appBlurClick [disabled]="form.loading">
|
||||
<button type="submit" [disabled]="form.loading">
|
||||
<span [hidden]="form.loading">{{ "save" | i18n }}</span>
|
||||
<i class="bwi bwi-spinner bwi-lg bwi-spin" [hidden]="!form.loading" aria-hidden="true"></i>
|
||||
</button>
|
||||
@ -51,7 +51,6 @@
|
||||
type="button"
|
||||
class="row-btn"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
appA11yTitle="{{ 'generateUsername' | i18n }}"
|
||||
(click)="generateUsername()"
|
||||
>
|
||||
@ -77,7 +76,6 @@
|
||||
type="button"
|
||||
#checkPasswordBtn
|
||||
class="row-btn btn"
|
||||
appBlurClick
|
||||
appA11yTitle="{{ 'checkPassword' | i18n }}"
|
||||
(click)="checkPassword()"
|
||||
[appApiAction]="checkPasswordPromise"
|
||||
@ -99,7 +97,6 @@
|
||||
type="button"
|
||||
class="row-btn"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
appA11yTitle="{{ 'toggleVisibility' | i18n }}"
|
||||
(click)="togglePassword()"
|
||||
*ngIf="cipher.viewPassword"
|
||||
@ -115,7 +112,6 @@
|
||||
type="button"
|
||||
class="row-btn"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
appA11yTitle="{{ 'generatePassword' | i18n }}"
|
||||
(click)="generatePassword()"
|
||||
*ngIf="cipher.viewPassword"
|
||||
@ -165,7 +161,6 @@
|
||||
type="button"
|
||||
class="row-btn"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
appA11yTitle="{{ 'toggleVisibility' | i18n }}"
|
||||
(click)="toggleCardNumber()"
|
||||
[attr.aria-pressed]="showCardNumber"
|
||||
@ -219,7 +214,6 @@
|
||||
type="button"
|
||||
class="row-btn"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
appA11yTitle="{{ 'toggleVisibility' | i18n }}"
|
||||
(click)="toggleCardCode()"
|
||||
[attr.aria-pressed]="showCardCode"
|
||||
@ -486,7 +480,6 @@
|
||||
<button
|
||||
type="button"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="addUri()"
|
||||
class="box-content-row box-content-row-newmulti"
|
||||
>
|
||||
@ -546,7 +539,6 @@
|
||||
type="button"
|
||||
class="box-content-row box-content-row-flex text-default"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="attachments()"
|
||||
*ngIf="editMode && showAttachments && !cloneMode"
|
||||
>
|
||||
@ -566,7 +558,6 @@
|
||||
type="button"
|
||||
class="box-content-row box-content-row-flex text-default"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="editCollections()"
|
||||
*ngIf="editMode && cipher.organizationId && !cloneMode"
|
||||
>
|
||||
@ -641,7 +632,6 @@
|
||||
type="button"
|
||||
class="box-content-row"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="delete()"
|
||||
[appApiAction]="deletePromise"
|
||||
#deleteBtn
|
||||
|
@ -1,10 +1,10 @@
|
||||
<form #form (ngSubmit)="submit()" [appApiAction]="formPromise">
|
||||
<header>
|
||||
<div class="left">
|
||||
<button type="button" appBlurClick (click)="close()" *ngIf="openedAttachmentsInPopup">
|
||||
<button type="button" (click)="close()" *ngIf="openedAttachmentsInPopup">
|
||||
{{ "close" | i18n }}
|
||||
</button>
|
||||
<button type="button" appBlurClick (click)="back()" *ngIf="!openedAttachmentsInPopup">
|
||||
<button type="button" (click)="back()" *ngIf="!openedAttachmentsInPopup">
|
||||
<span class="header-icon"><i class="bwi bwi-angle-left" aria-hidden="true"></i></span>
|
||||
<span>{{ "back" | i18n }}</span>
|
||||
</button>
|
||||
@ -13,7 +13,7 @@
|
||||
<span class="title">{{ "attachments" | i18n }}</span>
|
||||
</h1>
|
||||
<div class="right">
|
||||
<button type="submit" appBlurClick [disabled]="form.loading">
|
||||
<button type="submit" [disabled]="form.loading">
|
||||
<span [hidden]="form.loading">{{ "save" | i18n }}</span>
|
||||
<i class="bwi bwi-spinner bwi-lg bwi-spin" [hidden]="!form.loading" aria-hidden="true"></i>
|
||||
</button>
|
||||
@ -33,7 +33,6 @@
|
||||
class="row-btn btn"
|
||||
type="button"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
appA11yTitle="{{ 'deleteAttachment' | i18n }}"
|
||||
(click)="delete(a)"
|
||||
#deleteBtn
|
||||
|
@ -1,6 +1,6 @@
|
||||
<header>
|
||||
<div class="left">
|
||||
<button type="button" appBlurClick (click)="back()">
|
||||
<button type="button" (click)="back()">
|
||||
<span class="header-icon"><i class="bwi bwi-angle-left" aria-hidden="true"></i></span>
|
||||
<span>{{ "back" | i18n }}</span>
|
||||
</button>
|
||||
@ -19,7 +19,7 @@
|
||||
<i class="bwi bwi-search" aria-hidden="true"></i>
|
||||
</div>
|
||||
<div class="right">
|
||||
<button type="button" appBlurClick (click)="addCipher()" appA11yTitle="{{ 'addItem' | i18n }}">
|
||||
<button type="button" (click)="addCipher()" appA11yTitle="{{ 'addItem' | i18n }}">
|
||||
<i class="bwi bwi-plus bwi-lg bwi-fw" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
@ -40,7 +40,6 @@
|
||||
*ngFor="let f of nestedFolders"
|
||||
class="box-content-row"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="selectFolder(f.node)"
|
||||
>
|
||||
<div class="row-main">
|
||||
@ -63,7 +62,6 @@
|
||||
*ngFor="let c of nestedCollections"
|
||||
class="box-content-row"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="selectCollection(c.node)"
|
||||
>
|
||||
<div class="row-main">
|
||||
|
@ -1,7 +1,7 @@
|
||||
<form #form (ngSubmit)="submit()" [appApiAction]="formPromise">
|
||||
<header>
|
||||
<div class="left">
|
||||
<button type="button" appBlurClick (click)="back()">
|
||||
<button type="button" (click)="back()">
|
||||
<span class="header-icon"><i class="bwi bwi-angle-left" aria-hidden="true"></i></span>
|
||||
<span>{{ "back" | i18n }}</span>
|
||||
</button>
|
||||
@ -10,7 +10,7 @@
|
||||
<span class="title">{{ "collections" | i18n }}</span>
|
||||
</h1>
|
||||
<div class="right">
|
||||
<button type="submit" appBlurClick [disabled]="form.loading">
|
||||
<button type="submit" [disabled]="form.loading">
|
||||
<span [hidden]="form.loading">{{ "save" | i18n }}</span>
|
||||
<i class="bwi bwi-spinner bwi-lg bwi-spin" [hidden]="!form.loading" aria-hidden="true"></i>
|
||||
</button>
|
||||
|
@ -4,7 +4,6 @@
|
||||
<app-pop-out *ngIf="!inSidebar"></app-pop-out>
|
||||
<button
|
||||
type="button"
|
||||
appBlurClick
|
||||
(click)="refresh()"
|
||||
appA11yTitle="{{ 'refresh' | i18n }}"
|
||||
*ngIf="inSidebar"
|
||||
@ -25,7 +24,7 @@
|
||||
<i class="bwi bwi-search" aria-hidden="true"></i>
|
||||
</div>
|
||||
<div class="right">
|
||||
<button type="button" appBlurClick (click)="addCipher()" appA11yTitle="{{ 'addItem' | i18n }}">
|
||||
<button type="button" (click)="addCipher()" appA11yTitle="{{ 'addItem' | i18n }}">
|
||||
<i class="bwi bwi-plus bwi-lg bwi-fw" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<header>
|
||||
<div class="left">
|
||||
<button type="button" appBlurClick (click)="close()">{{ "close" | i18n }}</button>
|
||||
<button type="button" (click)="close()">{{ "close" | i18n }}</button>
|
||||
</div>
|
||||
<h1 class="center">
|
||||
<span class="title">{{ "passwordHistory" | i18n }}</span>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<form #form (ngSubmit)="submit()" [appApiAction]="formPromise">
|
||||
<header>
|
||||
<div class="left">
|
||||
<button type="button" appBlurClick (click)="cancel()">{{ "cancel" | i18n }}</button>
|
||||
<button type="button" (click)="cancel()">{{ "cancel" | i18n }}</button>
|
||||
</div>
|
||||
<h1 class="center">
|
||||
<span class="title">{{ "moveToOrganization" | i18n }}</span>
|
||||
@ -9,7 +9,6 @@
|
||||
<div class="right">
|
||||
<button
|
||||
type="submit"
|
||||
appBlurClick
|
||||
[disabled]="form.loading || !canSave"
|
||||
*ngIf="organizations && organizations.length"
|
||||
>
|
||||
|
@ -17,7 +17,7 @@
|
||||
<i class="bwi bwi-search"></i>
|
||||
</div>
|
||||
<div class="right">
|
||||
<button type="button" appBlurClick (click)="addCipher()" appA11yTitle="{{ 'addItem' | i18n }}">
|
||||
<button type="button" (click)="addCipher()" appA11yTitle="{{ 'addItem' | i18n }}">
|
||||
<i class="bwi bwi-plus bwi-lg bwi-fw" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
@ -61,7 +61,6 @@
|
||||
type="button"
|
||||
class="box-content-row"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="selectType(cipherType.Login)"
|
||||
>
|
||||
<div class="row-main">
|
||||
@ -75,7 +74,6 @@
|
||||
type="button"
|
||||
class="box-content-row"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="selectType(cipherType.Card)"
|
||||
>
|
||||
<div class="row-main">
|
||||
@ -89,7 +87,6 @@
|
||||
type="button"
|
||||
class="box-content-row"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="selectType(cipherType.Identity)"
|
||||
>
|
||||
<div class="row-main">
|
||||
@ -103,7 +100,6 @@
|
||||
type="button"
|
||||
class="box-content-row"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="selectType(cipherType.SecureNote)"
|
||||
>
|
||||
<div class="row-main">
|
||||
@ -126,7 +122,6 @@
|
||||
*ngFor="let f of nestedFolders"
|
||||
class="box-content-row"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="selectFolder(f.node)"
|
||||
>
|
||||
<div class="row-main">
|
||||
@ -151,7 +146,6 @@
|
||||
*ngFor="let nestedCollection of nestedCollections"
|
||||
class="box-content-row"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="selectCollection(nestedCollection.node)"
|
||||
>
|
||||
<div class="row-main">
|
||||
@ -187,13 +181,7 @@
|
||||
<span class="flex-right">{{ deletedCount }}</span>
|
||||
</h2>
|
||||
<div class="box-content single-line">
|
||||
<button
|
||||
type="button"
|
||||
class="box-content-row"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="selectTrash()"
|
||||
>
|
||||
<button type="button" class="box-content-row" appStopClick (click)="selectTrash()">
|
||||
<div class="row-main">
|
||||
<div class="icon"><i class="bwi bwi-fw bwi-lg bwi-trash"></i></div>
|
||||
<span class="text">{{ "trash" | i18n }}</span>
|
||||
|
@ -58,7 +58,7 @@
|
||||
class="bwi bwi-fw bwi-family"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span> {{ organization.name | ellipsis: 21:true }}</span>
|
||||
<span> {{ organization.name | ellipsis: (organization.enabled ? 21 : 18):true }}</span>
|
||||
<i
|
||||
*ngIf="!organization.enabled"
|
||||
class="bwi bwi-fw bwi-exclamation-triangle text-danger"
|
||||
|
@ -1,12 +1,12 @@
|
||||
<header>
|
||||
<div class="left">
|
||||
<button type="button" appBlurClick (click)="close()">{{ "close" | i18n }}</button>
|
||||
<button type="button" (click)="close()">{{ "close" | i18n }}</button>
|
||||
</div>
|
||||
<h1 class="center">
|
||||
<span class="title">{{ "viewItem" | i18n }}</span>
|
||||
</h1>
|
||||
<div class="right" *ngIf="cipher">
|
||||
<button type="button" appBlurClick (click)="edit()" *ngIf="!cipher.isDeleted">
|
||||
<button type="button" (click)="edit()" *ngIf="!cipher.isDeleted">
|
||||
{{ "edit" | i18n }}
|
||||
</button>
|
||||
</div>
|
||||
@ -79,7 +79,6 @@
|
||||
type="button"
|
||||
#checkPasswordBtn
|
||||
class="row-btn btn"
|
||||
appBlurClick
|
||||
appA11yTitle="{{ 'checkPassword' | i18n }}"
|
||||
(click)="checkPassword()"
|
||||
[appApiAction]="checkPasswordPromise"
|
||||
@ -397,7 +396,6 @@
|
||||
class="box-content-row box-content-row-flex text-default"
|
||||
*ngFor="let attachment of cipher.attachments"
|
||||
appStopClick
|
||||
appBlurCLick
|
||||
(click)="downloadAttachment(attachment)"
|
||||
>
|
||||
<span class="row-main">{{ attachment.fileName }}</span>
|
||||
@ -421,7 +419,6 @@
|
||||
type="button"
|
||||
class="box-content-row"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="fillCipher()"
|
||||
*ngIf="cipher.type !== cipherType.SecureNote && !cipher.isDeleted && !inPopout"
|
||||
>
|
||||
@ -436,7 +433,6 @@
|
||||
type="button"
|
||||
class="box-content-row"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="fillCipherAndSave()"
|
||||
*ngIf="cipher.type === cipherType.Login && !cipher.isDeleted && !inPopout"
|
||||
>
|
||||
@ -451,7 +447,6 @@
|
||||
type="button"
|
||||
class="box-content-row"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="clone()"
|
||||
*ngIf="!cipher.organizationId && !cipher.isDeleted"
|
||||
>
|
||||
@ -466,7 +461,6 @@
|
||||
type="button"
|
||||
class="box-content-row"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="share()"
|
||||
*ngIf="!cipher.organizationId"
|
||||
>
|
||||
@ -481,7 +475,6 @@
|
||||
type="button"
|
||||
class="box-content-row"
|
||||
appStopClick
|
||||
appBlurClick
|
||||
(click)="restore()"
|
||||
*ngIf="cipher.isDeleted"
|
||||
>
|
||||
@ -492,7 +485,7 @@
|
||||
<span>{{ "restoreItem" | i18n }}</span>
|
||||
</div>
|
||||
</button>
|
||||
<button type="button" class="box-content-row" appStopClick appBlurClick (click)="delete()">
|
||||
<button type="button" class="box-content-row" appStopClick (click)="delete()">
|
||||
<div class="row-main text-danger">
|
||||
<div class="icon text-danger" aria-hidden="true">
|
||||
<i class="bwi bwi-trash bwi-lg bwi-fw"></i>
|
||||
@ -514,14 +507,14 @@
|
||||
</div>
|
||||
<div *ngIf="cipher.hasPasswordHistory">
|
||||
<b class="font-weight-semibold">{{ "passwordHistory" | i18n }}:</b>
|
||||
<a
|
||||
<button
|
||||
routerLink="/cipher-password-history"
|
||||
[queryParams]="{ cipherId: cipher.id }"
|
||||
appStopClick
|
||||
title="{{ 'passwordHistory' | i18n }}"
|
||||
>
|
||||
{{ cipher.passwordHistory.length }}
|
||||
</a>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -29,8 +29,8 @@ export class BrowserFileDownloadService implements FileDownloadService {
|
||||
true
|
||||
);
|
||||
} else {
|
||||
if (navigator.msSaveOrOpenBlob) {
|
||||
navigator.msSaveBlob(builder.blob, request.fileName);
|
||||
if ((navigator as any).msSaveOrOpenBlob) {
|
||||
(navigator as any).msSaveBlob(builder.blob, request.fileName);
|
||||
} else {
|
||||
const a = window.document.createElement("a");
|
||||
a.href = URL.createObjectURL(builder.blob);
|
||||
|
@ -132,7 +132,7 @@ Gailu guztien artean pasahitz mugagabeak kudeatu, biltegiratu, babestu eta parte
|
||||
|
||||
Pasahitz sendoak, bakarrak eta ausazkoak sortzen ditu, webgune bakoitzaren segurtasun-baldintzetan oinarrituta.
|
||||
|
||||
Bitwarden Bidalketak-ek azkar transmititzen dio zifratutako informazioa --- artxiboak eta testu sinplea -- edozein pertsonari zuzenean.
|
||||
Bitwarden Send-ek azkar transmititzen du zifratutako informazioa --- artxiboak eta testu sinplea -- edozein pertsonari zuzenean.
|
||||
|
||||
Bitwarden-ek Taldeak eta Enpresak planak eskaintzen ditu, enpresa bereko lankideek pasahitzak modu seguruan parteka ditzaten.
|
||||
|
||||
|
@ -46,13 +46,20 @@ const moduleRules = [
|
||||
"sass-loader",
|
||||
],
|
||||
},
|
||||
// Hide System.import warnings. ref: https://github.com/angular/angular/issues/21560
|
||||
{
|
||||
test: /[\/\\]@angular[\/\\].+\.js$/,
|
||||
parser: { system: true },
|
||||
test: /\.[cm]?js$/,
|
||||
use: [
|
||||
{
|
||||
loader: "babel-loader",
|
||||
options: {
|
||||
configFile: false,
|
||||
plugins: ["@angular/compiler-cli/linker/babel"],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
|
||||
test: /\.[jt]sx?$/,
|
||||
loader: "@ngtools/webpack",
|
||||
},
|
||||
];
|
||||
@ -102,7 +109,7 @@ const plugins = [
|
||||
cleanAfterEveryBuildPatterns: ["!popup/fonts/**/*"],
|
||||
}),
|
||||
new webpack.ProvidePlugin({
|
||||
process: "process/browser",
|
||||
process: "process/browser.js",
|
||||
}),
|
||||
new webpack.SourceMapDevToolPlugin({
|
||||
exclude: [/content\/.*/, /notification\/.*/],
|
||||
|
254
apps/cli/package-lock.json
generated
254
apps/cli/package-lock.json
generated
@ -11,27 +11,27 @@
|
||||
"dependencies": {
|
||||
"@koa/multer": "^3.0.0",
|
||||
"@koa/router": "^10.1.1",
|
||||
"big-integer": "1.6.48",
|
||||
"big-integer": "^1.6.51",
|
||||
"browser-hrtime": "^1.1.8",
|
||||
"chalk": "^4.1.1",
|
||||
"commander": "7.2.0",
|
||||
"form-data": "4.0.0",
|
||||
"https-proxy-agent": "5.0.0",
|
||||
"inquirer": "8.0.0",
|
||||
"jsdom": "^16.5.3",
|
||||
"jszip": "^3.7.1",
|
||||
"jsdom": "^16.7.0",
|
||||
"jszip": "^3.10.0",
|
||||
"koa": "^2.13.4",
|
||||
"koa-bodyparser": "^4.3.0",
|
||||
"koa-json": "^2.0.2",
|
||||
"lowdb": "1.0.0",
|
||||
"lunr": "^2.3.9",
|
||||
"multer": "^1.4.4",
|
||||
"node-fetch": "^2.6.1",
|
||||
"multer": "^1.4.5-lts.1",
|
||||
"node-fetch": "^2.6.7",
|
||||
"node-forge": "1.3.1",
|
||||
"open": "^8.0.8",
|
||||
"papaparse": "^5.3.0",
|
||||
"open": "^8.4.0",
|
||||
"papaparse": "^5.3.2",
|
||||
"proper-lockfile": "^4.1.2",
|
||||
"rxjs": "6.6.7",
|
||||
"rxjs": "^7.5.5",
|
||||
"tldjs": "^2.3.1",
|
||||
"zxcvbn": "^4.4.2"
|
||||
},
|
||||
@ -187,9 +187,9 @@
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||
},
|
||||
"node_modules/big-integer": {
|
||||
"version": "1.6.48",
|
||||
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz",
|
||||
"integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==",
|
||||
"version": "1.6.51",
|
||||
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz",
|
||||
"integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==",
|
||||
"engines": {
|
||||
"node": ">=0.6"
|
||||
}
|
||||
@ -210,38 +210,16 @@
|
||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
|
||||
},
|
||||
"node_modules/busboy": {
|
||||
"version": "0.2.14",
|
||||
"resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz",
|
||||
"integrity": "sha512-InWFDomvlkEj+xWLBfU3AvnbVYqeTWmQopiW0tWWEy5yehYm2YkGEc59sUmw/4ty5Zj/b0WHGs1LgecuBSBGrg==",
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
|
||||
"integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==",
|
||||
"dependencies": {
|
||||
"dicer": "0.2.5",
|
||||
"readable-stream": "1.1.x"
|
||||
"streamsearch": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
"node": ">=10.16.0"
|
||||
}
|
||||
},
|
||||
"node_modules/busboy/node_modules/isarray": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
||||
"integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ=="
|
||||
},
|
||||
"node_modules/busboy/node_modules/readable-stream": {
|
||||
"version": "1.1.14",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
|
||||
"integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==",
|
||||
"dependencies": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.1",
|
||||
"isarray": "0.0.1",
|
||||
"string_decoder": "~0.10.x"
|
||||
}
|
||||
},
|
||||
"node_modules/busboy/node_modules/string_decoder": {
|
||||
"version": "0.10.31",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
||||
"integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ=="
|
||||
},
|
||||
"node_modules/bytes": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||
@ -534,39 +512,6 @@
|
||||
"npm": "1.2.8000 || >= 1.4.16"
|
||||
}
|
||||
},
|
||||
"node_modules/dicer": {
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz",
|
||||
"integrity": "sha512-FDvbtnq7dzlPz0wyYlOExifDEZcu8h+rErEXgfxqmLfRfC/kJidEFh4+effJRO3P0xmfqyPbSMG0LveNRfTKVg==",
|
||||
"dependencies": {
|
||||
"readable-stream": "1.1.x",
|
||||
"streamsearch": "0.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/dicer/node_modules/isarray": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
||||
"integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ=="
|
||||
},
|
||||
"node_modules/dicer/node_modules/readable-stream": {
|
||||
"version": "1.1.14",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
|
||||
"integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==",
|
||||
"dependencies": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.1",
|
||||
"isarray": "0.0.1",
|
||||
"string_decoder": "~0.10.x"
|
||||
}
|
||||
},
|
||||
"node_modules/dicer/node_modules/string_decoder": {
|
||||
"version": "0.10.31",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
||||
"integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ=="
|
||||
},
|
||||
"node_modules/domexception": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz",
|
||||
@ -901,6 +846,22 @@
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/inquirer/node_modules/rxjs": {
|
||||
"version": "6.6.7",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
|
||||
"integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
|
||||
"dependencies": {
|
||||
"tslib": "^1.9.0"
|
||||
},
|
||||
"engines": {
|
||||
"npm": ">=2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/inquirer/node_modules/tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||
},
|
||||
"node_modules/is-docker": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
|
||||
@ -1242,22 +1203,20 @@
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"node_modules/multer": {
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/multer/-/multer-1.4.4.tgz",
|
||||
"integrity": "sha512-2wY2+xD4udX612aMqMcB8Ws2Voq6NIUPEtD1be6m411T4uDH/VtL9i//xvcyFlTVfRdaBsk7hV5tgrGQqhuBiw==",
|
||||
"deprecated": "Multer 1.x is affected by CVE-2022-24434. This is fixed in v1.4.4-lts.1 which drops support for versions of Node.js before 6. Please upgrade to at least Node.js 6 and version 1.4.4-lts.1 of Multer. If you need support for older versions of Node.js, we are open to accepting patches that would fix the CVE on the main 1.x release line, whilst maintaining compatibility with Node.js 0.10.",
|
||||
"version": "1.4.5-lts.1",
|
||||
"resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.1.tgz",
|
||||
"integrity": "sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==",
|
||||
"dependencies": {
|
||||
"append-field": "^1.0.0",
|
||||
"busboy": "^0.2.11",
|
||||
"busboy": "^1.0.0",
|
||||
"concat-stream": "^1.5.2",
|
||||
"mkdirp": "^0.5.4",
|
||||
"object-assign": "^4.1.1",
|
||||
"on-finished": "^2.3.0",
|
||||
"type-is": "^1.6.4",
|
||||
"xtend": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.10.0"
|
||||
"node": ">= 6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/mute-stream": {
|
||||
@ -1586,14 +1545,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/rxjs": {
|
||||
"version": "6.6.7",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
|
||||
"integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
|
||||
"version": "7.5.6",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.6.tgz",
|
||||
"integrity": "sha512-dnyv2/YsXhnm461G+R/Pe5bWP41Nm6LBXEYWI6eiFP4fiwx6WRI/CD0zbdVAudd9xwLEF2IDcKXLHit0FYjUzw==",
|
||||
"dependencies": {
|
||||
"tslib": "^1.9.0"
|
||||
},
|
||||
"engines": {
|
||||
"npm": ">=2.0.0"
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/safe-buffer": {
|
||||
@ -1694,11 +1650,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/streamsearch": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz",
|
||||
"integrity": "sha512-jos8u++JKm0ARcSUTAZXOVC0mSox7Bhn6sBgty73P1f3JGf7yG2clTbBNHUdde/kdvP2FESam+vM6l8jBrNxHA==",
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz",
|
||||
"integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/string_decoder": {
|
||||
@ -1831,9 +1787,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
|
||||
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
|
||||
},
|
||||
"node_modules/tsscmp": {
|
||||
"version": "1.0.6",
|
||||
@ -2128,9 +2084,9 @@
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||
},
|
||||
"big-integer": {
|
||||
"version": "1.6.48",
|
||||
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz",
|
||||
"integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w=="
|
||||
"version": "1.6.51",
|
||||
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz",
|
||||
"integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg=="
|
||||
},
|
||||
"browser-hrtime": {
|
||||
"version": "1.1.8",
|
||||
@ -2148,35 +2104,11 @@
|
||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
|
||||
},
|
||||
"busboy": {
|
||||
"version": "0.2.14",
|
||||
"resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz",
|
||||
"integrity": "sha512-InWFDomvlkEj+xWLBfU3AvnbVYqeTWmQopiW0tWWEy5yehYm2YkGEc59sUmw/4ty5Zj/b0WHGs1LgecuBSBGrg==",
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
|
||||
"integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==",
|
||||
"requires": {
|
||||
"dicer": "0.2.5",
|
||||
"readable-stream": "1.1.x"
|
||||
},
|
||||
"dependencies": {
|
||||
"isarray": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
||||
"integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ=="
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "1.1.14",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
|
||||
"integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==",
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.1",
|
||||
"isarray": "0.0.1",
|
||||
"string_decoder": "~0.10.x"
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "0.10.31",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
||||
"integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ=="
|
||||
}
|
||||
"streamsearch": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"bytes": {
|
||||
@ -2399,38 +2331,6 @@
|
||||
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
|
||||
"integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="
|
||||
},
|
||||
"dicer": {
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz",
|
||||
"integrity": "sha512-FDvbtnq7dzlPz0wyYlOExifDEZcu8h+rErEXgfxqmLfRfC/kJidEFh4+effJRO3P0xmfqyPbSMG0LveNRfTKVg==",
|
||||
"requires": {
|
||||
"readable-stream": "1.1.x",
|
||||
"streamsearch": "0.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"isarray": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
||||
"integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ=="
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "1.1.14",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
|
||||
"integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==",
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.1",
|
||||
"isarray": "0.0.1",
|
||||
"string_decoder": "~0.10.x"
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "0.10.31",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
||||
"integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"domexception": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz",
|
||||
@ -2671,6 +2571,21 @@
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"through": "^2.3.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"rxjs": {
|
||||
"version": "6.6.7",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
|
||||
"integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
|
||||
"requires": {
|
||||
"tslib": "^1.9.0"
|
||||
}
|
||||
},
|
||||
"tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"is-docker": {
|
||||
@ -2944,16 +2859,15 @@
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"multer": {
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/multer/-/multer-1.4.4.tgz",
|
||||
"integrity": "sha512-2wY2+xD4udX612aMqMcB8Ws2Voq6NIUPEtD1be6m411T4uDH/VtL9i//xvcyFlTVfRdaBsk7hV5tgrGQqhuBiw==",
|
||||
"version": "1.4.5-lts.1",
|
||||
"resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.1.tgz",
|
||||
"integrity": "sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==",
|
||||
"requires": {
|
||||
"append-field": "^1.0.0",
|
||||
"busboy": "^0.2.11",
|
||||
"busboy": "^1.0.0",
|
||||
"concat-stream": "^1.5.2",
|
||||
"mkdirp": "^0.5.4",
|
||||
"object-assign": "^4.1.1",
|
||||
"on-finished": "^2.3.0",
|
||||
"type-is": "^1.6.4",
|
||||
"xtend": "^4.0.0"
|
||||
}
|
||||
@ -3210,11 +3124,11 @@
|
||||
"integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ=="
|
||||
},
|
||||
"rxjs": {
|
||||
"version": "6.6.7",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
|
||||
"integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
|
||||
"version": "7.5.6",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.6.tgz",
|
||||
"integrity": "sha512-dnyv2/YsXhnm461G+R/Pe5bWP41Nm6LBXEYWI6eiFP4fiwx6WRI/CD0zbdVAudd9xwLEF2IDcKXLHit0FYjUzw==",
|
||||
"requires": {
|
||||
"tslib": "^1.9.0"
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
@ -3289,9 +3203,9 @@
|
||||
}
|
||||
},
|
||||
"streamsearch": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz",
|
||||
"integrity": "sha512-jos8u++JKm0ARcSUTAZXOVC0mSox7Bhn6sBgty73P1f3JGf7yG2clTbBNHUdde/kdvP2FESam+vM6l8jBrNxHA=="
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz",
|
||||
"integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg=="
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
@ -3398,9 +3312,9 @@
|
||||
}
|
||||
},
|
||||
"tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
|
||||
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
|
||||
},
|
||||
"tsscmp": {
|
||||
"version": "1.0.6",
|
||||
|
@ -377,7 +377,7 @@ export class Main {
|
||||
private async init() {
|
||||
await this.storageService.init();
|
||||
await this.stateService.init();
|
||||
this.containerService.attachToWindow(global);
|
||||
this.containerService.attachToGlobal(global);
|
||||
await this.environmentService.setUrlsFromStorage();
|
||||
const locale = await this.stateService.getLocale();
|
||||
await this.i18nService.init(locale);
|
||||
|
@ -1,6 +1,7 @@
|
||||
import * as fet from "node-fetch";
|
||||
|
||||
import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
|
||||
import { EncArrayBuffer } from "@bitwarden/common/models/domain/encArrayBuffer";
|
||||
import { SymmetricCryptoKey } from "@bitwarden/common/models/domain/symmetricCryptoKey";
|
||||
import { Response } from "@bitwarden/node/cli/models/response";
|
||||
import { FileResponse } from "@bitwarden/node/cli/models/response/fileResponse";
|
||||
@ -24,8 +25,8 @@ export abstract class DownloadCommand {
|
||||
}
|
||||
|
||||
try {
|
||||
const buf = await response.arrayBuffer();
|
||||
const decBuf = await this.cryptoService.decryptFromBytes(buf, key);
|
||||
const encBuf = await EncArrayBuffer.fromResponse(response);
|
||||
const decBuf = await this.cryptoService.decryptFromBytes(encBuf, key);
|
||||
if (process.env.BW_SERVE === "true") {
|
||||
const res = new FileResponse(Buffer.from(decBuf), fileName);
|
||||
return Response.success(res);
|
||||
|
@ -2,6 +2,7 @@ import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
|
||||
import { LogService } from "@bitwarden/common/abstractions/log.service";
|
||||
import { AbstractStorageService } from "@bitwarden/common/abstractions/storage.service";
|
||||
import { Utils } from "@bitwarden/common/misc/utils";
|
||||
import { EncArrayBuffer } from "@bitwarden/common/models/domain/encArrayBuffer";
|
||||
import { SymmetricCryptoKey } from "@bitwarden/common/models/domain/symmetricCryptoKey";
|
||||
|
||||
export class NodeEnvSecureStorageService implements AbstractStorageService {
|
||||
@ -63,10 +64,8 @@ export class NodeEnvSecureStorageService implements AbstractStorageService {
|
||||
return null;
|
||||
}
|
||||
|
||||
const decValue = await this.cryptoService().decryptFromBytes(
|
||||
Utils.fromB64ToArray(encValue).buffer,
|
||||
sessionKey
|
||||
);
|
||||
const encBuf = EncArrayBuffer.fromB64(encValue);
|
||||
const decValue = await this.cryptoService().decryptFromBytes(encBuf, sessionKey);
|
||||
if (decValue == null) {
|
||||
this.logService.info("Failed to decrypt.");
|
||||
return null;
|
||||
|
8
apps/desktop/desktop_native/.cargo/config
Normal file
8
apps/desktop/desktop_native/.cargo/config
Normal file
@ -0,0 +1,8 @@
|
||||
[target.x86_64-pc-windows-msvc]
|
||||
rustflags = ["-Ctarget-feature=+crt-static"]
|
||||
|
||||
[target.i686-pc-windows-msvc]
|
||||
rustflags = ["-Ctarget-feature=+crt-static"]
|
||||
|
||||
[target.aarch64-pc-windows-msvc]
|
||||
rustflags = ["-Ctarget-feature=+crt-static"]
|
@ -25,9 +25,11 @@ widestring = "0.5.1"
|
||||
windows = {version = "0.32.0", features = [
|
||||
"alloc",
|
||||
"Foundation",
|
||||
"Security_Credentials_UI",
|
||||
"Storage_Streams",
|
||||
"Win32_Foundation",
|
||||
"Win32_Security_Credentials",
|
||||
"Win32_System_WinRT",
|
||||
]}
|
||||
|
||||
[target.'cfg(windows)'.dev-dependencies]
|
||||
|
@ -13,7 +13,7 @@ switch (process.platform) {
|
||||
break;
|
||||
|
||||
default:
|
||||
targets = ['x86_64-unknown-linux-gnu'];
|
||||
targets = ['x86_64-unknown-linux-musl'];
|
||||
break;
|
||||
}
|
||||
|
||||
|
4
apps/desktop/desktop_native/index.d.ts
vendored
4
apps/desktop/desktop_native/index.d.ts
vendored
@ -13,3 +13,7 @@ export namespace passwords {
|
||||
/** Delete the stored password from the keychain. */
|
||||
export function deletePassword(service: string, account: string): Promise<void>
|
||||
}
|
||||
export namespace biometrics {
|
||||
export function prompt(hwnd: Buffer, message: string): Promise<boolean>
|
||||
export function available(): Promise<boolean>
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ switch (platform) {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./desktop_native.android-arm64.node')
|
||||
} else {
|
||||
nativeBinding = require('@bitwarden/desktop_native-android-arm64')
|
||||
nativeBinding = require('@bitwarden/desktop-native-android-arm64')
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e
|
||||
@ -42,7 +42,7 @@ switch (platform) {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./desktop_native.android-arm-eabi.node')
|
||||
} else {
|
||||
nativeBinding = require('@bitwarden/desktop_native-android-arm-eabi')
|
||||
nativeBinding = require('@bitwarden/desktop-native-android-arm-eabi')
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e
|
||||
@ -62,7 +62,7 @@ switch (platform) {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./desktop_native.win32-x64-msvc.node')
|
||||
} else {
|
||||
nativeBinding = require('@bitwarden/desktop_native-win32-x64-msvc')
|
||||
nativeBinding = require('@bitwarden/desktop-native-win32-x64-msvc')
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e
|
||||
@ -76,7 +76,7 @@ switch (platform) {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./desktop_native.win32-ia32-msvc.node')
|
||||
} else {
|
||||
nativeBinding = require('@bitwarden/desktop_native-win32-ia32-msvc')
|
||||
nativeBinding = require('@bitwarden/desktop-native-win32-ia32-msvc')
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e
|
||||
@ -90,7 +90,7 @@ switch (platform) {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./desktop_native.win32-arm64-msvc.node')
|
||||
} else {
|
||||
nativeBinding = require('@bitwarden/desktop_native-win32-arm64-msvc')
|
||||
nativeBinding = require('@bitwarden/desktop-native-win32-arm64-msvc')
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e
|
||||
@ -108,7 +108,7 @@ switch (platform) {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./desktop_native.darwin-x64.node')
|
||||
} else {
|
||||
nativeBinding = require('@bitwarden/desktop_native-darwin-x64')
|
||||
nativeBinding = require('@bitwarden/desktop-native-darwin-x64')
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e
|
||||
@ -122,7 +122,7 @@ switch (platform) {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./desktop_native.darwin-arm64.node')
|
||||
} else {
|
||||
nativeBinding = require('@bitwarden/desktop_native-darwin-arm64')
|
||||
nativeBinding = require('@bitwarden/desktop-native-darwin-arm64')
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e
|
||||
@ -141,7 +141,7 @@ switch (platform) {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./desktop_native.freebsd-x64.node')
|
||||
} else {
|
||||
nativeBinding = require('@bitwarden/desktop_native-freebsd-x64')
|
||||
nativeBinding = require('@bitwarden/desktop-native-freebsd-x64')
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e
|
||||
@ -150,61 +150,31 @@ switch (platform) {
|
||||
case 'linux':
|
||||
switch (arch) {
|
||||
case 'x64':
|
||||
if (isMusl()) {
|
||||
localFileExisted = existsSync(
|
||||
join(__dirname, 'desktop_native.linux-x64-musl.node')
|
||||
)
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./desktop_native.linux-x64-musl.node')
|
||||
} else {
|
||||
nativeBinding = require('@bitwarden/desktop_native-linux-x64-musl')
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e
|
||||
}
|
||||
} else {
|
||||
localFileExisted = existsSync(
|
||||
join(__dirname, 'desktop_native.linux-x64-gnu.node')
|
||||
)
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./desktop_native.linux-x64-gnu.node')
|
||||
} else {
|
||||
nativeBinding = require('@bitwarden/desktop_native-linux-x64-gnu')
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e
|
||||
localFileExisted = existsSync(
|
||||
join(__dirname, 'desktop_native.linux-x64-musl.node')
|
||||
)
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./desktop_native.linux-x64-musl.node')
|
||||
} else {
|
||||
nativeBinding = require('@bitwarden/desktop-native-linux-x64-musl')
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e
|
||||
}
|
||||
break
|
||||
case 'arm64':
|
||||
if (isMusl()) {
|
||||
localFileExisted = existsSync(
|
||||
join(__dirname, 'desktop_native.linux-arm64-musl.node')
|
||||
)
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./desktop_native.linux-arm64-musl.node')
|
||||
} else {
|
||||
nativeBinding = require('@bitwarden/desktop_native-linux-arm64-musl')
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e
|
||||
}
|
||||
} else {
|
||||
localFileExisted = existsSync(
|
||||
join(__dirname, 'desktop_native.linux-arm64-gnu.node')
|
||||
)
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./desktop_native.linux-arm64-gnu.node')
|
||||
} else {
|
||||
nativeBinding = require('@bitwarden/desktop_native-linux-arm64-gnu')
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e
|
||||
localFileExisted = existsSync(
|
||||
join(__dirname, 'desktop_native.linux-arm64-musl.node')
|
||||
)
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./desktop_native.linux-arm64-musl.node')
|
||||
} else {
|
||||
nativeBinding = require('@bitwarden/desktop-native-linux-arm64-musl')
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e
|
||||
}
|
||||
break
|
||||
case 'arm':
|
||||
@ -215,7 +185,7 @@ switch (platform) {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./desktop_native.linux-arm-gnueabihf.node')
|
||||
} else {
|
||||
nativeBinding = require('@bitwarden/desktop_native-linux-arm-gnueabihf')
|
||||
nativeBinding = require('@bitwarden/desktop-native-linux-arm-gnueabihf')
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e
|
||||
@ -236,6 +206,7 @@ if (!nativeBinding) {
|
||||
throw new Error(`Failed to load native binding`)
|
||||
}
|
||||
|
||||
const { passwords } = nativeBinding
|
||||
const { passwords, biometrics } = nativeBinding
|
||||
|
||||
module.exports.passwords = passwords
|
||||
module.exports.biometrics = biometrics
|
||||
|
41
apps/desktop/desktop_native/package-lock.json
generated
41
apps/desktop/desktop_native/package-lock.json
generated
@ -1,41 +0,0 @@
|
||||
{
|
||||
"name": "@bitwarden/desktop_native",
|
||||
"version": "0.1.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@bitwarden/desktop_native",
|
||||
"version": "0.1.0",
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0",
|
||||
"devDependencies": {
|
||||
"@napi-rs/cli": "^2.6.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/cli": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-2.6.2.tgz",
|
||||
"integrity": "sha512-EmH+DQDEBUIoqMim0cc+X96ImtcIZLFjgW5WWORpzYnA9Ug7zNPO7jCLMhIQRd/p5AdWaXrT4SVXc/aip09rKQ==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"napi": "scripts/index.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Brooooooklyn"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@napi-rs/cli": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-2.6.2.tgz",
|
||||
"integrity": "sha512-EmH+DQDEBUIoqMim0cc+X96ImtcIZLFjgW5WWORpzYnA9Ug7zNPO7jCLMhIQRd/p5AdWaXrT4SVXc/aip09rKQ==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +1,10 @@
|
||||
{
|
||||
"name": "@bitwarden/desktop_native",
|
||||
"name": "@bitwarden/desktop-native",
|
||||
"version": "0.1.0",
|
||||
"description": "",
|
||||
"main": "index.node",
|
||||
"scripts": {
|
||||
"build": "napi build --release --platform",
|
||||
"build:debug": "napi build --platform",
|
||||
"build": "napi build --release --platform --js false",
|
||||
"build:debug": "napi build --platform --js false",
|
||||
"build:cross-platform": "node build.js",
|
||||
"test": "cargo test"
|
||||
},
|
||||
|
9
apps/desktop/desktop_native/src/biometric/macos.rs
Normal file
9
apps/desktop/desktop_native/src/biometric/macos.rs
Normal file
@ -0,0 +1,9 @@
|
||||
use anyhow::{Result, bail};
|
||||
|
||||
pub fn prompt(_hwnd: Vec<u8>, _message: String) -> Result<bool> {
|
||||
bail!("platform not supported");
|
||||
}
|
||||
|
||||
pub fn available() -> Result<bool> {
|
||||
bail!("platform not supported");
|
||||
}
|
5
apps/desktop/desktop_native/src/biometric/mod.rs
Normal file
5
apps/desktop/desktop_native/src/biometric/mod.rs
Normal file
@ -0,0 +1,5 @@
|
||||
#[cfg_attr(target_os = "linux", path = "unix.rs")]
|
||||
#[cfg_attr(target_os = "windows", path = "windows.rs")]
|
||||
#[cfg_attr(target_os = "macos", path = "macos.rs")]
|
||||
mod biometric;
|
||||
pub use biometric::*;
|
9
apps/desktop/desktop_native/src/biometric/unix.rs
Normal file
9
apps/desktop/desktop_native/src/biometric/unix.rs
Normal file
@ -0,0 +1,9 @@
|
||||
use anyhow::{Result, bail};
|
||||
|
||||
pub fn prompt(_hwnd: Vec<u8>, _message: String) -> Result<bool> {
|
||||
bail!("platform not supported");
|
||||
}
|
||||
|
||||
pub fn available() -> Result<bool> {
|
||||
bail!("platform not supported");
|
||||
}
|
51
apps/desktop/desktop_native/src/biometric/windows.rs
Normal file
51
apps/desktop/desktop_native/src/biometric/windows.rs
Normal file
@ -0,0 +1,51 @@
|
||||
use anyhow::Result;
|
||||
use windows::{
|
||||
core::factory, Foundation::IAsyncOperation, Security::Credentials::UI::*,
|
||||
Win32::Foundation::HWND, Win32::System::WinRT::IUserConsentVerifierInterop,
|
||||
};
|
||||
|
||||
pub fn prompt(hwnd: Vec<u8>, message: String) -> Result<bool> {
|
||||
let interop = factory::<UserConsentVerifier, IUserConsentVerifierInterop>()?;
|
||||
|
||||
let h = isize::from_le_bytes(hwnd.try_into().unwrap());
|
||||
let window = HWND(h);
|
||||
|
||||
let operation: IAsyncOperation<UserConsentVerificationResult> =
|
||||
unsafe { interop.RequestVerificationForWindowAsync(window, message)? };
|
||||
|
||||
let result: UserConsentVerificationResult = operation.get()?;
|
||||
|
||||
match result {
|
||||
UserConsentVerificationResult::Verified => Ok(true),
|
||||
_ => Ok(false),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn available() -> Result<bool> {
|
||||
let ucv_available = UserConsentVerifier::CheckAvailabilityAsync()?.get()?;
|
||||
|
||||
match ucv_available {
|
||||
UserConsentVerifierAvailability::Available => Ok(true),
|
||||
UserConsentVerifierAvailability::DeviceBusy => Ok(true), // TODO: Look into removing this and making the check more ad-hoc
|
||||
_ => Ok(false),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_prompt() {
|
||||
prompt(
|
||||
vec![0, 0, 0, 0, 0, 0, 0, 0],
|
||||
String::from("Hello from Rust"),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_available() {
|
||||
assert!(available().unwrap())
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
#[macro_use]
|
||||
extern crate napi_derive;
|
||||
|
||||
mod biometric;
|
||||
mod password;
|
||||
|
||||
#[napi]
|
||||
@ -37,3 +38,21 @@ pub mod passwords {
|
||||
.map_err(|e| napi::Error::from_reason(e.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub mod biometrics {
|
||||
// Prompt for biometric confirmation
|
||||
#[napi]
|
||||
pub async fn prompt(
|
||||
hwnd: napi::bindgen_prelude::Buffer,
|
||||
message: String,
|
||||
) -> napi::Result<bool> {
|
||||
super::biometric::prompt(hwnd.into(), message)
|
||||
.map_err(|e| napi::Error::from_reason(e.to_string()))
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub async fn available() -> napi::Result<bool> {
|
||||
super::biometric::available().map_err(|e| napi::Error::from_reason(e.to_string()))
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,12 @@
|
||||
},
|
||||
"afterSign": "scripts/after-sign.js",
|
||||
"asarUnpack": ["**/*.node"],
|
||||
"files": ["**/*", "!**/node_modules/@bitwarden/desktop-native/**/*"],
|
||||
"files": [
|
||||
"**/*",
|
||||
"!**/node_modules/@bitwarden/desktop-native/**/*",
|
||||
"**/node_modules/@bitwarden/desktop-native/index.js",
|
||||
"**/node_modules/@bitwarden/desktop-native/desktop_native.${platform}-${arch}*.node"
|
||||
],
|
||||
"electronVersion": "19.0.8",
|
||||
"generateUpdatesFilesForAllChannels": true,
|
||||
"publish": {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Component, NgZone } from "@angular/core";
|
||||
import { FormControl, FormGroup, Validators } from "@angular/forms";
|
||||
import { UntypedFormControl, UntypedFormGroup, Validators } from "@angular/forms";
|
||||
import { Router } from "@angular/router";
|
||||
|
||||
import { BroadcasterService } from "@bitwarden/common/abstractions/broadcaster.service";
|
||||
@ -19,8 +19,8 @@ export class AccessibilityCookieComponent {
|
||||
listenForCookie = false;
|
||||
hCaptchaWindow: Window;
|
||||
|
||||
accessibilityForm = new FormGroup({
|
||||
link: new FormControl("", Validators.required),
|
||||
accessibilityForm = new UntypedFormGroup({
|
||||
link: new UntypedFormControl("", Validators.required),
|
||||
});
|
||||
|
||||
constructor(
|
||||
|
38
apps/desktop/src/app/accounts/delete-account.component.html
Normal file
38
apps/desktop/src/app/accounts/delete-account.component.html
Normal file
@ -0,0 +1,38 @@
|
||||
<div class="modal fade" role="dialog" aria-modal="true" attr.aria-label="{{ 'settings' | i18n }}">
|
||||
<div class="modal-dialog" role="document">
|
||||
<form
|
||||
class="modal-content"
|
||||
#form
|
||||
[appApiAction]="formPromise"
|
||||
(ngSubmit)="submit()"
|
||||
[formGroup]="deleteForm"
|
||||
>
|
||||
<div class="modal-body">
|
||||
<p class="modal-text">{{ "deleteAccountDesc" | i18n }}</p>
|
||||
<app-callout type="warning" title="{{ 'warning' | i18n }}">
|
||||
{{ "deleteAccountWarning" | i18n }}
|
||||
</app-callout>
|
||||
<div class="box last">
|
||||
<div class="box-header">{{ "deleteAccount" | i18n }}</div>
|
||||
<div class="box-content">
|
||||
<app-user-verification
|
||||
ngDefaultControl
|
||||
formControlName="verification"
|
||||
name="verification"
|
||||
>
|
||||
</app-user-verification>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" class="danger" [disabled]="form.loading || !secret">
|
||||
<i class="bwi bwi-spinner bwi-spin" [hidden]="!form.loading" aria-hidden="true"></i>
|
||||
<span [hidden]="form.loading">{{ "deleteAccount" | i18n }}</span>
|
||||
</button>
|
||||
<button type="button" data-dismiss="modal" [disabled]="form.loading">
|
||||
{{ "cancel" | i18n }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
48
apps/desktop/src/app/accounts/delete-account.component.ts
Normal file
48
apps/desktop/src/app/accounts/delete-account.component.ts
Normal file
@ -0,0 +1,48 @@
|
||||
import { Component } from "@angular/core";
|
||||
import { FormBuilder } from "@angular/forms";
|
||||
|
||||
import { AccountService } from "@bitwarden/common/abstractions/account/account.service.abstraction";
|
||||
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/abstractions/log.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
||||
|
||||
import { Verification } from "../../../../../libs/common/src/types/verification";
|
||||
|
||||
@Component({
|
||||
selector: "app-delete-account",
|
||||
templateUrl: "delete-account.component.html",
|
||||
})
|
||||
export class DeleteAccountComponent {
|
||||
formPromise: Promise<void>;
|
||||
|
||||
deleteForm = this.formBuilder.group({
|
||||
verification: undefined as Verification | undefined,
|
||||
});
|
||||
|
||||
constructor(
|
||||
private i18nService: I18nService,
|
||||
private platformUtilsService: PlatformUtilsService,
|
||||
private formBuilder: FormBuilder,
|
||||
private accountService: AccountService,
|
||||
private logService: LogService
|
||||
) {}
|
||||
|
||||
get secret() {
|
||||
return this.deleteForm.get("verification")?.value?.secret;
|
||||
}
|
||||
|
||||
async submit() {
|
||||
try {
|
||||
const verification = this.deleteForm.get("verification").value;
|
||||
this.formPromise = this.accountService.delete(verification);
|
||||
await this.formPromise;
|
||||
this.platformUtilsService.showToast(
|
||||
"success",
|
||||
this.i18nService.t("accountDeleted"),
|
||||
this.i18nService.t("accountDeletedDesc")
|
||||
);
|
||||
} catch (e) {
|
||||
this.logService.error(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -18,11 +18,8 @@
|
||||
<div class="row-main">
|
||||
<label for="masterPassword">
|
||||
{{ "masterPass" | i18n }}
|
||||
<strong
|
||||
class="sub-label text-{{ masterPasswordScoreColor }}"
|
||||
*ngIf="masterPasswordScoreText"
|
||||
>
|
||||
{{ masterPasswordScoreText }}
|
||||
<strong class="sub-label text-{{ color }}" *ngIf="text">
|
||||
{{ text }}
|
||||
</strong>
|
||||
</label>
|
||||
<input
|
||||
@ -30,7 +27,6 @@
|
||||
type="{{ showPassword ? 'text' : 'password' }}"
|
||||
class="monospaced"
|
||||
formControlName="masterPassword"
|
||||
(input)="updatePasswordStrength()"
|
||||
appInputVerbatim
|
||||
/>
|
||||
</div>
|
||||
@ -51,17 +47,14 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress">
|
||||
<div
|
||||
class="progress-bar bg-{{ masterPasswordScoreColor }}"
|
||||
role="progressbar"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
[ngStyle]="{ width: masterPasswordScoreWidth + '%' }"
|
||||
attr.aria-valuenow="{{ masterPasswordScoreWidth }}"
|
||||
></div>
|
||||
</div>
|
||||
<app-password-strength
|
||||
[password]="formGroup.get('masterPassword')?.value"
|
||||
[email]="formGroup.get('email')?.value"
|
||||
[name]="formGroup.get('name')?.value"
|
||||
(passwordStrengthResult)="getStrengthResult($event)"
|
||||
(passwordScoreColor)="getPasswordScoreText($event)"
|
||||
>
|
||||
</app-password-strength>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Component, NgZone, OnDestroy, OnInit } from "@angular/core";
|
||||
import { FormBuilder } from "@angular/forms";
|
||||
import { UntypedFormBuilder } from "@angular/forms";
|
||||
import { Router } from "@angular/router";
|
||||
|
||||
import { RegisterComponent as BaseRegisterComponent } from "@bitwarden/angular/components/register.component";
|
||||
@ -24,7 +24,7 @@ const BroadcasterSubscriptionId = "RegisterComponent";
|
||||
export class RegisterComponent extends BaseRegisterComponent implements OnInit, OnDestroy {
|
||||
constructor(
|
||||
formValidationErrorService: FormValidationErrorsService,
|
||||
formBuilder: FormBuilder,
|
||||
formBuilder: UntypedFormBuilder,
|
||||
authService: AuthService,
|
||||
router: Router,
|
||||
i18nService: I18nService,
|
||||
|
@ -37,11 +37,8 @@
|
||||
<div class="row-main">
|
||||
<label for="masterPassword"
|
||||
>{{ "masterPass" | i18n }}
|
||||
<strong
|
||||
class="sub-label text-{{ masterPasswordScoreColor }}"
|
||||
*ngIf="masterPasswordScoreText"
|
||||
>
|
||||
{{ masterPasswordScoreText }}
|
||||
<strong class="sub-label text-{{ color }}" *ngIf="text">
|
||||
{{ text }}
|
||||
</strong>
|
||||
</label>
|
||||
<input
|
||||
@ -51,7 +48,6 @@
|
||||
class="monospaced"
|
||||
[(ngModel)]="masterPassword"
|
||||
required
|
||||
(input)="updatePasswordStrength()"
|
||||
appInputVerbatim
|
||||
/>
|
||||
</div>
|
||||
@ -72,17 +68,13 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress">
|
||||
<div
|
||||
class="progress-bar bg-{{ masterPasswordScoreColor }}"
|
||||
role="progressbar"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
[ngStyle]="{ width: masterPasswordScoreWidth + '%' }"
|
||||
attr.aria-valuenow="{{ masterPasswordScoreWidth }}"
|
||||
></div>
|
||||
</div>
|
||||
<app-password-strength
|
||||
[password]="masterPassword"
|
||||
[email]="email"
|
||||
(passwordStrengthResult)="getStrengthResult($event)"
|
||||
(passwordScoreColor)="getPasswordScoreText($event)"
|
||||
>
|
||||
</app-password-strength>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
@ -147,7 +139,7 @@
|
||||
></i>
|
||||
<span>{{ "submit" | i18n }}</span>
|
||||
</button>
|
||||
<button class="btn block" (click)="logOut()">
|
||||
<button type="button" class="btn block" (click)="logOut()">
|
||||
<span>{{ "logOut" | i18n }}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -50,36 +50,6 @@ export class SetPasswordComponent extends BaseSetPasswordComponent implements On
|
||||
);
|
||||
}
|
||||
|
||||
get masterPasswordScoreWidth() {
|
||||
return this.masterPasswordScore == null ? 0 : (this.masterPasswordScore + 1) * 20;
|
||||
}
|
||||
|
||||
get masterPasswordScoreColor() {
|
||||
switch (this.masterPasswordScore) {
|
||||
case 4:
|
||||
return "success";
|
||||
case 3:
|
||||
return "primary";
|
||||
case 2:
|
||||
return "warning";
|
||||
default:
|
||||
return "danger";
|
||||
}
|
||||
}
|
||||
|
||||
get masterPasswordScoreText() {
|
||||
switch (this.masterPasswordScore) {
|
||||
case 4:
|
||||
return this.i18nService.t("strong");
|
||||
case 3:
|
||||
return this.i18nService.t("good");
|
||||
case 2:
|
||||
return this.i18nService.t("weak");
|
||||
default:
|
||||
return this.masterPasswordScore != null ? this.i18nService.t("weak") : null;
|
||||
}
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
await super.ngOnInit();
|
||||
this.broadcasterService.subscribe(BroadcasterSubscriptionId, async (message: any) => {
|
||||
|
@ -108,6 +108,14 @@
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>{{ "deleteAccount" | i18n }}</label>
|
||||
<small class="help-block">
|
||||
{{ "deleteAccountDesc" | i18n }}
|
||||
<a (click)="openDeleteAccount()">{{ "deleteAccount" | i18n }}</a>
|
||||
</small>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { FormControl } from "@angular/forms";
|
||||
import { UntypedFormControl } from "@angular/forms";
|
||||
import { debounceTime } from "rxjs/operators";
|
||||
|
||||
import { ModalService } from "@bitwarden/angular/services/modal.service";
|
||||
@ -18,6 +18,8 @@ import { isWindowsStore } from "@bitwarden/electron/utils";
|
||||
|
||||
import { SetPinComponent } from "../components/set-pin.component";
|
||||
|
||||
import { DeleteAccountComponent } from "./delete-account.component";
|
||||
|
||||
@Component({
|
||||
selector: "app-settings",
|
||||
templateUrl: "settings.component.html",
|
||||
@ -60,7 +62,7 @@ export class SettingsComponent implements OnInit {
|
||||
startToTrayText: string;
|
||||
startToTrayDescText: string;
|
||||
|
||||
vaultTimeout: FormControl = new FormControl(null);
|
||||
vaultTimeout: UntypedFormControl = new UntypedFormControl(null);
|
||||
|
||||
showSecurity = true;
|
||||
showAccountPreferences = true;
|
||||
@ -437,4 +439,8 @@ export class SettingsComponent implements OnInit {
|
||||
this.enableBrowserIntegrationFingerprint
|
||||
);
|
||||
}
|
||||
|
||||
async openDeleteAccount() {
|
||||
this.modalService.open(DeleteAccountComponent, { replaceTopModal: true });
|
||||
}
|
||||
}
|
||||
|
@ -16,11 +16,8 @@
|
||||
<div class="row-main">
|
||||
<label for="masterPassword">
|
||||
{{ "masterPass" | i18n }}
|
||||
<strong
|
||||
class="sub-label text-{{ masterPasswordScoreStyle.Color }}"
|
||||
*ngIf="masterPasswordScoreStyle.Text"
|
||||
>
|
||||
{{ masterPasswordScoreStyle.Text }}
|
||||
<strong class="sub-label text-{{ color }}" *ngIf="text">
|
||||
{{ text }}
|
||||
</strong>
|
||||
</label>
|
||||
<input
|
||||
@ -31,7 +28,6 @@
|
||||
[(ngModel)]="masterPassword"
|
||||
required
|
||||
[appAutofocus]="masterPassword === ''"
|
||||
(input)="updatePasswordStrength()"
|
||||
appInputVerbatim
|
||||
/>
|
||||
</div>
|
||||
@ -52,17 +48,13 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress">
|
||||
<div
|
||||
class="progress-bar bg-{{ masterPasswordScoreStyle.Color }}"
|
||||
role="progressbar"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
[ngStyle]="{ width: masterPasswordScoreStyle.Width + '%' }"
|
||||
attr.aria-valuenow="{{ masterPasswordScoreStyle.Width }}"
|
||||
></div>
|
||||
</div>
|
||||
<app-password-strength
|
||||
[password]="masterPassword"
|
||||
[email]="email"
|
||||
(passwordStrengthResult)="getStrengthResult($event)"
|
||||
(passwordScoreColor)="getPasswordScoreText($event)"
|
||||
>
|
||||
</app-password-strength>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -12,46 +12,11 @@ import { PolicyService } from "@bitwarden/common/abstractions/policy.service";
|
||||
import { StateService } from "@bitwarden/common/abstractions/state.service";
|
||||
import { SyncService } from "@bitwarden/common/abstractions/sync.service";
|
||||
|
||||
interface MasterPasswordScore {
|
||||
Color: string;
|
||||
Text: string;
|
||||
Width: number;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: "app-update-temp-password",
|
||||
templateUrl: "update-temp-password.component.html",
|
||||
})
|
||||
export class UpdateTempPasswordComponent extends BaseUpdateTempPasswordComponent {
|
||||
get masterPasswordScoreStyle(): MasterPasswordScore {
|
||||
const scoreWidth = this.masterPasswordScore == null ? 0 : (this.masterPasswordScore + 1) * 20;
|
||||
switch (this.masterPasswordScore) {
|
||||
case 4:
|
||||
return {
|
||||
Color: "bg-success",
|
||||
Text: "strong",
|
||||
Width: scoreWidth,
|
||||
};
|
||||
case 3:
|
||||
return {
|
||||
Color: "bg-primary",
|
||||
Text: "good",
|
||||
Width: scoreWidth,
|
||||
};
|
||||
case 2:
|
||||
return {
|
||||
Color: "bg-warning",
|
||||
Text: "weak",
|
||||
Width: scoreWidth,
|
||||
};
|
||||
default:
|
||||
return {
|
||||
Color: "bg-danger",
|
||||
Text: "weak",
|
||||
Width: scoreWidth,
|
||||
};
|
||||
}
|
||||
}
|
||||
constructor(
|
||||
i18nService: I18nService,
|
||||
platformUtilsService: PlatformUtilsService,
|
||||
|
@ -40,6 +40,7 @@ import { CipherType } from "@bitwarden/common/enums/cipherType";
|
||||
|
||||
import { MenuUpdateRequest } from "../main/menu/menu.updater";
|
||||
|
||||
import { DeleteAccountComponent } from "./accounts/delete-account.component";
|
||||
import { PremiumComponent } from "./accounts/premium.component";
|
||||
import { SettingsComponent } from "./accounts/settings.component";
|
||||
import { ExportComponent } from "./vault/export.component";
|
||||
@ -153,9 +154,7 @@ export class AppComponent implements OnInit {
|
||||
this.systemService.cancelProcessReload();
|
||||
break;
|
||||
case "loggedOut":
|
||||
if (this.modal != null) {
|
||||
this.modal.close();
|
||||
}
|
||||
this.modalService.closeAll();
|
||||
this.notificationsService.updateConnection();
|
||||
this.updateAppMenu();
|
||||
await this.systemService.clearPendingClipboard();
|
||||
@ -180,9 +179,7 @@ export class AppComponent implements OnInit {
|
||||
}
|
||||
break;
|
||||
case "locked":
|
||||
if (this.modal != null) {
|
||||
this.modal.close();
|
||||
}
|
||||
this.modalService.closeAll();
|
||||
if (
|
||||
message.userId == null ||
|
||||
message.userId === (await this.stateService.getUserId())
|
||||
@ -195,7 +192,7 @@ export class AppComponent implements OnInit {
|
||||
await this.reloadProcess();
|
||||
break;
|
||||
case "reloadProcess":
|
||||
window.location.reload();
|
||||
(window.location as any).reload(true);
|
||||
break;
|
||||
case "syncStarted":
|
||||
break;
|
||||
@ -223,6 +220,9 @@ export class AppComponent implements OnInit {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "deleteAccount":
|
||||
this.modalService.open(DeleteAccountComponent, { replaceTopModal: true });
|
||||
break;
|
||||
case "openPasswordHistory":
|
||||
await this.openModal<PasswordGeneratorHistoryComponent>(
|
||||
PasswordGeneratorHistoryComponent,
|
||||
@ -368,9 +368,7 @@ export class AppComponent implements OnInit {
|
||||
}
|
||||
|
||||
async openExportVault() {
|
||||
if (this.modal != null) {
|
||||
this.modal.close();
|
||||
}
|
||||
this.modalService.closeAll();
|
||||
|
||||
const [modal, childComponent] = await this.modalService.openViewRef(
|
||||
ExportComponent,
|
||||
@ -388,9 +386,7 @@ export class AppComponent implements OnInit {
|
||||
}
|
||||
|
||||
async addFolder() {
|
||||
if (this.modal != null) {
|
||||
this.modal.close();
|
||||
}
|
||||
this.modalService.closeAll();
|
||||
|
||||
const [modal, childComponent] = await this.modalService.openViewRef(
|
||||
FolderAddEditComponent,
|
||||
@ -410,9 +406,7 @@ export class AppComponent implements OnInit {
|
||||
}
|
||||
|
||||
async openGenerator() {
|
||||
if (this.modal != null) {
|
||||
this.modal.close();
|
||||
}
|
||||
this.modalService.closeAll();
|
||||
|
||||
[this.modal] = await this.modalService.openViewRef(
|
||||
GeneratorComponent,
|
||||
@ -542,9 +536,7 @@ export class AppComponent implements OnInit {
|
||||
}
|
||||
|
||||
private async openModal<T>(type: Type<T>, ref: ViewContainerRef) {
|
||||
if (this.modal != null) {
|
||||
this.modal.close();
|
||||
}
|
||||
this.modalService.closeAll();
|
||||
|
||||
[this.modal] = await this.modalService.openViewRef(type, ref);
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user