├── .build_env.template ├── .dockerignore ├── .env.template ├── .github ├── CODEOWNERS └── workflows │ ├── ci.yml │ └── release.yml ├── .gitignore ├── .hadolint.yaml ├── Dockerfile ├── LICENSE.txt ├── Makefile ├── README.md ├── package_web_vault.sh ├── patches ├── legacy │ ├── v2.10.0.patch │ ├── v2.11.0.patch │ ├── v2.12.0.patch │ ├── v2.14.0.patch │ ├── v2.15.1.patch │ ├── v2.16.0.patch │ ├── v2.16.1.patch │ ├── v2.17.1.patch │ ├── v2.18.0.patch │ ├── v2.18.1.patch │ ├── v2.19.0.patch │ ├── v2.20.1.patch │ ├── v2.20.3.patch │ ├── v2.20.4.patch │ ├── v2.21.1.patch │ ├── v2.22.3.patch │ ├── v2.23.0.patch │ ├── v2.24.0.patch │ ├── v2.25.0.patch │ ├── v2.26.1.patch │ ├── v2.27.0.patch │ ├── v2.28.0.patch │ ├── v2.5.0.patch │ ├── v2.8.0.patch │ ├── v2022.05.0.patch │ ├── v2022.10.0.patch │ ├── v2022.10.2a.patch │ ├── v2022.11.1.patch │ ├── v2022.12.0.patch │ ├── v2022.5.2.patch │ ├── v2022.6.0.patch │ ├── v2022.8.0.patch │ ├── v2022.9.0.patch │ ├── v2022.9.2.patch │ ├── v2023.1.0.patch │ ├── v2023.1.1.patch │ ├── v2023.10.0.patch │ ├── v2023.12.0.patch │ ├── v2023.2.0.patch │ ├── v2023.3.0.patch │ ├── v2023.4.0.patch │ ├── v2023.5.0.patch │ ├── v2023.5.1.patch │ ├── v2023.7.1.patch │ ├── v2023.8.2.patch │ └── v2023.9.1.patch ├── v2024.1.0.patch ├── v2024.1.2.patch ├── v2024.10.5.patch ├── v2024.11.2.patch ├── v2024.12.0.patch ├── v2024.2.4.patch ├── v2024.3.0.patch ├── v2024.3.1.patch ├── v2024.4.1.patch ├── v2024.4.2.patch ├── v2024.5.0.patch ├── v2024.6.2.patch ├── v2025.1.0.patch ├── v2025.1.1.patch ├── v2025.1.2.patch ├── v2025.2.1.patch ├── v2025.2.2.patch ├── v2025.3.1.patch ├── v2025.4.0.patch └── v2025.4.1.patch ├── resources ├── src │ ├── favicon.ico │ └── images │ │ ├── icon-dark.png │ │ ├── icon-white.png │ │ ├── icon-white.svg │ │ ├── icons │ │ ├── android-chrome-192x192.png │ │ ├── android-chrome-512x512.png │ │ ├── apple-touch-icon.png │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── mstile-150x150.png │ │ └── safari-pinned-tab.svg │ │ ├── logo-dark@2x.png │ │ ├── logo-white.svg │ │ ├── logo-white@2x.png │ │ └── logo.svg ├── vaultwarden-admin-console-logo.svg ├── vaultwarden-icon.svg └── vaultwarden-password-manager-logo.svg └── scripts ├── .script_env ├── build_web_vault.sh ├── checkout_web_vault.sh ├── gh_prepare.sh ├── gh_release.sh ├── package_web_vault.sh └── tar_web_vault.sh /.build_env.template: -------------------------------------------------------------------------------- 1 | # shellcheck disable=SC2034,SC2148 2 | # ### 3 | # Do not use quotes for these variables! 4 | # 5 | # These variables will be loaded during the building process 6 | # This can be useful if you need to provide special variables for NodeJS or other applications 7 | # Make sure you export variables which are used for external scripts, else they will not be seen! 8 | # ### 9 | 10 | # Configure NodeJS Virtual Memory Allocation 11 | # NODE_OPTIONS=--max-old-space-size=4096 12 | # export NODE_OPTIONS 13 | 14 | # vim: syntax=sh filetype=sh 15 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | # Local build artifacts 2 | builds 3 | docker_builds 4 | container_builds 5 | web-vault 6 | 7 | # Documentation 8 | *.md 9 | *.txt 10 | 11 | # IDE files 12 | .vscode 13 | .idea 14 | *.iml 15 | 16 | # Environment files 17 | .env 18 | .build_env 19 | 20 | # Other 21 | .github 22 | Makefile 23 | 24 | # Release files 25 | *.tar.gz 26 | *.tar.gz.asc 27 | *.tar.gz.text 28 | sha256sums.txt 29 | -------------------------------------------------------------------------------- /.env.template: -------------------------------------------------------------------------------- 1 | # shellcheck disable=SC2034,SC2148 2 | # ### 3 | # Do not use quotes for these variables! 4 | # ### 5 | 6 | # To use either docker or podman 7 | # The default is docker 8 | # CONTAINER_CMD=docker 9 | 10 | # This is only used for the gh-release command 11 | # Which Key or User to use to signing the web-vault tar.gz file 12 | # GPG_SIGNING_USER=user@domain.tld 13 | # GPG_SIGNING_USER=MY_LONG_UNIQUE_GPG_KEY_IDENTIFIER 14 | 15 | # vim: syntax=sh filetype=sh 16 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | /.github @dani-garcia @BlackDex 2 | /.github/CODEOWNERS @dani-garcia @BlackDex 3 | /.github/workflows/** @dani-garcia @BlackDex 4 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | pull_request: 5 | paths: 6 | - ".github/workflows/ci.yml" 7 | - "patches/v20*.patch" 8 | - "resources/**" 9 | - "scripts/**" 10 | - "Dockerfile" 11 | 12 | jobs: 13 | docker-build: 14 | runs-on: ubuntu-latest 15 | env: 16 | # Force docker to output the progress in plain 17 | BUILDKIT_PROGRESS: plain 18 | steps: 19 | - name: Checkout 20 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 21 | 22 | - name: Build and Extract 23 | shell: bash 24 | run: | 25 | make docker-extract 26 | 27 | - name: Generate checksum 28 | shell: bash 29 | run: | 30 | echo "sha256sum: $(sha256sum container_builds/bw_web_vault.tar.gz)" 31 | 32 | - name: "Upload web-vault artifact" 33 | uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 34 | with: 35 | name: web-vault 36 | compression-level: 0 37 | path: container_builds/bw_web_vault.tar.gz 38 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v[0-9]+.[0-9]+.[0-9]+[a-z]?' 7 | 8 | jobs: 9 | docker-build: 10 | runs-on: ubuntu-latest 11 | env: 12 | # Force docker to output the progress in plain 13 | BUILDKIT_PROGRESS: plain 14 | # vars.DOCKERHUB_REPO needs to be '/', for example 'vaultwarden/web-vault' 15 | # Check for Docker hub credentials in secrets 16 | HAVE_DOCKERHUB_LOGIN: ${{ vars.DOCKERHUB_REPO != '' && secrets.DOCKERHUB_USERNAME != '' && secrets.DOCKERHUB_TOKEN != '' }} 17 | # vars.GHCR_REPO needs to be 'ghcr.io//' 18 | # Check for Github credentials in secrets 19 | HAVE_GHCR_LOGIN: ${{ vars.GHCR_REPO != '' && github.repository_owner != '' && secrets.GITHUB_TOKEN != '' }} 20 | steps: 21 | - name: Checkout 22 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 23 | 24 | # Determine Docker Tag 25 | - name: Init Variables 26 | id: vars 27 | shell: bash 28 | run: | 29 | if [[ "${{ github.ref }}" == refs/tags/* ]]; then 30 | echo "DOCKER_TAG=${GITHUB_REF#refs/*/}" | tee -a "${GITHUB_OUTPUT}" 31 | elif [[ "${{ github.ref }}" == refs/heads/* ]]; then 32 | echo "DOCKER_TAG=testing" | tee -a "${GITHUB_OUTPUT}" 33 | fi 34 | 35 | # Login to Docker Hub 36 | - name: Login to Docker Hub 37 | uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 38 | with: 39 | username: ${{ secrets.DOCKERHUB_USERNAME }} 40 | password: ${{ secrets.DOCKERHUB_TOKEN }} 41 | if: ${{ env.HAVE_DOCKERHUB_LOGIN == 'true' }} 42 | 43 | - name: Tags for DockerHub 44 | if: ${{ env.HAVE_DOCKERHUB_LOGIN == 'true' }} 45 | shell: bash 46 | run: | 47 | echo "tags=${tags:+${tags},}${{ vars.DOCKERHUB_REPO }}:${{ steps.vars.outputs.DOCKER_TAG }}" \ 48 | | tee -a "${GITHUB_ENV}" 49 | 50 | # Login to GitHub Container Registry 51 | - name: Login to GitHub Container Registry 52 | uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 53 | with: 54 | registry: ghcr.io 55 | username: ${{ github.repository_owner }} 56 | password: ${{ secrets.GITHUB_TOKEN }} 57 | if: ${{ env.HAVE_GHCR_LOGIN == 'true' }} 58 | 59 | - name: Tags for ghcr.io 60 | if: ${{ env.HAVE_GHCR_LOGIN == 'true' }} 61 | shell: bash 62 | run: | 63 | echo "tags=${tags:+${tags},}${{ vars.GHCR_REPO }}:${{ steps.vars.outputs.DOCKER_TAG }}" \ 64 | | tee -a "${GITHUB_ENV}" 65 | 66 | - name: Build and push 67 | uses: docker/build-push-action@4f58ea79222b3b9dc2c8bbdd6debcef730109a75 # v6.9.0 68 | with: 69 | context: . 70 | push: true 71 | tags: ${{ env.tags }} 72 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Local build artifacts 2 | builds 3 | docker_builds 4 | container_builds 5 | web-vault 6 | 7 | # IDE files 8 | .vscode 9 | .idea 10 | *.iml 11 | 12 | # Environment files 13 | .env 14 | .build_env 15 | 16 | # Release files 17 | *.tar.gz 18 | *.tar.gz.asc 19 | *.tar.gz.text 20 | sha256sums.txt 21 | -------------------------------------------------------------------------------- /.hadolint.yaml: -------------------------------------------------------------------------------- 1 | ignored: 2 | # Disable Multiple consecutive `RUN` instructions check. 3 | - DL3059 4 | # Disable pipefail check 5 | - DL4006 6 | # Disable Shellcheck Quote check 7 | - SC2046 8 | trustedRegistries: 9 | - docker.io 10 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | 3 | # Compile the web vault using docker 4 | # Usage: 5 | # Quick and easy: 6 | # `make container-extract` 7 | # or, if you just want to build 8 | # `make container` 9 | # The default is to use `docker` you can also configure `podman` via a `.env` file 10 | # See the `.env.template` file for more details 11 | # 12 | # docker build -t web_vault_build . 13 | # docker create --name bw_web_vault_extract web_vault_build 14 | # docker cp bw_web_vault_extract:/bw_web_vault.tar.gz . 15 | # docker rm bw_web_vault_extract 16 | # 17 | # Note: you can use --build-arg to specify the version to build: 18 | # docker build -t web_vault_build --build-arg VAULT_VERSION=main . 19 | 20 | FROM node:20-bookworm AS build 21 | RUN node --version && npm --version 22 | 23 | # Can be a tag, release, but prefer a commit hash because it's not changeable 24 | # https://github.com/bitwarden/clients/commit/${VAULT_VERSION} 25 | # 26 | # Using https://github.com/vaultwarden/vw_web_builds/tree/v2025.5.1 27 | ARG VAULT_VERSION=c51d0e09303a86aeda91d9877df4b025edb9a060 28 | ENV VAULT_VERSION=$VAULT_VERSION 29 | ENV VAULT_FOLDER=bw_clients 30 | ENV CHECKOUT_TAGS=false 31 | 32 | RUN mkdir /bw_web_builds 33 | WORKDIR /bw_web_builds 34 | 35 | COPY scripts ./scripts 36 | # Use a glob pattern here so builds will continue even if the `.build_env` does not exists 37 | COPY .build_env* ./ 38 | 39 | RUN ./scripts/checkout_web_vault.sh 40 | RUN ./scripts/build_web_vault.sh 41 | RUN mv "${VAULT_FOLDER}/apps/web/build" ./web-vault 42 | 43 | RUN tar -czvf "bw_web_vault.tar.gz" web-vault --owner=0 --group=0 44 | # Output the sha256sum here so people are able to match the sha256sum from the CI with the assets and the downloaded version if needed 45 | RUN echo "sha256sum: $(sha256sum bw_web_vault.tar.gz)" 46 | 47 | # We copy the final result as a separate empty image so there's no need to download all the intermediate steps 48 | # The result is included both uncompressed and as a tar.gz, to be able to use it in the docker images and the github releases directly 49 | FROM scratch 50 | # hadolint ignore=DL3010 51 | COPY --from=build /bw_web_builds/bw_web_vault.tar.gz /bw_web_vault.tar.gz 52 | COPY --from=build /bw_web_builds/web-vault /web-vault 53 | 54 | # Added so docker create works, can't actually run a scratch image 55 | CMD [""] 56 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SHELL := bash 2 | .ONESHELL: 3 | .SHELLFLAGS := -eu -o pipefail -c 4 | .DELETE_ON_ERROR: 5 | 6 | help: 7 | @echo "Use either: clean, checkout, build, tar, or full" 8 | @echo "Or for container builds use: container or container-extract" 9 | @echo 10 | @echo "By default docker is used, you can force podman by using podman or podman-extract" 11 | @echo "You can also define the default via a '.env' file, see the '.env.template' for details" 12 | @echo 13 | @echo "For releasing a new version you can use gh-prepare and gh-release" 14 | @echo 15 | .PHONY: help 16 | 17 | # Load .env variables if the file exists 18 | ifneq (,$(wildcard ./.env)) 19 | include .env 20 | export 21 | endif 22 | 23 | # Force docker to output the progress in plain 24 | BUILDKIT_PROGRESS=plain 25 | 26 | ifndef CONTAINER_CMD 27 | CONTAINER_CMD = docker 28 | endif 29 | 30 | clean: 31 | rm -rvf ./web-vault 32 | rm -rvf ./builds 33 | rm -rvf ./docker_builds 34 | rm -rvf ./container_builds 35 | rm -vf ./bw_web_v*.tar.gz* 36 | rm -vf sha256sums.txt 37 | .PHONY: clean 38 | 39 | checkout: 40 | ./scripts/checkout_web_vault.sh 41 | .PHONY: checkout 42 | 43 | build: 44 | ./scripts/build_web_vault.sh 45 | .PHONY: build 46 | 47 | tar: 48 | ./scripts/tar_web_vault.sh 49 | .PHONY: tar 50 | 51 | full: checkout build tar 52 | .PHONY: full 53 | 54 | container: 55 | ${CONTAINER_CMD} build -t bw_web_vault . 56 | .PHONY: container 57 | 58 | container-extract: container 59 | @${CONTAINER_CMD} rm bw_web_vault_extract 2>/dev/null || true 60 | @${CONTAINER_CMD} create --name bw_web_vault_extract bw_web_vault 61 | @mkdir -vp container_builds 62 | @rm -rf ./container_builds/bw_web_vault.tar.gz ./container_builds/web-vault 63 | @${CONTAINER_CMD} cp bw_web_vault_extract:/bw_web_vault.tar.gz ./container_builds/bw_web_vault.tar.gz 64 | @${CONTAINER_CMD} cp bw_web_vault_extract:/web-vault ./container_builds/web-vault 65 | @${CONTAINER_CMD} rm bw_web_vault_extract || true 66 | .PHONY: container-extract 67 | 68 | # Alias for container forcing docker 69 | docker: CONTAINER_CMD := docker 70 | docker: container 71 | .PHONY: docker 72 | 73 | # Alias for container forcing docker 74 | docker-extract: CONTAINER_CMD := docker 75 | docker-extract: container-extract 76 | .PHONY: docker-extract 77 | 78 | # Alias for container forcing podman 79 | podman: CONTAINER_CMD := podman 80 | podman: container 81 | .PHONY: podman 82 | 83 | # Alias for container forcing podman 84 | podman-extract: CONTAINER_CMD := podman 85 | podman-extract: container-extract 86 | .PHONY: podman-extract 87 | 88 | # This part is used for extracing and release a new version on Github 89 | gh-prepare: 90 | ./scripts/gh_prepare.sh 91 | .PHONY: gh-prepare 92 | 93 | gh-release: 94 | ./scripts/gh_release.sh 95 | .PHONY: gh-release 96 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Web Vault builds for Vaultwarden 2 | 3 | ![Vaultwarden Logo](https://raw.githubusercontent.com/dani-garcia/vaultwarden/refs/heads/main/resources/vaultwarden-logo-auto.svg) 4 | 5 | Scripts and CI to patch (including branding) and build the [Bitwarden web client](https://github.com/bitwarden/clients/tree/main/apps/web) [[disclaimer](#disclaimer)], to make it compatible with [Vaultwarden](https://github.com/dani-garcia/vaultwarden). 6 | 7 | --- 8 | 9 | [![GitHub Release](https://img.shields.io/github/release/dani-garcia/bw_web_builds.svg?style=for-the-badge&logo=vaultwarden&color=005AA4)](https://github.com/dani-garcia/bw_web_builds/releases/latest) 10 | [![ghcr.io Pulls](https://img.shields.io/badge/dynamic/json?style=for-the-badge&logo=github&logoColor=fff&color=005AA4&url=https%3A%2F%2Fipitio.github.io%2Fbackage%2Fdani-garcia%2Fbw_web_builds%2Fbw_web_builds.json&query=%24.downloads&label=ghcr.io%20pulls&cacheSeconds=14400)](https://github.com/dani-garcia/bw_web_builds/pkgs/container/bw_web_builds) 11 | [![Docker Pulls](https://img.shields.io/docker/pulls/vaultwarden/web-vault.svg?style=for-the-badge&logo=docker&logoColor=fff&color=005AA4&label=docker.io%20pulls)](https://hub.docker.com/r/vaultwarden/web-vault)
12 | [![GHA Release](https://img.shields.io/github/actions/workflow/status/dani-garcia/bw_web_builds/release.yml?style=flat-square&logo=github&logoColor=fff&label=Build%20Workflow)](https://github.com/dani-garcia/bw_web_builds/actions/workflows/release.yml) 13 | [![Contributors](https://img.shields.io/github/contributors-anon/dani-garcia/bw_web_builds.svg?style=flat-square&logo=vaultwarden&color=005AA4)](https://github.com/dani-garcia/bw_web_builds/graphs/contributors) 14 | [![Forks](https://img.shields.io/github/forks/dani-garcia/bw_web_builds.svg?style=flat-square&logo=github&logoColor=fff&color=005AA4)](https://github.com/dani-garcia/bw_web_builds/network/members) 15 | [![Stars](https://img.shields.io/github/stars/dani-garcia/bw_web_builds.svg?style=flat-square&logo=github&logoColor=fff&color=005AA4)](https://github.com/dani-garcia/bw_web_builds/stargazers) 16 | [![Issues Open](https://img.shields.io/github/issues/dani-garcia/bw_web_builds.svg?style=flat-square&logo=github&logoColor=fff&color=005AA4&cacheSeconds=300)](https://github.com/dani-garcia/bw_web_builds/issues) 17 | [![Issues Closed](https://img.shields.io/github/issues-closed/dani-garcia/bw_web_builds.svg?style=flat-square&logo=github&logoColor=fff&color=005AA4&cacheSeconds=300)](https://github.com/dani-garcia/bw_web_builds/issues?q=is%3Aissue+is%3Aclosed)
18 | [![Matrix Chat](https://img.shields.io/matrix/vaultwarden:matrix.org.svg?style=flat-square&logo=matrix&logoColor=fff&color=953B00&cacheSeconds=14400)](https://matrix.to/#/#vaultwarden:matrix.org) 19 | [![GitHub Discussions](https://img.shields.io/github/discussions/dani-garcia/vaultwarden?style=flat-square&logo=github&logoColor=fff&color=953B00&cacheSeconds=300)](https://github.com/dani-garcia/vaultwarden/discussions) 20 | [![Discourse Discussions](https://img.shields.io/discourse/topics?server=https%3A%2F%2Fvaultwarden.discourse.group%2F&style=flat-square&logo=discourse&color=953B00)](https://vaultwarden.discourse.group/) 21 | [![GPL-3.0 Licensed](https://img.shields.io/github/license/dani-garcia/bw_web_builds.svg?style=flat-square&logo=vaultwarden&color=944000&cacheSeconds=14400)](https://github.com/dani-garcia/bw_web_builds/blob/main/LICENSE.txt) 22 | 23 | 24 | > [!IMPORTANT] 25 | > **When using this web-vault, please report any bugs or suggestions directly to us (see [Get in touch](#get-in-touch)), regardless of whatever other clients you are using (mobile, desktop, browser...). DO NOT use the official Bitwarden support channels.** 26 | 27 | --- 28 | 29 | ## Building the web-vault 30 | 31 | To build the web-vault you need either node and npm installed or use Docker. 32 | 33 | ### Using node and npm 34 | 35 | For a quick and easy local build you could run: 36 | ```bash 37 | make full 38 | ``` 39 | 40 | That will generate a `tar.gz` file within the `builds` directory which you can extract and use with the `WEB_VAULT_FOLDER` environment variable. 41 | 42 | ### Using a container 43 | 44 | Or via the usage of building via a container: 45 | ```bash 46 | make container-extract 47 | ``` 48 | 49 | That will extract the `tar.gz` and files generated via Docker into the `container_builds` directory. 50 | 51 | #### Which container command to use, docker or podman 52 | 53 | The default is to use `docker`, but `podman` works too. 54 | 55 | You can force them by replacing `container` with either `docker` or `podman`, like: 56 | ```bash 57 | make docker-extract 58 | # Or 59 | make podman-extract 60 | ``` 61 | 62 | You can configure the default via a `.env` file. See the `.env.template`.
63 | Or you can set it as a make argument with the make command: 64 | ```bash 65 | make CONTAINER_CMD=podman container-extract 66 | ``` 67 | 68 | ### More information 69 | 70 | For more information see: [Install the web-vault](https://github.com/dani-garcia/vaultwarden/wiki/Building-binary#install-the-web-vault) 71 | 72 | 73 | ### Pre-build 74 | 75 | The builds are available in the [releases page](https://github.com/dani-garcia/bw_web_builds/releases), and can be replicated with the scripts in this repo. 76 | 77 |
78 | 79 | ## Get in touch 80 | 81 | Have a question, suggestion or need help? Join our community on [Matrix](https://matrix.to/#/#vaultwarden:matrix.org), [GitHub Discussions](https://github.com/dani-garcia/vaultwarden/discussions) or [Discourse Forums](https://vaultwarden.discourse.group/). 82 | 83 | Encountered a bug or crash? Please search our issue tracker and discussions to see if it's already been reported. If not, please [start a new discussion](https://github.com/dani-garcia/vaultwarden/discussions) or [create a new issue](https://github.com/dani-garcia/vaultwarden/issues/). Ensure you're using the latest version of Vaultwarden and there aren't any similar issues open or closed! 84 | 85 |
86 | 87 | ## Disclaimer 88 | 89 | **This project is not associated with [Bitwarden](https://bitwarden.com/) or Bitwarden, Inc.** 90 | 91 | However, one of the active maintainers for Vaultwarden is employed by Bitwarden and is allowed to contribute to the project on their own time. These contributions are independent of Bitwarden and are reviewed by other maintainers. 92 | 93 | The maintainers work together to set the direction for the project, focusing on serving the self-hosting community, including individuals, families, and small organizations, while ensuring the project's sustainability. 94 | 95 | **Please note:** We cannot be held liable for any data loss that may occur while using Vaultwarden. This includes passwords, attachments, and other information handled by the application. We highly recommend performing regular backups of your files and database. However, should you experience data loss, we encourage you to contact us immediately. 96 | -------------------------------------------------------------------------------- /package_web_vault.sh: -------------------------------------------------------------------------------- 1 | scripts/package_web_vault.sh -------------------------------------------------------------------------------- /patches/legacy/v2.10.0.patch: -------------------------------------------------------------------------------- 1 | diff --git a/src/app/services/services.module.ts b/src/app/services/services.module.ts 2 | index 9c152ae1..218e9243 100644 3 | --- a/src/app/services/services.module.ts 4 | +++ b/src/app/services/services.module.ts 5 | @@ -120,20 +120,16 @@ const notificationsService = new NotificationsService(userService, syncService, 6 | const environmentService = new EnvironmentService(apiService, storageService, notificationsService); 7 | const auditService = new AuditService(cryptoFunctionService, apiService); 8 | 9 | -const analytics = new Analytics(window, () => platformUtilsService.isDev() || platformUtilsService.isSelfHost(), 10 | +const analytics = new Analytics(window, () => platformUtilsService.isDev() || platformUtilsService.isSelfHost() || true, 11 | platformUtilsService, storageService, appIdService); 12 | containerService.attachToWindow(window); 13 | 14 | export function initFactory(): Function { 15 | return async () => { 16 | await (storageService as HtmlStorageService).init(); 17 | - const isDev = platformUtilsService.isDev(); 18 | - if (!isDev && platformUtilsService.isSelfHost()) { 19 | - environmentService.baseUrl = window.location.origin; 20 | - } else { 21 | - environmentService.notificationsUrl = isDev ? 'http://localhost:61840' : 22 | - 'https://notifications.bitwarden.com'; // window.location.origin + '/notifications'; 23 | - } 24 | + const isDev = false; 25 | + environmentService.baseUrl = window.location.origin; 26 | + environmentService.notificationsUrl = window.location.origin + '/notifications'; 27 | apiService.setUrls({ 28 | base: isDev ? null : window.location.origin, 29 | api: isDev ? 'http://localhost:4000' : null, 30 | diff --git a/src/app/settings/two-factor-u2f.component.ts b/src/app/settings/two-factor-u2f.component.ts 31 | index 5560c476..a9b954a8 100644 32 | --- a/src/app/settings/two-factor-u2f.component.ts 33 | +++ b/src/app/settings/two-factor-u2f.component.ts 34 | @@ -128,6 +128,7 @@ export class TwoFactorU2fComponent extends TwoFactorBaseComponent implements OnI 35 | (window as any).u2f.register(u2fChallenge.appId, [{ 36 | version: u2fChallenge.version, 37 | challenge: u2fChallenge.challenge, 38 | + attestation: 'direct', 39 | }], [], (data: any) => { 40 | this.ngZone.run(() => { 41 | this.u2fListening = false; 42 | diff --git a/src/scss/styles.scss b/src/scss/styles.scss 43 | index 2e1dbec9..2d9b635f 100644 44 | --- a/src/scss/styles.scss 45 | +++ b/src/scss/styles.scss 46 | @@ -1,5 +1,34 @@ 47 | @import "../css/webfonts.css"; 48 | 49 | +/**** START Bitwarden_RS CHANGES ****/ 50 | +/* This combines all selectors extending it into one */ 51 | +%bwrs-hide { display: none !important; } 52 | + 53 | +/* This allows searching for the combined style in the browsers dev-tools (look into the head tag) */ 54 | +#bwrs-hide, head { @extend %bwrs-hide; } 55 | + 56 | +/* Hide any link pointing to billing */ 57 | +a[href$="/settings/billing"] { @extend %bwrs-hide; } 58 | + 59 | +/* Hide any link pointing to subscriptions */ 60 | +a[href$="/settings/subscription"] { @extend %bwrs-hide; } 61 | + 62 | +/* Hide Two-Factor menu in Organization settings */ 63 | +app-org-settings a[href$="/settings/two-factor"] { @extend %bwrs-hide; } 64 | + 65 | +/* Hide 2FA Email button */ 66 | +ul.list-group.list-group-2fa > li:nth-child(5) button { @extend %bwrs-hide; } 67 | + 68 | +/* Hide organization plans */ 69 | +app-organization-plans > form > div.form-check { @extend %bwrs-hide; } 70 | +app-organization-plans > form > h2.mt-5 { @extend %bwrs-hide; } 71 | + 72 | +/* Hide Tax Info in Organization settings */ 73 | +app-org-account > div.secondary-header.border-0.mb-0:nth-child(3) { @extend %bwrs-hide; } 74 | +app-org-account > p { @extend %bwrs-hide; } 75 | +app-org-account > a.btn.btn-outline-secondary { @extend %bwrs-hide; } 76 | +/**** END Bitwarden_RS CHANGES ****/ 77 | + 78 | $primary: #3c8dbc; 79 | $primary-accent: #286090; 80 | $secondary: #ced4da; 81 | diff --git a/webpack.config.js b/webpack.config.js 82 | index aecb1860..44acdc1d 100644 83 | --- a/webpack.config.js 84 | +++ b/webpack.config.js 85 | @@ -170,6 +170,7 @@ const config = { 86 | }, 87 | minimizer: [ 88 | new TerserPlugin({ 89 | + sourceMap: true, 90 | terserOptions: { 91 | safari10: true, 92 | }, 93 | -------------------------------------------------------------------------------- /patches/legacy/v2.11.0.patch: -------------------------------------------------------------------------------- 1 | diff --git a/src/app/services/services.module.ts b/src/app/services/services.module.ts 2 | index a92bf70c..cf5a4cb4 100644 3 | --- a/src/app/services/services.module.ts 4 | +++ b/src/app/services/services.module.ts 5 | @@ -123,20 +123,16 @@ const environmentService = new EnvironmentService(apiService, storageService, no 6 | const auditService = new AuditService(cryptoFunctionService, apiService); 7 | const eventLoggingService = new EventLoggingService(storageService, apiService, userService, cipherService); 8 | 9 | -const analytics = new Analytics(window, () => platformUtilsService.isDev() || platformUtilsService.isSelfHost(), 10 | +const analytics = new Analytics(window, () => platformUtilsService.isDev() || platformUtilsService.isSelfHost() || true, 11 | platformUtilsService, storageService, appIdService); 12 | containerService.attachToWindow(window); 13 | 14 | export function initFactory(): Function { 15 | return async () => { 16 | await (storageService as HtmlStorageService).init(); 17 | - const isDev = platformUtilsService.isDev(); 18 | - if (!isDev && platformUtilsService.isSelfHost()) { 19 | - environmentService.baseUrl = window.location.origin; 20 | - } else { 21 | - environmentService.notificationsUrl = isDev ? 'http://localhost:61840' : 22 | - 'https://notifications.bitwarden.com'; // window.location.origin + '/notifications'; 23 | - } 24 | + const isDev = false; 25 | + environmentService.baseUrl = window.location.origin; 26 | + environmentService.notificationsUrl = window.location.origin + '/notifications'; 27 | apiService.setUrls({ 28 | base: isDev ? null : window.location.origin, 29 | api: isDev ? 'http://localhost:4000' : null, 30 | diff --git a/src/app/settings/two-factor-u2f.component.ts b/src/app/settings/two-factor-u2f.component.ts 31 | index 5560c476..a9b954a8 100644 32 | --- a/src/app/settings/two-factor-u2f.component.ts 33 | +++ b/src/app/settings/two-factor-u2f.component.ts 34 | @@ -128,6 +128,7 @@ export class TwoFactorU2fComponent extends TwoFactorBaseComponent implements OnI 35 | (window as any).u2f.register(u2fChallenge.appId, [{ 36 | version: u2fChallenge.version, 37 | challenge: u2fChallenge.challenge, 38 | + attestation: 'direct', 39 | }], [], (data: any) => { 40 | this.ngZone.run(() => { 41 | this.u2fListening = false; 42 | diff --git a/src/scss/styles.scss b/src/scss/styles.scss 43 | index 2e1dbec9..2d9b635f 100644 44 | --- a/src/scss/styles.scss 45 | +++ b/src/scss/styles.scss 46 | @@ -1,5 +1,31 @@ 47 | @import "../css/webfonts.css"; 48 | 49 | +/**** START Bitwarden_RS CHANGES ****/ 50 | +/* This combines all selectors extending it into one */ 51 | +%bwrs-hide { display: none !important; } 52 | + 53 | +/* This allows searching for the combined style in the browsers dev-tools (look into the head tag) */ 54 | +#bwrs-hide, head { @extend %bwrs-hide; } 55 | + 56 | +/* Hide any link pointing to billing */ 57 | +a[href$="/settings/billing"] { @extend %bwrs-hide; } 58 | + 59 | +/* Hide any link pointing to subscriptions */ 60 | +a[href$="/settings/subscription"] { @extend %bwrs-hide; } 61 | + 62 | +/* Hide Two-Factor menu in Organization settings */ 63 | +app-org-settings a[href$="/settings/two-factor"] { @extend %bwrs-hide; } 64 | + 65 | +/* Hide organization plans */ 66 | +app-organization-plans > form > div.form-check { @extend %bwrs-hide; } 67 | +app-organization-plans > form > h2.mt-5 { @extend %bwrs-hide; } 68 | + 69 | +/* Hide Tax Info in Organization settings */ 70 | +app-org-account > div.secondary-header.border-0.mb-0:nth-child(3) { @extend %bwrs-hide; } 71 | +app-org-account > p { @extend %bwrs-hide; } 72 | +app-org-account > a.btn.btn-outline-secondary { @extend %bwrs-hide; } 73 | +/**** END Bitwarden_RS CHANGES ****/ 74 | + 75 | $primary: #3c8dbc; 76 | $primary-accent: #286090; 77 | $secondary: #ced4da; 78 | diff --git a/webpack.config.js b/webpack.config.js 79 | index aecb1860..44acdc1d 100644 80 | --- a/webpack.config.js 81 | +++ b/webpack.config.js 82 | @@ -170,6 +170,7 @@ const config = { 83 | }, 84 | minimizer: [ 85 | new TerserPlugin({ 86 | + sourceMap: true, 87 | terserOptions: { 88 | safari10: true, 89 | }, 90 | -------------------------------------------------------------------------------- /patches/legacy/v2.12.0.patch: -------------------------------------------------------------------------------- 1 | diff --git a/src/app/app.component.ts b/src/app/app.component.ts 2 | index 2c694d95..bba34865 100644 3 | --- a/src/app/app.component.ts 4 | +++ b/src/app/app.component.ts 5 | @@ -140,6 +140,10 @@ export class AppComponent implements OnDestroy, OnInit { 6 | } 7 | break; 8 | case 'showToast': 9 | + if (typeof message.text === "string" && (message.text.indexOf("this.subtle") != -1 || message.text.indexOf("importKey") != -1)) { 10 | + message.title="This browser requires HTTPS to use the web vault"; 11 | + message.text="Check the bitwarden_rs wiki for details on how to enable it"; 12 | + } 13 | this.showToast(message); 14 | break; 15 | case 'analyticsEventTrack': 16 | diff --git a/src/app/services/services.module.ts b/src/app/services/services.module.ts 17 | index c74261dd..f61ccefe 100644 18 | --- a/src/app/services/services.module.ts 19 | +++ b/src/app/services/services.module.ts 20 | @@ -127,22 +127,31 @@ const environmentService = new EnvironmentService(apiService, storageService, no 21 | const auditService = new AuditService(cryptoFunctionService, apiService); 22 | const eventLoggingService = new EventLoggingService(storageService, apiService, userService, cipherService); 23 | 24 | -const analytics = new Analytics(window, () => platformUtilsService.isDev() || platformUtilsService.isSelfHost(), 25 | +const analytics = new Analytics(window, () => platformUtilsService.isDev() || platformUtilsService.isSelfHost() || true, 26 | platformUtilsService, storageService, appIdService); 27 | containerService.attachToWindow(window); 28 | 29 | export function initFactory(): Function { 30 | + function getBaseUrl() { 31 | + // If the base URL is `https://bitwarden.example.com/base/path/`, 32 | + // `window.location.href` should have one of the following forms: 33 | + // 34 | + // - `https://bitwarden.example.com/base/path/` 35 | + // - `https://bitwarden.example.com/base/path/#/some/endpoint[?queryParam=...]` 36 | + // 37 | + // We want to get to just `https://bitwarden.example.com/base/path`. 38 | + let baseUrl = window.location.href; 39 | + baseUrl = baseUrl.replace(/#.*/, ''); // Strip off `#` and everything after. 40 | + baseUrl = baseUrl.replace(/\/+$/, ''); // Trim any trailing `/` chars. 41 | + return baseUrl; 42 | + } 43 | return async () => { 44 | await (storageService as HtmlStorageService).init(); 45 | - const isDev = platformUtilsService.isDev(); 46 | - if (!isDev && platformUtilsService.isSelfHost()) { 47 | - environmentService.baseUrl = window.location.origin; 48 | - } else { 49 | - environmentService.notificationsUrl = isDev ? 'http://localhost:61840' : 50 | - 'https://notifications.bitwarden.com'; // window.location.origin + '/notifications'; 51 | - } 52 | + const isDev = false; 53 | + environmentService.baseUrl = getBaseUrl(); 54 | + environmentService.notificationsUrl = environmentService.baseUrl + '/notifications'; 55 | apiService.setUrls({ 56 | - base: isDev ? null : window.location.origin, 57 | + base: isDev ? null : environmentService.baseUrl, 58 | api: isDev ? 'http://localhost:4000' : null, 59 | identity: isDev ? 'http://localhost:33656' : null, 60 | events: isDev ? 'http://localhost:46273' : null, 61 | diff --git a/src/app/settings/two-factor-u2f.component.ts b/src/app/settings/two-factor-u2f.component.ts 62 | index 5560c476..a9b954a8 100644 63 | --- a/src/app/settings/two-factor-u2f.component.ts 64 | +++ b/src/app/settings/two-factor-u2f.component.ts 65 | @@ -128,6 +128,7 @@ export class TwoFactorU2fComponent extends TwoFactorBaseComponent implements OnI 66 | (window as any).u2f.register(u2fChallenge.appId, [{ 67 | version: u2fChallenge.version, 68 | challenge: u2fChallenge.challenge, 69 | + attestation: 'direct', 70 | }], [], (data: any) => { 71 | this.ngZone.run(() => { 72 | this.u2fListening = false; 73 | diff --git a/src/scss/styles.scss b/src/scss/styles.scss 74 | index 80951953..5c784175 100644 75 | --- a/src/scss/styles.scss 76 | +++ b/src/scss/styles.scss 77 | @@ -1,5 +1,31 @@ 78 | @import "../css/webfonts.css"; 79 | 80 | +/**** START Bitwarden_RS CHANGES ****/ 81 | +/* This combines all selectors extending it into one */ 82 | +%bwrs-hide { display: none !important; } 83 | + 84 | +/* This allows searching for the combined style in the browsers dev-tools (look into the head tag) */ 85 | +#bwrs-hide, head { @extend %bwrs-hide; } 86 | + 87 | +/* Hide any link pointing to billing */ 88 | +a[href$="/settings/billing"] { @extend %bwrs-hide; } 89 | + 90 | +/* Hide any link pointing to subscriptions */ 91 | +a[href$="/settings/subscription"] { @extend %bwrs-hide; } 92 | + 93 | +/* Hide Two-Factor menu in Organization settings */ 94 | +app-org-settings a[href$="/settings/two-factor"] { @extend %bwrs-hide; } 95 | + 96 | +/* Hide organization plans */ 97 | +app-organization-plans > form > div.form-check { @extend %bwrs-hide; } 98 | +app-organization-plans > form > h2.mt-5 { @extend %bwrs-hide; } 99 | + 100 | +/* Hide Tax Info in Organization settings */ 101 | +app-org-account > div.secondary-header.border-0.mb-0:nth-child(3) { @extend %bwrs-hide; } 102 | +app-org-account > p { @extend %bwrs-hide; } 103 | +app-org-account > a.btn.btn-outline-secondary { @extend %bwrs-hide; } 104 | +/**** END Bitwarden_RS CHANGES ****/ 105 | + 106 | $primary: #3c8dbc; 107 | $primary-accent: #286090; 108 | $secondary: #ced4da; 109 | diff --git a/webpack.config.js b/webpack.config.js 110 | index aecb1860..44acdc1d 100644 111 | --- a/webpack.config.js 112 | +++ b/webpack.config.js 113 | @@ -170,6 +170,7 @@ const config = { 114 | }, 115 | minimizer: [ 116 | new TerserPlugin({ 117 | + sourceMap: true, 118 | terserOptions: { 119 | safari10: true, 120 | }, 121 | -------------------------------------------------------------------------------- /patches/legacy/v2.14.0.patch: -------------------------------------------------------------------------------- 1 | diff --git a/src/app/app.component.ts b/src/app/app.component.ts 2 | index 2c694d95..bba34865 100644 3 | --- a/src/app/app.component.ts 4 | +++ b/src/app/app.component.ts 5 | @@ -140,6 +140,10 @@ export class AppComponent implements OnDestroy, OnInit { 6 | } 7 | break; 8 | case 'showToast': 9 | + if (typeof message.text === "string" && (message.text.indexOf("this.subtle") != -1 || message.text.indexOf("importKey") != -1)) { 10 | + message.title="This browser requires HTTPS to use the web vault"; 11 | + message.text="Check the bitwarden_rs wiki for details on how to enable it"; 12 | + } 13 | this.showToast(message); 14 | break; 15 | case 'analyticsEventTrack': 16 | diff --git a/src/app/services/services.module.ts b/src/app/services/services.module.ts 17 | index c74261dd..f61ccefe 100644 18 | --- a/src/app/services/services.module.ts 19 | +++ b/src/app/services/services.module.ts 20 | @@ -127,22 +127,31 @@ const environmentService = new EnvironmentService(apiService, storageService, no 21 | const auditService = new AuditService(cryptoFunctionService, apiService); 22 | const eventLoggingService = new EventLoggingService(storageService, apiService, userService, cipherService); 23 | 24 | -const analytics = new Analytics(window, () => platformUtilsService.isDev() || platformUtilsService.isSelfHost(), 25 | +const analytics = new Analytics(window, () => platformUtilsService.isDev() || platformUtilsService.isSelfHost() || true, 26 | platformUtilsService, storageService, appIdService); 27 | containerService.attachToWindow(window); 28 | 29 | export function initFactory(): Function { 30 | + function getBaseUrl() { 31 | + // If the base URL is `https://bitwarden.example.com/base/path/`, 32 | + // `window.location.href` should have one of the following forms: 33 | + // 34 | + // - `https://bitwarden.example.com/base/path/` 35 | + // - `https://bitwarden.example.com/base/path/#/some/endpoint[?queryParam=...]` 36 | + // 37 | + // We want to get to just `https://bitwarden.example.com/base/path`. 38 | + let baseUrl = window.location.href; 39 | + baseUrl = baseUrl.replace(/#.*/, ''); // Strip off `#` and everything after. 40 | + baseUrl = baseUrl.replace(/\/+$/, ''); // Trim any trailing `/` chars. 41 | + return baseUrl; 42 | + } 43 | return async () => { 44 | await (storageService as HtmlStorageService).init(); 45 | - const isDev = platformUtilsService.isDev(); 46 | - if (!isDev && platformUtilsService.isSelfHost()) { 47 | - environmentService.baseUrl = window.location.origin; 48 | - } else { 49 | - environmentService.notificationsUrl = isDev ? 'http://localhost:61840' : 50 | - 'https://notifications.bitwarden.com'; // window.location.origin + '/notifications'; 51 | - } 52 | + const isDev = false; 53 | + environmentService.baseUrl = getBaseUrl(); 54 | + environmentService.notificationsUrl = environmentService.baseUrl + '/notifications'; 55 | apiService.setUrls({ 56 | - base: isDev ? null : window.location.origin, 57 | + base: isDev ? null : environmentService.baseUrl, 58 | api: isDev ? 'http://localhost:4000' : null, 59 | identity: isDev ? 'http://localhost:33656' : null, 60 | events: isDev ? 'http://localhost:46273' : null, 61 | diff --git a/src/app/settings/two-factor-u2f.component.ts b/src/app/settings/two-factor-u2f.component.ts 62 | index 5560c476..a9b954a8 100644 63 | --- a/src/app/settings/two-factor-u2f.component.ts 64 | +++ b/src/app/settings/two-factor-u2f.component.ts 65 | @@ -128,6 +128,7 @@ export class TwoFactorU2fComponent extends TwoFactorBaseComponent implements OnI 66 | (window as any).u2f.register(u2fChallenge.appId, [{ 67 | version: u2fChallenge.version, 68 | challenge: u2fChallenge.challenge, 69 | + attestation: 'direct', 70 | }], [], (data: any) => { 71 | this.ngZone.run(() => { 72 | this.u2fListening = false; 73 | diff --git a/src/scss/styles.scss b/src/scss/styles.scss 74 | index 80951953..5c784175 100644 75 | --- a/src/scss/styles.scss 76 | +++ b/src/scss/styles.scss 77 | @@ -1,5 +1,31 @@ 78 | @import "../css/webfonts.css"; 79 | 80 | +/**** START Bitwarden_RS CHANGES ****/ 81 | +/* This combines all selectors extending it into one */ 82 | +%bwrs-hide { display: none !important; } 83 | + 84 | +/* This allows searching for the combined style in the browsers dev-tools (look into the head tag) */ 85 | +#bwrs-hide, head { @extend %bwrs-hide; } 86 | + 87 | +/* Hide any link pointing to billing */ 88 | +a[href$="/settings/billing"] { @extend %bwrs-hide; } 89 | + 90 | +/* Hide any link pointing to subscriptions */ 91 | +a[href$="/settings/subscription"] { @extend %bwrs-hide; } 92 | + 93 | +/* Hide Two-Factor menu in Organization settings */ 94 | +app-org-settings a[href$="/settings/two-factor"] { @extend %bwrs-hide; } 95 | + 96 | +/* Hide organization plans */ 97 | +app-organization-plans > form > div.form-check { @extend %bwrs-hide; } 98 | +app-organization-plans > form > h2.mt-5 { @extend %bwrs-hide; } 99 | + 100 | +/* Hide Tax Info in Organization settings */ 101 | +app-org-account > div.secondary-header.border-0.mb-0:nth-child(3) { @extend %bwrs-hide; } 102 | +app-org-account > p { @extend %bwrs-hide; } 103 | +app-org-account > a.btn.btn-outline-secondary { @extend %bwrs-hide; } 104 | +/**** END Bitwarden_RS CHANGES ****/ 105 | + 106 | $primary: #175DDC; 107 | $primary-accent: #1252A3; 108 | $secondary: #ced4da; 109 | diff --git a/webpack.config.js b/webpack.config.js 110 | index aecb1860..44acdc1d 100644 111 | --- a/webpack.config.js 112 | +++ b/webpack.config.js 113 | @@ -170,6 +170,7 @@ const config = { 114 | }, 115 | minimizer: [ 116 | new TerserPlugin({ 117 | + sourceMap: true, 118 | terserOptions: { 119 | safari10: true, 120 | }, 121 | -------------------------------------------------------------------------------- /patches/legacy/v2.15.1.patch: -------------------------------------------------------------------------------- 1 | diff --git a/src/app/app.component.ts b/src/app/app.component.ts 2 | index 6807ec89..62dbe456 100644 3 | --- a/src/app/app.component.ts 4 | +++ b/src/app/app.component.ts 5 | @@ -140,6 +140,10 @@ export class AppComponent implements OnDestroy, OnInit { 6 | } 7 | break; 8 | case 'showToast': 9 | + if (typeof message.text === "string" && (message.text.indexOf("this.subtle") != -1 || message.text.indexOf("importKey") != -1)) { 10 | + message.title="This browser requires HTTPS to use the web vault"; 11 | + message.text="Check the bitwarden_rs wiki for details on how to enable it"; 12 | + } 13 | this.showToast(message); 14 | break; 15 | case 'analyticsEventTrack': 16 | diff --git a/src/app/services/services.module.ts b/src/app/services/services.module.ts 17 | index e64240ad..025fdef1 100644 18 | --- a/src/app/services/services.module.ts 19 | +++ b/src/app/services/services.module.ts 20 | @@ -127,24 +127,32 @@ const environmentService = new EnvironmentService(apiService, storageService, no 21 | const auditService = new AuditService(cryptoFunctionService, apiService); 22 | const eventLoggingService = new EventLoggingService(storageService, apiService, userService, cipherService); 23 | 24 | -const analytics = new Analytics(window, () => platformUtilsService.isDev() || platformUtilsService.isSelfHost(), 25 | +const analytics = new Analytics(window, () => platformUtilsService.isDev() || platformUtilsService.isSelfHost() || true, 26 | platformUtilsService, storageService, appIdService); 27 | containerService.attachToWindow(window); 28 | 29 | export function initFactory(): Function { 30 | + function getBaseUrl() { 31 | + // If the base URL is `https://bitwarden.example.com/base/path/`, 32 | + // `window.location.href` should have one of the following forms: 33 | + // 34 | + // - `https://bitwarden.example.com/base/path/` 35 | + // - `https://bitwarden.example.com/base/path/#/some/route[?queryParam=...]` 36 | + // 37 | + // We want to get to just `https://bitwarden.example.com/base/path`. 38 | + let baseUrl = window.location.href; 39 | + baseUrl = baseUrl.replace(/#.*/, ''); // Strip off `#` and everything after. 40 | + baseUrl = baseUrl.replace(/\/+$/, ''); // Trim any trailing `/` chars. 41 | + return baseUrl; 42 | + } 43 | return async () => { 44 | await (storageService as HtmlStorageService).init(); 45 | - const isDev = platformUtilsService.isDev(); 46 | - if (!isDev && platformUtilsService.isSelfHost()) { 47 | - environmentService.baseUrl = window.location.origin; 48 | - } else { 49 | - environmentService.notificationsUrl = isDev ? 'http://localhost:61840' : 50 | - 'https://notifications.bitwarden.com'; // window.location.origin + '/notifications'; 51 | - environmentService.enterpriseUrl = isDev ? 'http://localhost:61840' : 52 | - 'https://enterprise.bitwarden.com'; // window.location.origin + '/enterprise'; 53 | - } 54 | + const isDev = false; 55 | + environmentService.baseUrl = getBaseUrl(); 56 | + environmentService.notificationsUrl = environmentService.baseUrl + '/notifications'; 57 | + environmentService.enterpriseUrl = environmentService.baseUrl + '/enterprise'; 58 | apiService.setUrls({ 59 | - base: isDev ? null : window.location.origin, 60 | + base: isDev ? null : environmentService.baseUrl, 61 | api: isDev ? 'http://localhost:4000' : null, 62 | identity: isDev ? 'http://localhost:33656' : null, 63 | events: isDev ? 'http://localhost:46273' : null, 64 | diff --git a/src/app/settings/two-factor-u2f.component.ts b/src/app/settings/two-factor-u2f.component.ts 65 | index 5560c476..a9b954a8 100644 66 | --- a/src/app/settings/two-factor-u2f.component.ts 67 | +++ b/src/app/settings/two-factor-u2f.component.ts 68 | @@ -128,6 +128,7 @@ export class TwoFactorU2fComponent extends TwoFactorBaseComponent implements OnI 69 | (window as any).u2f.register(u2fChallenge.appId, [{ 70 | version: u2fChallenge.version, 71 | challenge: u2fChallenge.challenge, 72 | + attestation: 'direct', 73 | }], [], (data: any) => { 74 | this.ngZone.run(() => { 75 | this.u2fListening = false; 76 | diff --git a/src/scss/styles.scss b/src/scss/styles.scss 77 | index 676e275f..ba9888fc 100644 78 | --- a/src/scss/styles.scss 79 | +++ b/src/scss/styles.scss 80 | @@ -1,5 +1,31 @@ 81 | @import "../css/webfonts.css"; 82 | 83 | +/**** START Bitwarden_RS CHANGES ****/ 84 | +/* This combines all selectors extending it into one */ 85 | +%bwrs-hide { display: none !important; } 86 | + 87 | +/* This allows searching for the combined style in the browsers dev-tools (look into the head tag) */ 88 | +#bwrs-hide, head { @extend %bwrs-hide; } 89 | + 90 | +/* Hide any link pointing to billing */ 91 | +a[href$="/settings/billing"] { @extend %bwrs-hide; } 92 | + 93 | +/* Hide any link pointing to subscriptions */ 94 | +a[href$="/settings/subscription"] { @extend %bwrs-hide; } 95 | + 96 | +/* Hide Two-Factor menu in Organization settings */ 97 | +app-org-settings a[href$="/settings/two-factor"] { @extend %bwrs-hide; } 98 | + 99 | +/* Hide organization plans */ 100 | +app-organization-plans > form > div.form-check { @extend %bwrs-hide; } 101 | +app-organization-plans > form > h2.mt-5 { @extend %bwrs-hide; } 102 | + 103 | +/* Hide Tax Info in Organization settings */ 104 | +app-org-account > div.secondary-header.border-0.mb-0:nth-child(3) { @extend %bwrs-hide; } 105 | +app-org-account > p { @extend %bwrs-hide; } 106 | +app-org-account > a.btn.btn-outline-secondary { @extend %bwrs-hide; } 107 | +/**** END Bitwarden_RS CHANGES ****/ 108 | + 109 | $primary: #175DDC; 110 | $primary-accent: #1252A3; 111 | $secondary: #ced4da; 112 | diff --git a/webpack.config.js b/webpack.config.js 113 | index 3391d5ff..c4e2c0b5 100644 114 | --- a/webpack.config.js 115 | +++ b/webpack.config.js 116 | @@ -170,6 +170,7 @@ const config = { 117 | }, 118 | minimizer: [ 119 | new TerserPlugin({ 120 | + sourceMap: true, 121 | terserOptions: { 122 | safari10: true, 123 | }, 124 | -------------------------------------------------------------------------------- /patches/legacy/v2.16.0.patch: -------------------------------------------------------------------------------- 1 | diff --git a/src/app/app.component.ts b/src/app/app.component.ts 2 | index fabd9294..2f0d88ad 100644 3 | --- a/src/app/app.component.ts 4 | +++ b/src/app/app.component.ts 5 | @@ -140,6 +140,10 @@ export class AppComponent implements OnDestroy, OnInit { 6 | } 7 | break; 8 | case 'showToast': 9 | + if (typeof message.text === "string" && (message.text.indexOf("this.subtle") != -1 || message.text.indexOf("importKey") != -1)) { 10 | + message.title="This browser requires HTTPS to use the web vault"; 11 | + message.text="Check the bitwarden_rs wiki for details on how to enable it"; 12 | + } 13 | this.showToast(message); 14 | break; 15 | case 'analyticsEventTrack': 16 | diff --git a/src/app/services/services.module.ts b/src/app/services/services.module.ts 17 | index dc4290f1..e3f74602 100644 18 | --- a/src/app/services/services.module.ts 19 | +++ b/src/app/services/services.module.ts 20 | @@ -127,24 +127,32 @@ const environmentService = new EnvironmentService(apiService, storageService, no 21 | const auditService = new AuditService(cryptoFunctionService, apiService); 22 | const eventLoggingService = new EventLoggingService(storageService, apiService, userService, cipherService); 23 | 24 | -const analytics = new Analytics(window, () => platformUtilsService.isDev() || platformUtilsService.isSelfHost(), 25 | +const analytics = new Analytics(window, () => platformUtilsService.isDev() || platformUtilsService.isSelfHost() || true, 26 | platformUtilsService, storageService, appIdService); 27 | containerService.attachToWindow(window); 28 | 29 | export function initFactory(): Function { 30 | + function getBaseUrl() { 31 | + // If the base URL is `https://bitwarden.example.com/base/path/`, 32 | + // `window.location.href` should have one of the following forms: 33 | + // 34 | + // - `https://bitwarden.example.com/base/path/` 35 | + // - `https://bitwarden.example.com/base/path/#/some/route[?queryParam=...]` 36 | + // 37 | + // We want to get to just `https://bitwarden.example.com/base/path`. 38 | + let baseUrl = window.location.href; 39 | + baseUrl = baseUrl.replace(/#.*/, ''); // Strip off `#` and everything after. 40 | + baseUrl = baseUrl.replace(/\/+$/, ''); // Trim any trailing `/` chars. 41 | + return baseUrl; 42 | + } 43 | return async () => { 44 | await (storageService as HtmlStorageService).init(); 45 | - const isDev = platformUtilsService.isDev(); 46 | - if (!isDev && platformUtilsService.isSelfHost()) { 47 | - environmentService.baseUrl = window.location.origin; 48 | - } else { 49 | - environmentService.notificationsUrl = isDev ? 'http://localhost:61840' : 50 | - 'https://notifications.bitwarden.com'; // window.location.origin + '/notifications'; 51 | - environmentService.enterpriseUrl = isDev ? 'http://localhost:52313' : 52 | - 'https://portal.bitwarden.com'; // window.location.origin + '/portal'; 53 | - } 54 | + const isDev = false; 55 | + environmentService.baseUrl = getBaseUrl(); 56 | + environmentService.notificationsUrl = environmentService.baseUrl + '/notifications'; 57 | + environmentService.enterpriseUrl = environmentService.baseUrl + '/portal'; 58 | apiService.setUrls({ 59 | - base: isDev ? null : window.location.origin, 60 | + base: isDev ? null : environmentService.baseUrl, 61 | api: isDev ? 'http://localhost:4000' : null, 62 | identity: isDev ? 'http://localhost:33656' : null, 63 | events: isDev ? 'http://localhost:46273' : null, 64 | diff --git a/src/app/settings/two-factor-u2f.component.ts b/src/app/settings/two-factor-u2f.component.ts 65 | index 5560c476..a9b954a8 100644 66 | --- a/src/app/settings/two-factor-u2f.component.ts 67 | +++ b/src/app/settings/two-factor-u2f.component.ts 68 | @@ -128,6 +128,7 @@ export class TwoFactorU2fComponent extends TwoFactorBaseComponent implements OnI 69 | (window as any).u2f.register(u2fChallenge.appId, [{ 70 | version: u2fChallenge.version, 71 | challenge: u2fChallenge.challenge, 72 | + attestation: 'direct', 73 | }], [], (data: any) => { 74 | this.ngZone.run(() => { 75 | this.u2fListening = false; 76 | diff --git a/src/scss/styles.scss b/src/scss/styles.scss 77 | index 676e275f..ab3304af 100644 78 | --- a/src/scss/styles.scss 79 | +++ b/src/scss/styles.scss 80 | @@ -1,5 +1,34 @@ 81 | @import "../css/webfonts.css"; 82 | 83 | +/**** START Bitwarden_RS CHANGES ****/ 84 | +/* This combines all selectors extending it into one */ 85 | +%bwrs-hide { display: none !important; } 86 | + 87 | +/* This allows searching for the combined style in the browsers dev-tools (look into the head tag) */ 88 | +#bwrs-hide, head { @extend %bwrs-hide; } 89 | + 90 | +/* Hide any link pointing to billing */ 91 | +a[href$="/settings/billing"] { @extend %bwrs-hide; } 92 | + 93 | +/* Hide any link pointing to subscriptions */ 94 | +a[href$="/settings/subscription"] { @extend %bwrs-hide; } 95 | + 96 | +/* Hide the `Enterprise Single Sign-On` button on the login page */ 97 | +a[href$="/sso"] { @extend %bwrs-hide; } 98 | + 99 | +/* Hide Two-Factor menu in Organization settings */ 100 | +app-org-settings a[href$="/settings/two-factor"] { @extend %bwrs-hide; } 101 | + 102 | +/* Hide organization plans */ 103 | +app-organization-plans > form > div.form-check { @extend %bwrs-hide; } 104 | +app-organization-plans > form > h2.mt-5 { @extend %bwrs-hide; } 105 | + 106 | +/* Hide Tax Info in Organization settings */ 107 | +app-org-account > div.secondary-header.border-0.mb-0:nth-child(3) { @extend %bwrs-hide; } 108 | +app-org-account > p { @extend %bwrs-hide; } 109 | +app-org-account > a.btn.btn-outline-secondary { @extend %bwrs-hide; } 110 | +/**** END Bitwarden_RS CHANGES ****/ 111 | + 112 | $primary: #175DDC; 113 | $primary-accent: #1252A3; 114 | $secondary: #ced4da; 115 | diff --git a/webpack.config.js b/webpack.config.js 116 | index 5f00785a..a3cd89bd 100644 117 | --- a/webpack.config.js 118 | +++ b/webpack.config.js 119 | @@ -176,6 +176,7 @@ const config = { 120 | }, 121 | minimizer: [ 122 | new TerserPlugin({ 123 | + sourceMap: true, 124 | terserOptions: { 125 | safari10: true, 126 | }, 127 | -------------------------------------------------------------------------------- /patches/legacy/v2.16.1.patch: -------------------------------------------------------------------------------- 1 | diff --git a/src/app/app.component.ts b/src/app/app.component.ts 2 | index fabd9294..2f0d88ad 100644 3 | --- a/src/app/app.component.ts 4 | +++ b/src/app/app.component.ts 5 | @@ -140,6 +140,10 @@ export class AppComponent implements OnDestroy, OnInit { 6 | } 7 | break; 8 | case 'showToast': 9 | + if (typeof message.text === "string" && (message.text.indexOf("this.subtle") != -1 || message.text.indexOf("importKey") != -1)) { 10 | + message.title="This browser requires HTTPS to use the web vault"; 11 | + message.text="Check the bitwarden_rs wiki for details on how to enable it"; 12 | + } 13 | this.showToast(message); 14 | break; 15 | case 'analyticsEventTrack': 16 | diff --git a/src/app/services/services.module.ts b/src/app/services/services.module.ts 17 | index d5892f0f..50547d1b 100644 18 | --- a/src/app/services/services.module.ts 19 | +++ b/src/app/services/services.module.ts 20 | @@ -127,24 +127,32 @@ const environmentService = new EnvironmentService(apiService, storageService, no 21 | const auditService = new AuditService(cryptoFunctionService, apiService); 22 | const eventLoggingService = new EventLoggingService(storageService, apiService, userService, cipherService); 23 | 24 | -const analytics = new Analytics(window, () => platformUtilsService.isDev() || platformUtilsService.isSelfHost(), 25 | +const analytics = new Analytics(window, () => platformUtilsService.isDev() || platformUtilsService.isSelfHost() || true, 26 | platformUtilsService, storageService, appIdService); 27 | containerService.attachToWindow(window); 28 | 29 | export function initFactory(): Function { 30 | + function getBaseUrl() { 31 | + // If the base URL is `https://bitwarden.example.com/base/path/`, 32 | + // `window.location.href` should have one of the following forms: 33 | + // 34 | + // - `https://bitwarden.example.com/base/path/` 35 | + // - `https://bitwarden.example.com/base/path/#/some/route[?queryParam=...]` 36 | + // 37 | + // We want to get to just `https://bitwarden.example.com/base/path`. 38 | + let baseUrl = window.location.href; 39 | + baseUrl = baseUrl.replace(/#.*/, ''); // Strip off `#` and everything after. 40 | + baseUrl = baseUrl.replace(/\/+$/, ''); // Trim any trailing `/` chars. 41 | + return baseUrl; 42 | + } 43 | return async () => { 44 | await (storageService as HtmlStorageService).init(); 45 | - const isDev = platformUtilsService.isDev(); 46 | - if (!isDev && platformUtilsService.isSelfHost()) { 47 | - environmentService.baseUrl = window.location.origin; 48 | - } else { 49 | - environmentService.notificationsUrl = isDev ? 'http://localhost:61840' : 50 | - 'https://notifications.bitwarden.com'; // window.location.origin + '/notifications'; 51 | - environmentService.enterpriseUrl = isDev ? 'http://localhost:52313' : 52 | - 'https://portal.bitwarden.com'; // window.location.origin + '/portal'; 53 | - } 54 | + const isDev = false; 55 | + environmentService.baseUrl = getBaseUrl(); 56 | + environmentService.notificationsUrl = environmentService.baseUrl + '/notifications'; 57 | + environmentService.enterpriseUrl = environmentService.baseUrl + '/portal'; 58 | apiService.setUrls({ 59 | - base: isDev ? null : window.location.origin, 60 | + base: isDev ? null : environmentService.baseUrl, 61 | api: isDev ? 'http://localhost:4000' : null, 62 | identity: isDev ? 'http://localhost:33656' : null, 63 | events: isDev ? 'http://localhost:46273' : null, 64 | diff --git a/src/app/settings/two-factor-u2f.component.ts b/src/app/settings/two-factor-u2f.component.ts 65 | index 5560c476..a9b954a8 100644 66 | --- a/src/app/settings/two-factor-u2f.component.ts 67 | +++ b/src/app/settings/two-factor-u2f.component.ts 68 | @@ -128,6 +128,7 @@ export class TwoFactorU2fComponent extends TwoFactorBaseComponent implements OnI 69 | (window as any).u2f.register(u2fChallenge.appId, [{ 70 | version: u2fChallenge.version, 71 | challenge: u2fChallenge.challenge, 72 | + attestation: 'direct', 73 | }], [], (data: any) => { 74 | this.ngZone.run(() => { 75 | this.u2fListening = false; 76 | diff --git a/src/scss/styles.scss b/src/scss/styles.scss 77 | index 676e275f..7aec40ad 100644 78 | --- a/src/scss/styles.scss 79 | +++ b/src/scss/styles.scss 80 | @@ -1,5 +1,34 @@ 81 | @import "../css/webfonts.css"; 82 | 83 | +/**** START Bitwarden_RS CHANGES ****/ 84 | +/* This combines all selectors extending it into one */ 85 | +%bwrs-hide { display: none !important; } 86 | + 87 | +/* This allows searching for the combined style in the browsers dev-tools (look into the head tag) */ 88 | +#bwrs-hide, head { @extend %bwrs-hide; } 89 | + 90 | +/* Hide any link pointing to billing */ 91 | +a[href$="/settings/billing"] { @extend %bwrs-hide; } 92 | + 93 | +/* Hide any link pointing to subscriptions */ 94 | +a[href$="/settings/subscription"] { @extend %bwrs-hide; } 95 | + 96 | +/* Hide the `Enterprise Single Sign-On` button on the login page */ 97 | +a[href$="/sso"] { @extend %bwrs-hide; } 98 | + 99 | +/* Hide Two-Factor menu in Organization settings */ 100 | +app-org-settings a[href$="/settings/two-factor"] { @extend %bwrs-hide; } 101 | + 102 | +/* Hide organization plans */ 103 | +app-organization-plans > form > div.form-check { @extend %bwrs-hide; } 104 | +app-organization-plans > form > h2.mt-5 { @extend %bwrs-hide; } 105 | + 106 | +/* Hide Tax Info and Form in Organization settings */ 107 | +app-org-account > div.secondary-header:nth-child(3) { @extend %bwrs-hide; } 108 | +app-org-account > div.secondary-header:nth-child(3) + p { @extend %bwrs-hide; } 109 | +app-org-account > div.secondary-header:nth-child(3) + p + form { @extend %bwrs-hide; } 110 | +/**** END Bitwarden_RS CHANGES ****/ 111 | + 112 | $primary: #175DDC; 113 | $primary-accent: #1252A3; 114 | $secondary: #ced4da; 115 | diff --git a/webpack.config.js b/webpack.config.js 116 | index 5f00785a..a3cd89bd 100644 117 | --- a/webpack.config.js 118 | +++ b/webpack.config.js 119 | @@ -176,6 +176,7 @@ const config = { 120 | }, 121 | minimizer: [ 122 | new TerserPlugin({ 123 | + sourceMap: true, 124 | terserOptions: { 125 | safari10: true, 126 | }, 127 | -------------------------------------------------------------------------------- /patches/legacy/v2.17.1.patch: -------------------------------------------------------------------------------- 1 | diff --git a/src/app/app.component.ts b/src/app/app.component.ts 2 | index 51853633..c9b3d48a 100644 3 | --- a/src/app/app.component.ts 4 | +++ b/src/app/app.component.ts 5 | @@ -140,6 +140,10 @@ export class AppComponent implements OnDestroy, OnInit { 6 | } 7 | break; 8 | case 'showToast': 9 | + if (typeof message.text === "string" && (message.text.indexOf("this.subtle") != -1 || message.text.indexOf("importKey") != -1)) { 10 | + message.title="This browser requires HTTPS to use the web vault"; 11 | + message.text="Check the bitwarden_rs wiki for details on how to enable it"; 12 | + } 13 | this.showToast(message); 14 | break; 15 | case 'analyticsEventTrack': 16 | diff --git a/src/app/services/services.module.ts b/src/app/services/services.module.ts 17 | index 092af73a..95eb8f49 100644 18 | --- a/src/app/services/services.module.ts 19 | +++ b/src/app/services/services.module.ts 20 | @@ -131,24 +131,32 @@ const environmentService = new EnvironmentService(apiService, storageService, no 21 | const auditService = new AuditService(cryptoFunctionService, apiService); 22 | const eventLoggingService = new EventLoggingService(storageService, apiService, userService, cipherService); 23 | 24 | -const analytics = new Analytics(window, () => platformUtilsService.isDev() || platformUtilsService.isSelfHost(), 25 | +const analytics = new Analytics(window, () => platformUtilsService.isDev() || platformUtilsService.isSelfHost() || true, 26 | platformUtilsService, storageService, appIdService); 27 | containerService.attachToWindow(window); 28 | 29 | export function initFactory(): Function { 30 | + function getBaseUrl() { 31 | + // If the base URL is `https://bitwarden.example.com/base/path/`, 32 | + // `window.location.href` should have one of the following forms: 33 | + // 34 | + // - `https://bitwarden.example.com/base/path/` 35 | + // - `https://bitwarden.example.com/base/path/#/some/route[?queryParam=...]` 36 | + // 37 | + // We want to get to just `https://bitwarden.example.com/base/path`. 38 | + let baseUrl = window.location.href; 39 | + baseUrl = baseUrl.replace(/#.*/, ''); // Strip off `#` and everything after. 40 | + baseUrl = baseUrl.replace(/\/+$/, ''); // Trim any trailing `/` chars. 41 | + return baseUrl; 42 | + } 43 | return async () => { 44 | await (storageService as HtmlStorageService).init(); 45 | - const isDev = platformUtilsService.isDev(); 46 | - if (!isDev && platformUtilsService.isSelfHost()) { 47 | - environmentService.baseUrl = window.location.origin; 48 | - } else { 49 | - environmentService.notificationsUrl = isDev ? 'http://localhost:61840' : 50 | - 'https://notifications.bitwarden.com'; // window.location.origin + '/notifications'; 51 | - environmentService.enterpriseUrl = isDev ? 'http://localhost:52313' : 52 | - 'https://portal.bitwarden.com'; // window.location.origin + '/portal'; 53 | - } 54 | + const isDev = false; 55 | + environmentService.baseUrl = getBaseUrl(); 56 | + environmentService.notificationsUrl = environmentService.baseUrl + '/notifications'; 57 | + environmentService.enterpriseUrl = environmentService.baseUrl + '/portal'; 58 | apiService.setUrls({ 59 | - base: isDev ? null : window.location.origin, 60 | + base: isDev ? null : environmentService.baseUrl, 61 | api: isDev ? 'http://localhost:4000' : null, 62 | identity: isDev ? 'http://localhost:33656' : null, 63 | events: isDev ? 'http://localhost:46273' : null, 64 | diff --git a/src/app/settings/two-factor-u2f.component.ts b/src/app/settings/two-factor-u2f.component.ts 65 | index 5560c476..a9b954a8 100644 66 | --- a/src/app/settings/two-factor-u2f.component.ts 67 | +++ b/src/app/settings/two-factor-u2f.component.ts 68 | @@ -128,6 +128,7 @@ export class TwoFactorU2fComponent extends TwoFactorBaseComponent implements OnI 69 | (window as any).u2f.register(u2fChallenge.appId, [{ 70 | version: u2fChallenge.version, 71 | challenge: u2fChallenge.challenge, 72 | + attestation: 'direct', 73 | }], [], (data: any) => { 74 | this.ngZone.run(() => { 75 | this.u2fListening = false; 76 | diff --git a/src/scss/styles.scss b/src/scss/styles.scss 77 | index 55b3c92c..91279fef 100644 78 | --- a/src/scss/styles.scss 79 | +++ b/src/scss/styles.scss 80 | @@ -1,5 +1,42 @@ 81 | @import "../css/webfonts.css"; 82 | 83 | +/**** START Bitwarden_RS CHANGES ****/ 84 | +/* This combines all selectors extending it into one */ 85 | +%bwrs-hide { display: none !important; } 86 | + 87 | +/* This allows searching for the combined style in the browsers dev-tools (look into the head tag) */ 88 | +#bwrs-hide, head { @extend %bwrs-hide; } 89 | + 90 | +/* Hide any link pointing to billing */ 91 | +a[href$="/settings/billing"] { @extend %bwrs-hide; } 92 | + 93 | +/* Hide any link pointing to subscriptions */ 94 | +a[href$="/settings/subscription"] { @extend %bwrs-hide; } 95 | + 96 | +/* Hide the `Enterprise Single Sign-On` button on the login page */ 97 | +a[href$="/sso"] { @extend %bwrs-hide; } 98 | + 99 | +/* Hide Two-Factor menu in Organization settings */ 100 | +app-org-settings a[href$="/settings/two-factor"] { @extend %bwrs-hide; } 101 | + 102 | +/* Hide organization plans */ 103 | +app-organization-plans > form > div.form-check { @extend %bwrs-hide; } 104 | +app-organization-plans > form > h2.mt-5 { @extend %bwrs-hide; } 105 | + 106 | +/* Hide the `API Key` section under `My Account` */ 107 | +app-account > div:nth-child(9), 108 | +app-account > p, 109 | +app-account > button:nth-child(11), 110 | +app-account > button:nth-child(12) { 111 | + @extend %bwrs-hide; 112 | +} 113 | + 114 | +/* Hide Tax Info and Form in Organization settings */ 115 | +app-org-account > div.secondary-header:nth-child(3) { @extend %bwrs-hide; } 116 | +app-org-account > div.secondary-header:nth-child(3) + p { @extend %bwrs-hide; } 117 | +app-org-account > div.secondary-header:nth-child(3) + p + form { @extend %bwrs-hide; } 118 | +/**** END Bitwarden_RS CHANGES ****/ 119 | + 120 | $primary: #175DDC; 121 | $primary-accent: #1252A3; 122 | $secondary: #ced4da; 123 | diff --git a/webpack.config.js b/webpack.config.js 124 | index 6b01c93d..809b396a 100644 125 | --- a/webpack.config.js 126 | +++ b/webpack.config.js 127 | @@ -176,6 +176,7 @@ const config = { 128 | }, 129 | minimizer: [ 130 | new TerserPlugin({ 131 | + sourceMap: true, 132 | terserOptions: { 133 | safari10: true, 134 | }, 135 | -------------------------------------------------------------------------------- /patches/legacy/v2.18.0.patch: -------------------------------------------------------------------------------- 1 | diff --git a/src/app/app.component.ts b/src/app/app.component.ts 2 | index 51853633..c9b3d48a 100644 3 | --- a/src/app/app.component.ts 4 | +++ b/src/app/app.component.ts 5 | @@ -140,6 +140,10 @@ export class AppComponent implements OnDestroy, OnInit { 6 | } 7 | break; 8 | case 'showToast': 9 | + if (typeof message.text === "string" && (message.text.indexOf("this.subtle") != -1 || message.text.indexOf("importKey") != -1)) { 10 | + message.title="This browser requires HTTPS to use the web vault"; 11 | + message.text="Check the bitwarden_rs wiki for details on how to enable it"; 12 | + } 13 | this.showToast(message); 14 | break; 15 | case 'analyticsEventTrack': 16 | diff --git a/src/app/services/services.module.ts b/src/app/services/services.module.ts 17 | index 3e4d8dfa..f5bf60e4 100644 18 | --- a/src/app/services/services.module.ts 19 | +++ b/src/app/services/services.module.ts 20 | @@ -135,24 +135,32 @@ const environmentService = new EnvironmentService(apiService, storageService, no 21 | const auditService = new AuditService(cryptoFunctionService, apiService); 22 | const eventLoggingService = new EventLoggingService(storageService, apiService, userService, cipherService); 23 | 24 | -const analytics = new Analytics(window, () => platformUtilsService.isDev() || platformUtilsService.isSelfHost(), 25 | +const analytics = new Analytics(window, () => platformUtilsService.isDev() || platformUtilsService.isSelfHost() || true, 26 | platformUtilsService, storageService, appIdService); 27 | containerService.attachToWindow(window); 28 | 29 | export function initFactory(): Function { 30 | + function getBaseUrl() { 31 | + // If the base URL is `https://bitwarden.example.com/base/path/`, 32 | + // `window.location.href` should have one of the following forms: 33 | + // 34 | + // - `https://bitwarden.example.com/base/path/` 35 | + // - `https://bitwarden.example.com/base/path/#/some/route[?queryParam=...]` 36 | + // 37 | + // We want to get to just `https://bitwarden.example.com/base/path`. 38 | + let baseUrl = window.location.href; 39 | + baseUrl = baseUrl.replace(/#.*/, ''); // Strip off `#` and everything after. 40 | + baseUrl = baseUrl.replace(/\/+$/, ''); // Trim any trailing `/` chars. 41 | + return baseUrl; 42 | + } 43 | return async () => { 44 | await (storageService as HtmlStorageService).init(); 45 | - const isDev = platformUtilsService.isDev(); 46 | - if (!isDev && platformUtilsService.isSelfHost()) { 47 | - environmentService.baseUrl = window.location.origin; 48 | - } else { 49 | - environmentService.notificationsUrl = isDev ? 'http://localhost:61840' : 50 | - 'https://notifications.bitwarden.com'; // window.location.origin + '/notifications'; 51 | - environmentService.enterpriseUrl = isDev ? 'http://localhost:52313' : 52 | - 'https://portal.bitwarden.com'; // window.location.origin + '/portal'; 53 | - } 54 | + const isDev = false; 55 | + environmentService.baseUrl = getBaseUrl(); 56 | + environmentService.notificationsUrl = environmentService.baseUrl + '/notifications'; 57 | + environmentService.enterpriseUrl = environmentService.baseUrl + '/portal'; 58 | apiService.setUrls({ 59 | - base: isDev ? null : window.location.origin, 60 | + base: isDev ? null : environmentService.baseUrl, 61 | api: isDev ? 'http://localhost:4000' : null, 62 | identity: isDev ? 'http://localhost:33656' : null, 63 | events: isDev ? 'http://localhost:46273' : null, 64 | diff --git a/src/app/settings/two-factor-u2f.component.ts b/src/app/settings/two-factor-u2f.component.ts 65 | index 5560c476..a9b954a8 100644 66 | --- a/src/app/settings/two-factor-u2f.component.ts 67 | +++ b/src/app/settings/two-factor-u2f.component.ts 68 | @@ -128,6 +128,7 @@ export class TwoFactorU2fComponent extends TwoFactorBaseComponent implements OnI 69 | (window as any).u2f.register(u2fChallenge.appId, [{ 70 | version: u2fChallenge.version, 71 | challenge: u2fChallenge.challenge, 72 | + attestation: 'direct', 73 | }], [], (data: any) => { 74 | this.ngZone.run(() => { 75 | this.u2fListening = false; 76 | diff --git a/src/scss/styles.scss b/src/scss/styles.scss 77 | index 55b3c92c..a716bfd6 100644 78 | --- a/src/scss/styles.scss 79 | +++ b/src/scss/styles.scss 80 | @@ -1,5 +1,50 @@ 81 | @import "../css/webfonts.css"; 82 | 83 | +/**** START Bitwarden_RS CHANGES ****/ 84 | +/* This combines all selectors extending it into one */ 85 | +%bwrs-hide { display: none !important; } 86 | + 87 | +/* This allows searching for the combined style in the browsers dev-tools (look into the head tag) */ 88 | +#bwrs-hide, head { @extend %bwrs-hide; } 89 | + 90 | +/* Hide any link pointing to billing */ 91 | +a[href$="/settings/billing"] { @extend %bwrs-hide; } 92 | + 93 | +/* Hide any link pointing to subscriptions */ 94 | +a[href$="/settings/subscription"] { @extend %bwrs-hide; } 95 | + 96 | +/* Hide any link pointing to emergency access */ 97 | +a[href$="/settings/emergency-access"] { @extend %bwrs-hide; } 98 | + 99 | +/* Hide the `Enterprise Single Sign-On` button on the login page */ 100 | +a[href$="/sso"] { @extend %bwrs-hide; } 101 | + 102 | +/* Hide Two-Factor menu in Organization settings */ 103 | +app-org-settings a[href$="/settings/two-factor"] { @extend %bwrs-hide; } 104 | + 105 | +/* Hide organization plans */ 106 | +app-organization-plans > form > div.form-check { @extend %bwrs-hide; } 107 | +app-organization-plans > form > h2.mt-5 { @extend %bwrs-hide; } 108 | + 109 | +/* Hide the `API Key` section under `My Account` */ 110 | +app-account > div:nth-child(9), 111 | +app-account > p, 112 | +app-account > button:nth-child(11), 113 | +app-account > button:nth-child(12) { 114 | + @extend %bwrs-hide; 115 | +} 116 | + 117 | +/* Hide the radio button and label for the `Custom` org user type */ 118 | +#userTypeCustom, label[for^=userTypeCustom] { 119 | + @extend %bwrs-hide; 120 | +} 121 | + 122 | +/* Hide Tax Info and Form in Organization settings */ 123 | +app-org-account > div.secondary-header:nth-child(3) { @extend %bwrs-hide; } 124 | +app-org-account > div.secondary-header:nth-child(3) + p { @extend %bwrs-hide; } 125 | +app-org-account > div.secondary-header:nth-child(3) + p + form { @extend %bwrs-hide; } 126 | +/**** END Bitwarden_RS CHANGES ****/ 127 | + 128 | $primary: #175DDC; 129 | $primary-accent: #1252A3; 130 | $secondary: #ced4da; 131 | diff --git a/webpack.config.js b/webpack.config.js 132 | index 6b01c93d..809b396a 100644 133 | --- a/webpack.config.js 134 | +++ b/webpack.config.js 135 | @@ -176,6 +176,7 @@ const config = { 136 | }, 137 | minimizer: [ 138 | new TerserPlugin({ 139 | + sourceMap: true, 140 | terserOptions: { 141 | safari10: true, 142 | }, 143 | -------------------------------------------------------------------------------- /patches/legacy/v2.18.1.patch: -------------------------------------------------------------------------------- 1 | Submodule jslib contains modified content 2 | diff --git a/jslib/src/angular/components/register.component.ts b/jslib/src/angular/components/register.component.ts 3 | index 6149f83..005d528 100644 4 | --- a/jslib/src/angular/components/register.component.ts 5 | +++ b/jslib/src/angular/components/register.component.ts 6 | @@ -69,6 +69,12 @@ export class RegisterComponent { 7 | } 8 | 9 | async submit() { 10 | + if (typeof crypto.subtle === 'undefined') { 11 | + this.platformUtilsService.showToast('error', "This browser requires HTTPS to use the web vault", 12 | + "Check the bitwarden_rs wiki for details on how to enable it"); 13 | + return; 14 | + } 15 | + 16 | if (!this.acceptPolicies && this.showTerms) { 17 | this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), 18 | this.i18nService.t('acceptPoliciesError')); 19 | diff --git a/src/app/app.component.ts b/src/app/app.component.ts 20 | index 51853633..f589e498 100644 21 | --- a/src/app/app.component.ts 22 | +++ b/src/app/app.component.ts 23 | @@ -140,6 +140,10 @@ export class AppComponent implements OnDestroy, OnInit { 24 | } 25 | break; 26 | case 'showToast': 27 | + if (typeof message.text === "string" && typeof crypto.subtle === 'undefined') { 28 | + message.title="This browser requires HTTPS to use the web vault"; 29 | + message.text="Check the bitwarden_rs wiki for details on how to enable it"; 30 | + } 31 | this.showToast(message); 32 | break; 33 | case 'analyticsEventTrack': 34 | diff --git a/src/app/services/services.module.ts b/src/app/services/services.module.ts 35 | index 3e4d8dfa..f5bf60e4 100644 36 | --- a/src/app/services/services.module.ts 37 | +++ b/src/app/services/services.module.ts 38 | @@ -135,24 +135,32 @@ const environmentService = new EnvironmentService(apiService, storageService, no 39 | const auditService = new AuditService(cryptoFunctionService, apiService); 40 | const eventLoggingService = new EventLoggingService(storageService, apiService, userService, cipherService); 41 | 42 | -const analytics = new Analytics(window, () => platformUtilsService.isDev() || platformUtilsService.isSelfHost(), 43 | +const analytics = new Analytics(window, () => platformUtilsService.isDev() || platformUtilsService.isSelfHost() || true, 44 | platformUtilsService, storageService, appIdService); 45 | containerService.attachToWindow(window); 46 | 47 | export function initFactory(): Function { 48 | + function getBaseUrl() { 49 | + // If the base URL is `https://bitwarden.example.com/base/path/`, 50 | + // `window.location.href` should have one of the following forms: 51 | + // 52 | + // - `https://bitwarden.example.com/base/path/` 53 | + // - `https://bitwarden.example.com/base/path/#/some/route[?queryParam=...]` 54 | + // 55 | + // We want to get to just `https://bitwarden.example.com/base/path`. 56 | + let baseUrl = window.location.href; 57 | + baseUrl = baseUrl.replace(/#.*/, ''); // Strip off `#` and everything after. 58 | + baseUrl = baseUrl.replace(/\/+$/, ''); // Trim any trailing `/` chars. 59 | + return baseUrl; 60 | + } 61 | return async () => { 62 | await (storageService as HtmlStorageService).init(); 63 | - const isDev = platformUtilsService.isDev(); 64 | - if (!isDev && platformUtilsService.isSelfHost()) { 65 | - environmentService.baseUrl = window.location.origin; 66 | - } else { 67 | - environmentService.notificationsUrl = isDev ? 'http://localhost:61840' : 68 | - 'https://notifications.bitwarden.com'; // window.location.origin + '/notifications'; 69 | - environmentService.enterpriseUrl = isDev ? 'http://localhost:52313' : 70 | - 'https://portal.bitwarden.com'; // window.location.origin + '/portal'; 71 | - } 72 | + const isDev = false; 73 | + environmentService.baseUrl = getBaseUrl(); 74 | + environmentService.notificationsUrl = environmentService.baseUrl + '/notifications'; 75 | + environmentService.enterpriseUrl = environmentService.baseUrl + '/portal'; 76 | apiService.setUrls({ 77 | - base: isDev ? null : window.location.origin, 78 | + base: isDev ? null : environmentService.baseUrl, 79 | api: isDev ? 'http://localhost:4000' : null, 80 | identity: isDev ? 'http://localhost:33656' : null, 81 | events: isDev ? 'http://localhost:46273' : null, 82 | diff --git a/src/app/settings/two-factor-u2f.component.ts b/src/app/settings/two-factor-u2f.component.ts 83 | index 5560c476..a9b954a8 100644 84 | --- a/src/app/settings/two-factor-u2f.component.ts 85 | +++ b/src/app/settings/two-factor-u2f.component.ts 86 | @@ -128,6 +128,7 @@ export class TwoFactorU2fComponent extends TwoFactorBaseComponent implements OnI 87 | (window as any).u2f.register(u2fChallenge.appId, [{ 88 | version: u2fChallenge.version, 89 | challenge: u2fChallenge.challenge, 90 | + attestation: 'direct', 91 | }], [], (data: any) => { 92 | this.ngZone.run(() => { 93 | this.u2fListening = false; 94 | diff --git a/src/scss/styles.scss b/src/scss/styles.scss 95 | index 55b3c92c..c48e2baf 100644 96 | --- a/src/scss/styles.scss 97 | +++ b/src/scss/styles.scss 98 | @@ -1,5 +1,56 @@ 99 | @import "../css/webfonts.css"; 100 | 101 | +/**** START Bitwarden_RS CHANGES ****/ 102 | +/* This combines all selectors extending it into one */ 103 | +%bwrs-hide { display: none !important; } 104 | + 105 | +/* This allows searching for the combined style in the browsers dev-tools (look into the head tag) */ 106 | +#bwrs-hide, head { @extend %bwrs-hide; } 107 | + 108 | +/* Hide any link pointing to billing */ 109 | +a[href$="/settings/billing"] { @extend %bwrs-hide; } 110 | + 111 | +/* Hide any link pointing to subscriptions */ 112 | +a[href$="/settings/subscription"] { @extend %bwrs-hide; } 113 | + 114 | +/* Hide any link pointing to emergency access */ 115 | +a[href$="/settings/emergency-access"] { @extend %bwrs-hide; } 116 | + 117 | +/* Hide the `Enterprise Single Sign-On` button on the login page */ 118 | +a[href$="/sso"] { @extend %bwrs-hide; } 119 | + 120 | +/* Hide Two-Factor menu in Organization settings */ 121 | +app-org-settings a[href$="/settings/two-factor"] { @extend %bwrs-hide; } 122 | + 123 | +/* Hide organization plans */ 124 | +app-organization-plans > form > div.form-check { @extend %bwrs-hide; } 125 | +app-organization-plans > form > h2.mt-5 { @extend %bwrs-hide; } 126 | + 127 | +/* Hide the `API Key` section under `My Account` */ 128 | +app-account > div:nth-child(9), 129 | +app-account > p, 130 | +app-account > button:nth-child(11), 131 | +app-account > button:nth-child(12) { 132 | + @extend %bwrs-hide; 133 | +} 134 | + 135 | +/* Hide the radio button and label for the `Custom` org user type */ 136 | +#userTypeCustom, label[for^=userTypeCustom] { 137 | + @extend %bwrs-hide; 138 | +} 139 | + 140 | +/* Hide the warning that policy config is moving to Business Portal */ 141 | +app-org-policies > app-callout { @extend %bwrs-hide; } 142 | + 143 | +/* Hide `Single Organization` policy */ 144 | +app-org-policies > table > tbody > tr:nth-child(4) { @extend %bwrs-hide; } 145 | + 146 | +/* Hide Tax Info and Form in Organization settings */ 147 | +app-org-account > div.secondary-header:nth-child(3) { @extend %bwrs-hide; } 148 | +app-org-account > div.secondary-header:nth-child(3) + p { @extend %bwrs-hide; } 149 | +app-org-account > div.secondary-header:nth-child(3) + p + form { @extend %bwrs-hide; } 150 | +/**** END Bitwarden_RS CHANGES ****/ 151 | + 152 | $primary: #175DDC; 153 | $primary-accent: #1252A3; 154 | $secondary: #ced4da; 155 | -------------------------------------------------------------------------------- /patches/legacy/v2.19.0.patch: -------------------------------------------------------------------------------- 1 | Submodule jslib contains modified content 2 | diff --git a/jslib/src/angular/components/register.component.ts b/jslib/src/angular/components/register.component.ts 3 | index 6149f83..005d528 100644 4 | --- a/jslib/src/angular/components/register.component.ts 5 | +++ b/jslib/src/angular/components/register.component.ts 6 | @@ -69,6 +69,12 @@ export class RegisterComponent { 7 | } 8 | 9 | async submit() { 10 | + if (typeof crypto.subtle === 'undefined') { 11 | + this.platformUtilsService.showToast('error', "This browser requires HTTPS to use the web vault", 12 | + "Check the bitwarden_rs wiki for details on how to enable it"); 13 | + return; 14 | + } 15 | + 16 | if (!this.acceptPolicies && this.showTerms) { 17 | this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), 18 | this.i18nService.t('acceptPoliciesError')); 19 | diff --git a/src/404.html b/src/404.html 20 | index dae3951b..b4b3e39b 100644 21 | --- a/src/404.html 22 | +++ b/src/404.html 23 | @@ -45,10 +45,10 @@ 24 | 25 |

26 |

You can return to the web vault, check our status page 27 | - or contact us.

28 | + or contact us.

29 | 30 | 34 | 35 | 36 | diff --git a/src/app/app.component.ts b/src/app/app.component.ts 37 | index 9c5b6b5d..287338d2 100644 38 | --- a/src/app/app.component.ts 39 | +++ b/src/app/app.component.ts 40 | @@ -140,6 +140,10 @@ export class AppComponent implements OnDestroy, OnInit { 41 | } 42 | break; 43 | case 'showToast': 44 | + if (typeof message.text === "string" && typeof crypto.subtle === 'undefined') { 45 | + message.title="This browser requires HTTPS to use the web vault"; 46 | + message.text="Check the bitwarden_rs wiki for details on how to enable it"; 47 | + } 48 | this.showToast(message); 49 | break; 50 | case 'analyticsEventTrack': 51 | diff --git a/src/app/layouts/footer.component.html b/src/app/layouts/footer.component.html 52 | index b001b9e3..c1bd2ac8 100644 53 | --- a/src/app/layouts/footer.component.html 54 | +++ b/src/app/layouts/footer.component.html 55 | @@ -1,7 +1,7 @@ 56 |