mirror of
				https://github.com/dani-garcia/vaultwarden.git
				synced 2025-10-28 00:40:01 +02:00 
			
		
		
		
	Merge branch 'main' into fix-domain-description
This commit is contained in:
		
							
								
								
									
										5
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							| @@ -48,7 +48,10 @@ jobs: | ||||
|         ports: | ||||
|           - 5000:5000 | ||||
|     env: | ||||
|       DOCKER_BUILDKIT: 1 # Disabled for now, but we should look at this because it will speedup building! | ||||
|       # Use BuildKit (https://docs.docker.com/build/buildkit/) for better | ||||
|       # build performance and the ability to copy extended file attributes | ||||
|       # (e.g., for executable capabilities) across build phases. | ||||
|       DOCKER_BUILDKIT: 1 | ||||
|       # DOCKER_REPO/secrets.DOCKERHUB_REPO needs to be 'index.docker.io/<user>/<repo>' | ||||
|       DOCKER_REPO: ${{ secrets.DOCKERHUB_REPO }} | ||||
|       SOURCE_COMMIT: ${{ github.sha }} | ||||
|   | ||||
| @@ -3,5 +3,7 @@ ignored: | ||||
|   - DL3008 | ||||
|   # disable explicit version for apk install | ||||
|   - DL3018 | ||||
|   # disable check for consecutive `RUN` instructions | ||||
|   - DL3059 | ||||
| trustedRegistries: | ||||
|   - docker.io | ||||
|   | ||||
| @@ -8,7 +8,7 @@ resolver = "2" | ||||
|  | ||||
| repository = "https://github.com/dani-garcia/vaultwarden" | ||||
| readme = "README.md" | ||||
| license = "GPL-3.0-only" | ||||
| license = "AGPL-3.0-only" | ||||
| publish = false | ||||
| build = "build.rs" | ||||
|  | ||||
|   | ||||
							
								
								
									
										143
									
								
								LICENSE.txt
									
									
									
									
									
								
							
							
						
						
									
										143
									
								
								LICENSE.txt
									
									
									
									
									
								
							| @@ -1,5 +1,5 @@ | ||||
|                     GNU GENERAL PUBLIC LICENSE | ||||
|                        Version 3, 29 June 2007 | ||||
|                     GNU AFFERO GENERAL PUBLIC LICENSE | ||||
|                        Version 3, 19 November 2007 | ||||
|  | ||||
|  Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> | ||||
|  Everyone is permitted to copy and distribute verbatim copies | ||||
| @@ -7,17 +7,15 @@ | ||||
|  | ||||
|                             Preamble | ||||
|  | ||||
|   The GNU General Public License is a free, copyleft license for | ||||
| software and other kinds of works. | ||||
|   The GNU Affero General Public License is a free, copyleft license for | ||||
| software and other kinds of works, specifically designed to ensure | ||||
| cooperation with the community in the case of network server software. | ||||
|  | ||||
|   The licenses for most software and other practical works are designed | ||||
| to take away your freedom to share and change the works.  By contrast, | ||||
| the GNU General Public License is intended to guarantee your freedom to | ||||
| our General Public Licenses are intended to guarantee your freedom to | ||||
| share and change all versions of a program--to make sure it remains free | ||||
| software for all its users.  We, the Free Software Foundation, use the | ||||
| GNU General Public License for most of our software; it applies also to | ||||
| any other work released this way by its authors.  You can apply it to | ||||
| your programs, too. | ||||
| software for all its users. | ||||
|  | ||||
|   When we speak of free software, we are referring to freedom, not | ||||
| price.  Our General Public Licenses are designed to make sure that you | ||||
| @@ -26,44 +24,34 @@ them if you wish), that you receive source code or can get it if you | ||||
| want it, that you can change the software or use pieces of it in new | ||||
| free programs, and that you know you can do these things. | ||||
|  | ||||
|   To protect your rights, we need to prevent others from denying you | ||||
| these rights or asking you to surrender the rights.  Therefore, you have | ||||
| certain responsibilities if you distribute copies of the software, or if | ||||
| you modify it: responsibilities to respect the freedom of others. | ||||
|   Developers that use our General Public Licenses protect your rights | ||||
| with two steps: (1) assert copyright on the software, and (2) offer | ||||
| you this License which gives you legal permission to copy, distribute | ||||
| and/or modify the software. | ||||
|  | ||||
|   For example, if you distribute copies of such a program, whether | ||||
| gratis or for a fee, you must pass on to the recipients the same | ||||
| freedoms that you received.  You must make sure that they, too, receive | ||||
| or can get the source code.  And you must show them these terms so they | ||||
| know their rights. | ||||
|   A secondary benefit of defending all users' freedom is that | ||||
| improvements made in alternate versions of the program, if they | ||||
| receive widespread use, become available for other developers to | ||||
| incorporate.  Many developers of free software are heartened and | ||||
| encouraged by the resulting cooperation.  However, in the case of | ||||
| software used on network servers, this result may fail to come about. | ||||
| The GNU General Public License permits making a modified version and | ||||
| letting the public access it on a server without ever releasing its | ||||
| source code to the public. | ||||
|  | ||||
|   Developers that use the GNU GPL protect your rights with two steps: | ||||
| (1) assert copyright on the software, and (2) offer you this License | ||||
| giving you legal permission to copy, distribute and/or modify it. | ||||
|   The GNU Affero General Public License is designed specifically to | ||||
| ensure that, in such cases, the modified source code becomes available | ||||
| to the community.  It requires the operator of a network server to | ||||
| provide the source code of the modified version running there to the | ||||
| users of that server.  Therefore, public use of a modified version, on | ||||
| a publicly accessible server, gives the public access to the source | ||||
| code of the modified version. | ||||
|  | ||||
|   For the developers' and authors' protection, the GPL clearly explains | ||||
| that there is no warranty for this free software.  For both users' and | ||||
| authors' sake, the GPL requires that modified versions be marked as | ||||
| changed, so that their problems will not be attributed erroneously to | ||||
| authors of previous versions. | ||||
|  | ||||
|   Some devices are designed to deny users access to install or run | ||||
| modified versions of the software inside them, although the manufacturer | ||||
| can do so.  This is fundamentally incompatible with the aim of | ||||
| protecting users' freedom to change the software.  The systematic | ||||
| pattern of such abuse occurs in the area of products for individuals to | ||||
| use, which is precisely where it is most unacceptable.  Therefore, we | ||||
| have designed this version of the GPL to prohibit the practice for those | ||||
| products.  If such problems arise substantially in other domains, we | ||||
| stand ready to extend this provision to those domains in future versions | ||||
| of the GPL, as needed to protect the freedom of users. | ||||
|  | ||||
|   Finally, every program is threatened constantly by software patents. | ||||
| States should not allow patents to restrict development and use of | ||||
| software on general-purpose computers, but in those that do, we wish to | ||||
| avoid the special danger that patents applied to a free program could | ||||
| make it effectively proprietary.  To prevent this, the GPL assures that | ||||
| patents cannot be used to render the program non-free. | ||||
|   An older license, called the Affero General Public License and | ||||
| published by Affero, was designed to accomplish similar goals.  This is | ||||
| a different license, not a version of the Affero GPL, but Affero has | ||||
| released a new version of the Affero GPL which permits relicensing under | ||||
| this license. | ||||
|  | ||||
|   The precise terms and conditions for copying, distribution and | ||||
| modification follow. | ||||
| @@ -72,7 +60,7 @@ modification follow. | ||||
|  | ||||
|   0. Definitions. | ||||
|  | ||||
|   "This License" refers to version 3 of the GNU General Public License. | ||||
|   "This License" refers to version 3 of the GNU Affero General Public License. | ||||
|  | ||||
|   "Copyright" also means copyright-like laws that apply to other kinds of | ||||
| works, such as semiconductor masks. | ||||
| @@ -549,35 +537,45 @@ to collect a royalty for further conveying from those to whom you convey | ||||
| the Program, the only way you could satisfy both those terms and this | ||||
| License would be to refrain entirely from conveying the Program. | ||||
|  | ||||
|   13. Use with the GNU Affero General Public License. | ||||
|   13. Remote Network Interaction; Use with the GNU General Public License. | ||||
|  | ||||
|   Notwithstanding any other provision of this License, if you modify the | ||||
| Program, your modified version must prominently offer all users | ||||
| interacting with it remotely through a computer network (if your version | ||||
| supports such interaction) an opportunity to receive the Corresponding | ||||
| Source of your version by providing access to the Corresponding Source | ||||
| from a network server at no charge, through some standard or customary | ||||
| means of facilitating copying of software.  This Corresponding Source | ||||
| shall include the Corresponding Source for any work covered by version 3 | ||||
| of the GNU General Public License that is incorporated pursuant to the | ||||
| following paragraph. | ||||
|  | ||||
|   Notwithstanding any other provision of this License, you have | ||||
| permission to link or combine any covered work with a work licensed | ||||
| under version 3 of the GNU Affero General Public License into a single | ||||
| under version 3 of the GNU General Public License into a single | ||||
| combined work, and to convey the resulting work.  The terms of this | ||||
| License will continue to apply to the part which is the covered work, | ||||
| but the special requirements of the GNU Affero General Public License, | ||||
| section 13, concerning interaction through a network will apply to the | ||||
| combination as such. | ||||
| but the work with which it is combined will remain governed by version | ||||
| 3 of the GNU General Public License. | ||||
|  | ||||
|   14. Revised Versions of this License. | ||||
|  | ||||
|   The Free Software Foundation may publish revised and/or new versions of | ||||
| the GNU General Public License from time to time.  Such new versions will | ||||
| be similar in spirit to the present version, but may differ in detail to | ||||
| the GNU Affero General Public License from time to time.  Such new versions | ||||
| will be similar in spirit to the present version, but may differ in detail to | ||||
| address new problems or concerns. | ||||
|  | ||||
|   Each version is given a distinguishing version number.  If the | ||||
| Program specifies that a certain numbered version of the GNU General | ||||
| Program specifies that a certain numbered version of the GNU Affero General | ||||
| Public License "or any later version" applies to it, you have the | ||||
| option of following the terms and conditions either of that numbered | ||||
| version or of any later version published by the Free Software | ||||
| Foundation.  If the Program does not specify a version number of the | ||||
| GNU General Public License, you may choose any version ever published | ||||
| GNU Affero General Public License, you may choose any version ever published | ||||
| by the Free Software Foundation. | ||||
|  | ||||
|   If the Program specifies that a proxy can decide which future | ||||
| versions of the GNU General Public License can be used, that proxy's | ||||
| versions of the GNU Affero General Public License can be used, that proxy's | ||||
| public statement of acceptance of a version permanently authorizes you | ||||
| to choose that version for the Program. | ||||
|  | ||||
| @@ -635,40 +633,29 @@ the "copyright" line and a pointer to where the full notice is found. | ||||
|     Copyright (C) <year>  <name of author> | ||||
|  | ||||
|     This program is free software: you can redistribute it and/or modify | ||||
|     it under the terms of the GNU General Public License as published by | ||||
|     the Free Software Foundation, either version 3 of the License, or | ||||
|     it under the terms of the GNU Affero General Public License as published | ||||
|     by the Free Software Foundation, either version 3 of the License, or | ||||
|     (at your option) any later version. | ||||
|  | ||||
|     This program is distributed in the hope that it will be useful, | ||||
|     but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|     GNU General Public License for more details. | ||||
|     GNU Affero General Public License for more details. | ||||
|  | ||||
|     You should have received a copy of the GNU General Public License | ||||
|     You should have received a copy of the GNU Affero General Public License | ||||
|     along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||
|  | ||||
| Also add information on how to contact you by electronic and paper mail. | ||||
|  | ||||
|   If the program does terminal interaction, make it output a short | ||||
| notice like this when it starts in an interactive mode: | ||||
|  | ||||
|     <program>  Copyright (C) <year>  <name of author> | ||||
|     This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. | ||||
|     This is free software, and you are welcome to redistribute it | ||||
|     under certain conditions; type `show c' for details. | ||||
|  | ||||
| The hypothetical commands `show w' and `show c' should show the appropriate | ||||
| parts of the General Public License.  Of course, your program's commands | ||||
| might be different; for a GUI interface, you would use an "about box". | ||||
|   If your software can interact with users remotely through a computer | ||||
| network, you should also make sure that it provides a way for users to | ||||
| get its source.  For example, if your program is a web application, its | ||||
| interface could display a "Source" link that leads users to an archive | ||||
| of the code.  There are many ways you could offer source, and different | ||||
| solutions will be better for different programs; see section 13 for the | ||||
| specific requirements. | ||||
|  | ||||
|   You should also get your employer (if you work as a programmer) or school, | ||||
| if any, to sign a "copyright disclaimer" for the program, if necessary. | ||||
| For more information on this, and how to apply and follow the GNU GPL, see | ||||
| For more information on this, and how to apply and follow the GNU AGPL, see | ||||
| <https://www.gnu.org/licenses/>. | ||||
|  | ||||
|   The GNU General Public License does not permit incorporating your program | ||||
| into proprietary programs.  If your program is a subroutine library, you | ||||
| may consider it more useful to permit linking proprietary applications with | ||||
| the library.  If this is what you want to do, use the GNU Lesser General | ||||
| Public License instead of this License.  But first, please read | ||||
| <https://www.gnu.org/licenses/why-not-lgpl.html>. | ||||
|   | ||||
| @@ -7,7 +7,7 @@ | ||||
| [](https://hub.docker.com/r/vaultwarden/server) | ||||
| [](https://deps.rs/repo/github/dani-garcia/vaultwarden) | ||||
| [](https://github.com/dani-garcia/vaultwarden/releases/latest) | ||||
| [](https://github.com/dani-garcia/vaultwarden/blob/main/LICENSE.txt) | ||||
| [](https://github.com/dani-garcia/vaultwarden/blob/main/LICENSE.txt) | ||||
| [](https://matrix.to/#/#vaultwarden:matrix.org) | ||||
|  | ||||
| Image is based on [Rust implementation of Bitwarden API](https://github.com/dani-garcia/vaultwarden). | ||||
|   | ||||
| @@ -50,7 +50,7 @@ | ||||
| {% else %} | ||||
| {%   set package_arch_target_param = "" %} | ||||
| {% endif %} | ||||
| {% if "buildx" in target_file %} | ||||
| {% if "buildkit" in target_file %} | ||||
| {%   set mount_rust_cache = "--mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry " %} | ||||
| {% else %} | ||||
| {%   set mount_rust_cache = "" %} | ||||
| @@ -83,8 +83,6 @@ FROM vaultwarden/web-vault@{{ vault_image_digest }} as vault | ||||
| ########################## BUILD IMAGE  ########################## | ||||
| FROM {{ build_stage_base_image }} as build | ||||
|  | ||||
|  | ||||
|  | ||||
| # Build time options to avoid dpkg warnings and help with reproducible builds. | ||||
| ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     LANG=C.UTF-8 \ | ||||
| @@ -93,7 +91,6 @@ ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     CARGO_HOME="/root/.cargo" \ | ||||
|     USER="root" | ||||
|  | ||||
|  | ||||
| # Create CARGO_HOME folder and don't download rust docs | ||||
| RUN {{ mount_rust_cache -}} mkdir -pv "${CARGO_HOME}" \ | ||||
|     && rustup set profile minimal | ||||
| @@ -104,21 +101,20 @@ RUN {{ mount_rust_cache -}} mkdir -pv "${CARGO_HOME}" \ | ||||
| ENV RUSTFLAGS='-Clink-arg=/usr/local/musl/{{ package_arch_target }}/lib/libatomic.a' | ||||
| {%   endif %} | ||||
| {% elif "arm" in target_file %} | ||||
| # | ||||
| # Install required build libs for {{ package_arch_name }} architecture. | ||||
| # hadolint ignore=DL3059 | ||||
| # Install build dependencies for the {{ package_arch_name }} architecture | ||||
| RUN dpkg --add-architecture {{ package_arch_name }} \ | ||||
|     && apt-get update \ | ||||
|     && apt-get install -y \ | ||||
|         --no-install-recommends \ | ||||
|         libssl-dev{{ package_arch_prefix }} \ | ||||
|         gcc-{{ package_cross_compiler }} \ | ||||
|         libc6-dev{{ package_arch_prefix }} \ | ||||
|         libpq5{{ package_arch_prefix }} \ | ||||
|         libpq-dev{{ package_arch_prefix }} \ | ||||
|         libmariadb3{{ package_arch_prefix }} \ | ||||
|         libcap2-bin \ | ||||
|         libmariadb-dev{{ package_arch_prefix }} \ | ||||
|         libmariadb-dev-compat{{ package_arch_prefix }} \ | ||||
|         gcc-{{ package_cross_compiler }} \ | ||||
|         libmariadb3{{ package_arch_prefix }} \ | ||||
|         libpq-dev{{ package_arch_prefix }} \ | ||||
|         libpq5{{ package_arch_prefix }} \ | ||||
|         libssl-dev{{ package_arch_prefix }} \ | ||||
|     # | ||||
|     # Make sure cargo has the right target config | ||||
|     && echo '[target.{{ package_arch_target }}]' >> "${CARGO_HOME}/config" \ | ||||
| @@ -130,16 +126,14 @@ ENV CC_{{ package_arch_target | replace("-", "_") }}="/usr/bin/{{ package_cross_ | ||||
|     CROSS_COMPILE="1" \ | ||||
|     OPENSSL_INCLUDE_DIR="/usr/include/{{ package_cross_compiler }}" \ | ||||
|     OPENSSL_LIB_DIR="/usr/lib/{{ package_cross_compiler }}" | ||||
|  | ||||
| {% elif "amd64" in target_file %} | ||||
| # Install DB packages | ||||
| # Install build dependencies | ||||
| RUN apt-get update \ | ||||
|     && apt-get install -y \ | ||||
|         --no-install-recommends \ | ||||
|         libmariadb-dev{{ package_arch_prefix }} \ | ||||
|         libpq-dev{{ package_arch_prefix }} \ | ||||
|     && apt-get clean \ | ||||
|     && rm -rf /var/lib/apt/lists/* | ||||
|         libcap2-bin \ | ||||
|         libmariadb-dev \ | ||||
|         libpq-dev | ||||
| {% endif %} | ||||
|  | ||||
| # Creates a dummy project used to grab dependencies | ||||
| @@ -178,9 +172,20 @@ RUN touch src/main.rs | ||||
|  | ||||
| # Builds again, this time it'll just be | ||||
| # your actual source files being built | ||||
| # hadolint ignore=DL3059 | ||||
| RUN {{ mount_rust_cache -}} cargo build --features ${DB} --release{{ package_arch_target_param }} | ||||
|  | ||||
| {% if "buildkit" in target_file %} | ||||
| # Add the `cap_net_bind_service` capability to allow listening on | ||||
| # privileged (< 1024) ports even when running as a non-root user. | ||||
| # This is only done if building with BuildKit; with the legacy | ||||
| # builder, the `COPY` instruction doesn't carry over capabilities. | ||||
| {%   if package_arch_target is defined %} | ||||
| RUN setcap cap_net_bind_service=+ep target/{{ package_arch_target }}/release/vaultwarden | ||||
| {%   else %} | ||||
| RUN setcap cap_net_bind_service=+ep target/release/vaultwarden | ||||
| {%   endif %} | ||||
| {% endif %} | ||||
|  | ||||
| ######################## RUNTIME IMAGE  ######################## | ||||
| # Create a new stage with a minimal image | ||||
| # because we already have a binary built | ||||
| @@ -195,7 +200,6 @@ ENV ROCKET_PROFILE="release" \ | ||||
|  | ||||
|  | ||||
| {% if "amd64" not in target_file %} | ||||
| # hadolint ignore=DL3059 | ||||
| RUN [ "cross-build-start" ] | ||||
| {% endif %} | ||||
|  | ||||
| @@ -203,18 +207,18 @@ RUN [ "cross-build-start" ] | ||||
| RUN mkdir /data \ | ||||
| {% if "alpine" in runtime_stage_base_image %} | ||||
|     && apk add --no-cache \ | ||||
|         openssl \ | ||||
|         tzdata \ | ||||
|         ca-certificates \ | ||||
|         curl \ | ||||
|         ca-certificates | ||||
|         openssl \ | ||||
|         tzdata | ||||
| {% else %} | ||||
|     && apt-get update && apt-get install -y \ | ||||
|     --no-install-recommends \ | ||||
|     openssl \ | ||||
|     ca-certificates \ | ||||
|     curl \ | ||||
|     libmariadb-dev-compat \ | ||||
|     libpq5 \ | ||||
|     openssl \ | ||||
|     && apt-get clean \ | ||||
|     && rm -rf /var/lib/apt/lists/* | ||||
| {% endif %} | ||||
| @@ -222,13 +226,11 @@ RUN mkdir /data \ | ||||
| {% if "armv6" in target_file and "alpine" not in target_file %} | ||||
| # In the Balena Bullseye images for armv6/rpi-debian there is a missing symlink. | ||||
| # This symlink was there in the buster images, and for some reason this is needed. | ||||
| # hadolint ignore=DL3059 | ||||
| RUN ln -v -s /lib/ld-linux-armhf.so.3 /lib/ld-linux.so.3 | ||||
|  | ||||
| {% endif -%} | ||||
|  | ||||
| {% if "amd64" not in target_file %} | ||||
| # hadolint ignore=DL3059 | ||||
| RUN [ "cross-build-end" ] | ||||
| {% endif %} | ||||
|  | ||||
|   | ||||
| @@ -8,8 +8,8 @@ all: $(OBJECTS) | ||||
| %/Dockerfile.alpine: Dockerfile.j2 render_template | ||||
| 	./render_template "$<" "{\"target_file\":\"$@\"}" > "$@" | ||||
|  | ||||
| %/Dockerfile.buildx: Dockerfile.j2 render_template | ||||
| %/Dockerfile.buildkit: Dockerfile.j2 render_template | ||||
| 	./render_template "$<" "{\"target_file\":\"$@\"}" > "$@" | ||||
|  | ||||
| %/Dockerfile.buildx.alpine: Dockerfile.j2 render_template | ||||
| %/Dockerfile.buildkit.alpine: Dockerfile.j2 render_template | ||||
| 	./render_template "$<" "{\"target_file\":\"$@\"}" > "$@" | ||||
|   | ||||
| @@ -29,8 +29,6 @@ FROM vaultwarden/web-vault@sha256:d5f71fb05c4b87935bf51d84140db0f8716cabfe2974fb | ||||
| ########################## BUILD IMAGE  ########################## | ||||
| FROM rust:1.66-bullseye as build | ||||
|  | ||||
|  | ||||
|  | ||||
| # Build time options to avoid dpkg warnings and help with reproducible builds. | ||||
| ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     LANG=C.UTF-8 \ | ||||
| @@ -39,19 +37,17 @@ ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     CARGO_HOME="/root/.cargo" \ | ||||
|     USER="root" | ||||
|  | ||||
|  | ||||
| # Create CARGO_HOME folder and don't download rust docs | ||||
| RUN mkdir -pv "${CARGO_HOME}" \ | ||||
|     && rustup set profile minimal | ||||
|  | ||||
| # Install DB packages | ||||
| # Install build dependencies | ||||
| RUN apt-get update \ | ||||
|     && apt-get install -y \ | ||||
|         --no-install-recommends \ | ||||
|         libcap2-bin \ | ||||
|         libmariadb-dev \ | ||||
|         libpq-dev \ | ||||
|     && apt-get clean \ | ||||
|     && rm -rf /var/lib/apt/lists/* | ||||
|         libpq-dev | ||||
|  | ||||
| # Creates a dummy project used to grab dependencies | ||||
| RUN USER=root cargo new --bin /app | ||||
| @@ -81,9 +77,9 @@ RUN touch src/main.rs | ||||
|  | ||||
| # Builds again, this time it'll just be | ||||
| # your actual source files being built | ||||
| # hadolint ignore=DL3059 | ||||
| RUN cargo build --features ${DB} --release | ||||
|  | ||||
|  | ||||
| ######################## RUNTIME IMAGE  ######################## | ||||
| # Create a new stage with a minimal image | ||||
| # because we already have a binary built | ||||
| @@ -98,11 +94,11 @@ ENV ROCKET_PROFILE="release" \ | ||||
| RUN mkdir /data \ | ||||
|     && apt-get update && apt-get install -y \ | ||||
|     --no-install-recommends \ | ||||
|     openssl \ | ||||
|     ca-certificates \ | ||||
|     curl \ | ||||
|     libmariadb-dev-compat \ | ||||
|     libpq5 \ | ||||
|     openssl \ | ||||
|     && apt-get clean \ | ||||
|     && rm -rf /var/lib/apt/lists/* | ||||
|  | ||||
|   | ||||
| @@ -29,8 +29,6 @@ FROM vaultwarden/web-vault@sha256:d5f71fb05c4b87935bf51d84140db0f8716cabfe2974fb | ||||
| ########################## BUILD IMAGE  ########################## | ||||
| FROM blackdex/rust-musl:x86_64-musl-stable-1.66.1 as build | ||||
|  | ||||
|  | ||||
|  | ||||
| # Build time options to avoid dpkg warnings and help with reproducible builds. | ||||
| ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     LANG=C.UTF-8 \ | ||||
| @@ -39,7 +37,6 @@ ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     CARGO_HOME="/root/.cargo" \ | ||||
|     USER="root" | ||||
|  | ||||
|  | ||||
| # Create CARGO_HOME folder and don't download rust docs | ||||
| RUN mkdir -pv "${CARGO_HOME}" \ | ||||
|     && rustup set profile minimal | ||||
| @@ -75,9 +72,9 @@ RUN touch src/main.rs | ||||
|  | ||||
| # Builds again, this time it'll just be | ||||
| # your actual source files being built | ||||
| # hadolint ignore=DL3059 | ||||
| RUN cargo build --features ${DB} --release --target=x86_64-unknown-linux-musl | ||||
|  | ||||
|  | ||||
| ######################## RUNTIME IMAGE  ######################## | ||||
| # Create a new stage with a minimal image | ||||
| # because we already have a binary built | ||||
| @@ -93,10 +90,10 @@ ENV ROCKET_PROFILE="release" \ | ||||
| # Create data folder and Install needed libraries | ||||
| RUN mkdir /data \ | ||||
|     && apk add --no-cache \ | ||||
|         openssl \ | ||||
|         tzdata \ | ||||
|         ca-certificates \ | ||||
|         curl \ | ||||
|         ca-certificates | ||||
|         openssl \ | ||||
|         tzdata | ||||
|  | ||||
|  | ||||
| VOLUME /data | ||||
|   | ||||
| @@ -29,8 +29,6 @@ FROM vaultwarden/web-vault@sha256:d5f71fb05c4b87935bf51d84140db0f8716cabfe2974fb | ||||
| ########################## BUILD IMAGE  ########################## | ||||
| FROM rust:1.66-bullseye as build | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| # Build time options to avoid dpkg warnings and help with reproducible builds. | ||||
| ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     LANG=C.UTF-8 \ | ||||
| @@ -39,19 +37,17 @@ ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     CARGO_HOME="/root/.cargo" \ | ||||
|     USER="root" | ||||
| 
 | ||||
| 
 | ||||
| # Create CARGO_HOME folder and don't download rust docs | ||||
| RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry mkdir -pv "${CARGO_HOME}" \ | ||||
|     && rustup set profile minimal | ||||
| 
 | ||||
| # Install DB packages | ||||
| # Install build dependencies | ||||
| RUN apt-get update \ | ||||
|     && apt-get install -y \ | ||||
|         --no-install-recommends \ | ||||
|         libcap2-bin \ | ||||
|         libmariadb-dev \ | ||||
|         libpq-dev \ | ||||
|     && apt-get clean \ | ||||
|     && rm -rf /var/lib/apt/lists/* | ||||
|         libpq-dev | ||||
| 
 | ||||
| # Creates a dummy project used to grab dependencies | ||||
| RUN USER=root cargo new --bin /app | ||||
| @@ -81,9 +77,14 @@ RUN touch src/main.rs | ||||
| 
 | ||||
| # Builds again, this time it'll just be | ||||
| # your actual source files being built | ||||
| # hadolint ignore=DL3059 | ||||
| RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry cargo build --features ${DB} --release | ||||
| 
 | ||||
| # Add the `cap_net_bind_service` capability to allow listening on | ||||
| # privileged (< 1024) ports even when running as a non-root user. | ||||
| # This is only done if building with BuildKit; with the legacy | ||||
| # builder, the `COPY` instruction doesn't carry over capabilities. | ||||
| RUN setcap cap_net_bind_service=+ep target/release/vaultwarden | ||||
| 
 | ||||
| ######################## RUNTIME IMAGE  ######################## | ||||
| # Create a new stage with a minimal image | ||||
| # because we already have a binary built | ||||
| @@ -98,11 +99,11 @@ ENV ROCKET_PROFILE="release" \ | ||||
| RUN mkdir /data \ | ||||
|     && apt-get update && apt-get install -y \ | ||||
|     --no-install-recommends \ | ||||
|     openssl \ | ||||
|     ca-certificates \ | ||||
|     curl \ | ||||
|     libmariadb-dev-compat \ | ||||
|     libpq5 \ | ||||
|     openssl \ | ||||
|     && apt-get clean \ | ||||
|     && rm -rf /var/lib/apt/lists/* | ||||
| 
 | ||||
| @@ -29,8 +29,6 @@ FROM vaultwarden/web-vault@sha256:d5f71fb05c4b87935bf51d84140db0f8716cabfe2974fb | ||||
| ########################## BUILD IMAGE  ########################## | ||||
| FROM blackdex/rust-musl:x86_64-musl-stable-1.66.1 as build | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| # Build time options to avoid dpkg warnings and help with reproducible builds. | ||||
| ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     LANG=C.UTF-8 \ | ||||
| @@ -39,7 +37,6 @@ ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     CARGO_HOME="/root/.cargo" \ | ||||
|     USER="root" | ||||
| 
 | ||||
| 
 | ||||
| # Create CARGO_HOME folder and don't download rust docs | ||||
| RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry mkdir -pv "${CARGO_HOME}" \ | ||||
|     && rustup set profile minimal | ||||
| @@ -75,9 +72,14 @@ RUN touch src/main.rs | ||||
| 
 | ||||
| # Builds again, this time it'll just be | ||||
| # your actual source files being built | ||||
| # hadolint ignore=DL3059 | ||||
| RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry cargo build --features ${DB} --release --target=x86_64-unknown-linux-musl | ||||
| 
 | ||||
| # Add the `cap_net_bind_service` capability to allow listening on | ||||
| # privileged (< 1024) ports even when running as a non-root user. | ||||
| # This is only done if building with BuildKit; with the legacy | ||||
| # builder, the `COPY` instruction doesn't carry over capabilities. | ||||
| RUN setcap cap_net_bind_service=+ep target/x86_64-unknown-linux-musl/release/vaultwarden | ||||
| 
 | ||||
| ######################## RUNTIME IMAGE  ######################## | ||||
| # Create a new stage with a minimal image | ||||
| # because we already have a binary built | ||||
| @@ -93,10 +95,10 @@ ENV ROCKET_PROFILE="release" \ | ||||
| # Create data folder and Install needed libraries | ||||
| RUN mkdir /data \ | ||||
|     && apk add --no-cache \ | ||||
|         openssl \ | ||||
|         tzdata \ | ||||
|         ca-certificates \ | ||||
|         curl \ | ||||
|         ca-certificates | ||||
|         openssl \ | ||||
|         tzdata | ||||
| 
 | ||||
| 
 | ||||
| VOLUME /data | ||||
| @@ -29,8 +29,6 @@ FROM vaultwarden/web-vault@sha256:d5f71fb05c4b87935bf51d84140db0f8716cabfe2974fb | ||||
| ########################## BUILD IMAGE  ########################## | ||||
| FROM rust:1.66-bullseye as build | ||||
|  | ||||
|  | ||||
|  | ||||
| # Build time options to avoid dpkg warnings and help with reproducible builds. | ||||
| ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     LANG=C.UTF-8 \ | ||||
| @@ -39,26 +37,24 @@ ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     CARGO_HOME="/root/.cargo" \ | ||||
|     USER="root" | ||||
|  | ||||
|  | ||||
| # Create CARGO_HOME folder and don't download rust docs | ||||
| RUN mkdir -pv "${CARGO_HOME}" \ | ||||
|     && rustup set profile minimal | ||||
|  | ||||
| # | ||||
| # Install required build libs for arm64 architecture. | ||||
| # hadolint ignore=DL3059 | ||||
| # Install build dependencies for the arm64 architecture | ||||
| RUN dpkg --add-architecture arm64 \ | ||||
|     && apt-get update \ | ||||
|     && apt-get install -y \ | ||||
|         --no-install-recommends \ | ||||
|         libssl-dev:arm64 \ | ||||
|         gcc-aarch64-linux-gnu \ | ||||
|         libc6-dev:arm64 \ | ||||
|         libpq5:arm64 \ | ||||
|         libpq-dev:arm64 \ | ||||
|         libmariadb3:arm64 \ | ||||
|         libcap2-bin \ | ||||
|         libmariadb-dev:arm64 \ | ||||
|         libmariadb-dev-compat:arm64 \ | ||||
|         gcc-aarch64-linux-gnu \ | ||||
|         libmariadb3:arm64 \ | ||||
|         libpq-dev:arm64 \ | ||||
|         libpq5:arm64 \ | ||||
|         libssl-dev:arm64 \ | ||||
|     # | ||||
|     # Make sure cargo has the right target config | ||||
|     && echo '[target.aarch64-unknown-linux-gnu]' >> "${CARGO_HOME}/config" \ | ||||
| @@ -71,7 +67,6 @@ ENV CC_aarch64_unknown_linux_gnu="/usr/bin/aarch64-linux-gnu-gcc" \ | ||||
|     OPENSSL_INCLUDE_DIR="/usr/include/aarch64-linux-gnu" \ | ||||
|     OPENSSL_LIB_DIR="/usr/lib/aarch64-linux-gnu" | ||||
|  | ||||
|  | ||||
| # Creates a dummy project used to grab dependencies | ||||
| RUN USER=root cargo new --bin /app | ||||
| WORKDIR /app | ||||
| @@ -101,9 +96,9 @@ RUN touch src/main.rs | ||||
|  | ||||
| # Builds again, this time it'll just be | ||||
| # your actual source files being built | ||||
| # hadolint ignore=DL3059 | ||||
| RUN cargo build --features ${DB} --release --target=aarch64-unknown-linux-gnu | ||||
|  | ||||
|  | ||||
| ######################## RUNTIME IMAGE  ######################## | ||||
| # Create a new stage with a minimal image | ||||
| # because we already have a binary built | ||||
| @@ -113,22 +108,20 @@ ENV ROCKET_PROFILE="release" \ | ||||
|     ROCKET_ADDRESS=0.0.0.0 \ | ||||
|     ROCKET_PORT=80 | ||||
|  | ||||
| # hadolint ignore=DL3059 | ||||
| RUN [ "cross-build-start" ] | ||||
|  | ||||
| # Create data folder and Install needed libraries | ||||
| RUN mkdir /data \ | ||||
|     && apt-get update && apt-get install -y \ | ||||
|     --no-install-recommends \ | ||||
|     openssl \ | ||||
|     ca-certificates \ | ||||
|     curl \ | ||||
|     libmariadb-dev-compat \ | ||||
|     libpq5 \ | ||||
|     openssl \ | ||||
|     && apt-get clean \ | ||||
|     && rm -rf /var/lib/apt/lists/* | ||||
|  | ||||
| # hadolint ignore=DL3059 | ||||
| RUN [ "cross-build-end" ] | ||||
|  | ||||
| VOLUME /data | ||||
|   | ||||
| @@ -29,8 +29,6 @@ FROM vaultwarden/web-vault@sha256:d5f71fb05c4b87935bf51d84140db0f8716cabfe2974fb | ||||
| ########################## BUILD IMAGE  ########################## | ||||
| FROM blackdex/rust-musl:aarch64-musl-stable-1.66.1 as build | ||||
|  | ||||
|  | ||||
|  | ||||
| # Build time options to avoid dpkg warnings and help with reproducible builds. | ||||
| ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     LANG=C.UTF-8 \ | ||||
| @@ -39,7 +37,6 @@ ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     CARGO_HOME="/root/.cargo" \ | ||||
|     USER="root" | ||||
|  | ||||
|  | ||||
| # Create CARGO_HOME folder and don't download rust docs | ||||
| RUN mkdir -pv "${CARGO_HOME}" \ | ||||
|     && rustup set profile minimal | ||||
| @@ -75,9 +72,9 @@ RUN touch src/main.rs | ||||
|  | ||||
| # Builds again, this time it'll just be | ||||
| # your actual source files being built | ||||
| # hadolint ignore=DL3059 | ||||
| RUN cargo build --features ${DB} --release --target=aarch64-unknown-linux-musl | ||||
|  | ||||
|  | ||||
| ######################## RUNTIME IMAGE  ######################## | ||||
| # Create a new stage with a minimal image | ||||
| # because we already have a binary built | ||||
| @@ -89,18 +86,16 @@ ENV ROCKET_PROFILE="release" \ | ||||
|     SSL_CERT_DIR=/etc/ssl/certs | ||||
|  | ||||
|  | ||||
| # hadolint ignore=DL3059 | ||||
| RUN [ "cross-build-start" ] | ||||
|  | ||||
| # Create data folder and Install needed libraries | ||||
| RUN mkdir /data \ | ||||
|     && apk add --no-cache \ | ||||
|         openssl \ | ||||
|         tzdata \ | ||||
|         ca-certificates \ | ||||
|         curl \ | ||||
|         ca-certificates | ||||
|         openssl \ | ||||
|         tzdata | ||||
|  | ||||
| # hadolint ignore=DL3059 | ||||
| RUN [ "cross-build-end" ] | ||||
|  | ||||
| VOLUME /data | ||||
|   | ||||
| @@ -29,8 +29,6 @@ FROM vaultwarden/web-vault@sha256:d5f71fb05c4b87935bf51d84140db0f8716cabfe2974fb | ||||
| ########################## BUILD IMAGE  ########################## | ||||
| FROM rust:1.66-bullseye as build | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| # Build time options to avoid dpkg warnings and help with reproducible builds. | ||||
| ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     LANG=C.UTF-8 \ | ||||
| @@ -39,26 +37,24 @@ ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     CARGO_HOME="/root/.cargo" \ | ||||
|     USER="root" | ||||
| 
 | ||||
| 
 | ||||
| # Create CARGO_HOME folder and don't download rust docs | ||||
| RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry mkdir -pv "${CARGO_HOME}" \ | ||||
|     && rustup set profile minimal | ||||
| 
 | ||||
| # | ||||
| # Install required build libs for arm64 architecture. | ||||
| # hadolint ignore=DL3059 | ||||
| # Install build dependencies for the arm64 architecture | ||||
| RUN dpkg --add-architecture arm64 \ | ||||
|     && apt-get update \ | ||||
|     && apt-get install -y \ | ||||
|         --no-install-recommends \ | ||||
|         libssl-dev:arm64 \ | ||||
|         gcc-aarch64-linux-gnu \ | ||||
|         libc6-dev:arm64 \ | ||||
|         libpq5:arm64 \ | ||||
|         libpq-dev:arm64 \ | ||||
|         libmariadb3:arm64 \ | ||||
|         libcap2-bin \ | ||||
|         libmariadb-dev:arm64 \ | ||||
|         libmariadb-dev-compat:arm64 \ | ||||
|         gcc-aarch64-linux-gnu \ | ||||
|         libmariadb3:arm64 \ | ||||
|         libpq-dev:arm64 \ | ||||
|         libpq5:arm64 \ | ||||
|         libssl-dev:arm64 \ | ||||
|     # | ||||
|     # Make sure cargo has the right target config | ||||
|     && echo '[target.aarch64-unknown-linux-gnu]' >> "${CARGO_HOME}/config" \ | ||||
| @@ -71,7 +67,6 @@ ENV CC_aarch64_unknown_linux_gnu="/usr/bin/aarch64-linux-gnu-gcc" \ | ||||
|     OPENSSL_INCLUDE_DIR="/usr/include/aarch64-linux-gnu" \ | ||||
|     OPENSSL_LIB_DIR="/usr/lib/aarch64-linux-gnu" | ||||
| 
 | ||||
| 
 | ||||
| # Creates a dummy project used to grab dependencies | ||||
| RUN USER=root cargo new --bin /app | ||||
| WORKDIR /app | ||||
| @@ -101,9 +96,14 @@ RUN touch src/main.rs | ||||
| 
 | ||||
| # Builds again, this time it'll just be | ||||
| # your actual source files being built | ||||
| # hadolint ignore=DL3059 | ||||
| RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry cargo build --features ${DB} --release --target=aarch64-unknown-linux-gnu | ||||
| 
 | ||||
| # Add the `cap_net_bind_service` capability to allow listening on | ||||
| # privileged (< 1024) ports even when running as a non-root user. | ||||
| # This is only done if building with BuildKit; with the legacy | ||||
| # builder, the `COPY` instruction doesn't carry over capabilities. | ||||
| RUN setcap cap_net_bind_service=+ep target/aarch64-unknown-linux-gnu/release/vaultwarden | ||||
| 
 | ||||
| ######################## RUNTIME IMAGE  ######################## | ||||
| # Create a new stage with a minimal image | ||||
| # because we already have a binary built | ||||
| @@ -113,22 +113,20 @@ ENV ROCKET_PROFILE="release" \ | ||||
|     ROCKET_ADDRESS=0.0.0.0 \ | ||||
|     ROCKET_PORT=80 | ||||
| 
 | ||||
| # hadolint ignore=DL3059 | ||||
| RUN [ "cross-build-start" ] | ||||
| 
 | ||||
| # Create data folder and Install needed libraries | ||||
| RUN mkdir /data \ | ||||
|     && apt-get update && apt-get install -y \ | ||||
|     --no-install-recommends \ | ||||
|     openssl \ | ||||
|     ca-certificates \ | ||||
|     curl \ | ||||
|     libmariadb-dev-compat \ | ||||
|     libpq5 \ | ||||
|     openssl \ | ||||
|     && apt-get clean \ | ||||
|     && rm -rf /var/lib/apt/lists/* | ||||
| 
 | ||||
| # hadolint ignore=DL3059 | ||||
| RUN [ "cross-build-end" ] | ||||
| 
 | ||||
| VOLUME /data | ||||
| @@ -29,8 +29,6 @@ FROM vaultwarden/web-vault@sha256:d5f71fb05c4b87935bf51d84140db0f8716cabfe2974fb | ||||
| ########################## BUILD IMAGE  ########################## | ||||
| FROM blackdex/rust-musl:aarch64-musl-stable-1.66.1 as build | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| # Build time options to avoid dpkg warnings and help with reproducible builds. | ||||
| ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     LANG=C.UTF-8 \ | ||||
| @@ -39,7 +37,6 @@ ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     CARGO_HOME="/root/.cargo" \ | ||||
|     USER="root" | ||||
| 
 | ||||
| 
 | ||||
| # Create CARGO_HOME folder and don't download rust docs | ||||
| RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry mkdir -pv "${CARGO_HOME}" \ | ||||
|     && rustup set profile minimal | ||||
| @@ -75,9 +72,14 @@ RUN touch src/main.rs | ||||
| 
 | ||||
| # Builds again, this time it'll just be | ||||
| # your actual source files being built | ||||
| # hadolint ignore=DL3059 | ||||
| RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry cargo build --features ${DB} --release --target=aarch64-unknown-linux-musl | ||||
| 
 | ||||
| # Add the `cap_net_bind_service` capability to allow listening on | ||||
| # privileged (< 1024) ports even when running as a non-root user. | ||||
| # This is only done if building with BuildKit; with the legacy | ||||
| # builder, the `COPY` instruction doesn't carry over capabilities. | ||||
| RUN setcap cap_net_bind_service=+ep target/aarch64-unknown-linux-musl/release/vaultwarden | ||||
| 
 | ||||
| ######################## RUNTIME IMAGE  ######################## | ||||
| # Create a new stage with a minimal image | ||||
| # because we already have a binary built | ||||
| @@ -89,18 +91,16 @@ ENV ROCKET_PROFILE="release" \ | ||||
|     SSL_CERT_DIR=/etc/ssl/certs | ||||
| 
 | ||||
| 
 | ||||
| # hadolint ignore=DL3059 | ||||
| RUN [ "cross-build-start" ] | ||||
| 
 | ||||
| # Create data folder and Install needed libraries | ||||
| RUN mkdir /data \ | ||||
|     && apk add --no-cache \ | ||||
|         openssl \ | ||||
|         tzdata \ | ||||
|         ca-certificates \ | ||||
|         curl \ | ||||
|         ca-certificates | ||||
|         openssl \ | ||||
|         tzdata | ||||
| 
 | ||||
| # hadolint ignore=DL3059 | ||||
| RUN [ "cross-build-end" ] | ||||
| 
 | ||||
| VOLUME /data | ||||
| @@ -29,8 +29,6 @@ FROM vaultwarden/web-vault@sha256:d5f71fb05c4b87935bf51d84140db0f8716cabfe2974fb | ||||
| ########################## BUILD IMAGE  ########################## | ||||
| FROM rust:1.66-bullseye as build | ||||
|  | ||||
|  | ||||
|  | ||||
| # Build time options to avoid dpkg warnings and help with reproducible builds. | ||||
| ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     LANG=C.UTF-8 \ | ||||
| @@ -39,26 +37,24 @@ ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     CARGO_HOME="/root/.cargo" \ | ||||
|     USER="root" | ||||
|  | ||||
|  | ||||
| # Create CARGO_HOME folder and don't download rust docs | ||||
| RUN mkdir -pv "${CARGO_HOME}" \ | ||||
|     && rustup set profile minimal | ||||
|  | ||||
| # | ||||
| # Install required build libs for armel architecture. | ||||
| # hadolint ignore=DL3059 | ||||
| # Install build dependencies for the armel architecture | ||||
| RUN dpkg --add-architecture armel \ | ||||
|     && apt-get update \ | ||||
|     && apt-get install -y \ | ||||
|         --no-install-recommends \ | ||||
|         libssl-dev:armel \ | ||||
|         gcc-arm-linux-gnueabi \ | ||||
|         libc6-dev:armel \ | ||||
|         libpq5:armel \ | ||||
|         libpq-dev:armel \ | ||||
|         libmariadb3:armel \ | ||||
|         libcap2-bin \ | ||||
|         libmariadb-dev:armel \ | ||||
|         libmariadb-dev-compat:armel \ | ||||
|         gcc-arm-linux-gnueabi \ | ||||
|         libmariadb3:armel \ | ||||
|         libpq-dev:armel \ | ||||
|         libpq5:armel \ | ||||
|         libssl-dev:armel \ | ||||
|     # | ||||
|     # Make sure cargo has the right target config | ||||
|     && echo '[target.arm-unknown-linux-gnueabi]' >> "${CARGO_HOME}/config" \ | ||||
| @@ -71,7 +67,6 @@ ENV CC_arm_unknown_linux_gnueabi="/usr/bin/arm-linux-gnueabi-gcc" \ | ||||
|     OPENSSL_INCLUDE_DIR="/usr/include/arm-linux-gnueabi" \ | ||||
|     OPENSSL_LIB_DIR="/usr/lib/arm-linux-gnueabi" | ||||
|  | ||||
|  | ||||
| # Creates a dummy project used to grab dependencies | ||||
| RUN USER=root cargo new --bin /app | ||||
| WORKDIR /app | ||||
| @@ -101,9 +96,9 @@ RUN touch src/main.rs | ||||
|  | ||||
| # Builds again, this time it'll just be | ||||
| # your actual source files being built | ||||
| # hadolint ignore=DL3059 | ||||
| RUN cargo build --features ${DB} --release --target=arm-unknown-linux-gnueabi | ||||
|  | ||||
|  | ||||
| ######################## RUNTIME IMAGE  ######################## | ||||
| # Create a new stage with a minimal image | ||||
| # because we already have a binary built | ||||
| @@ -113,27 +108,24 @@ ENV ROCKET_PROFILE="release" \ | ||||
|     ROCKET_ADDRESS=0.0.0.0 \ | ||||
|     ROCKET_PORT=80 | ||||
|  | ||||
| # hadolint ignore=DL3059 | ||||
| RUN [ "cross-build-start" ] | ||||
|  | ||||
| # Create data folder and Install needed libraries | ||||
| RUN mkdir /data \ | ||||
|     && apt-get update && apt-get install -y \ | ||||
|     --no-install-recommends \ | ||||
|     openssl \ | ||||
|     ca-certificates \ | ||||
|     curl \ | ||||
|     libmariadb-dev-compat \ | ||||
|     libpq5 \ | ||||
|     openssl \ | ||||
|     && apt-get clean \ | ||||
|     && rm -rf /var/lib/apt/lists/* | ||||
|  | ||||
| # In the Balena Bullseye images for armv6/rpi-debian there is a missing symlink. | ||||
| # This symlink was there in the buster images, and for some reason this is needed. | ||||
| # hadolint ignore=DL3059 | ||||
| RUN ln -v -s /lib/ld-linux-armhf.so.3 /lib/ld-linux.so.3 | ||||
|  | ||||
| # hadolint ignore=DL3059 | ||||
| RUN [ "cross-build-end" ] | ||||
|  | ||||
| VOLUME /data | ||||
|   | ||||
| @@ -29,8 +29,6 @@ FROM vaultwarden/web-vault@sha256:d5f71fb05c4b87935bf51d84140db0f8716cabfe2974fb | ||||
| ########################## BUILD IMAGE  ########################## | ||||
| FROM blackdex/rust-musl:arm-musleabi-stable-1.66.1 as build | ||||
|  | ||||
|  | ||||
|  | ||||
| # Build time options to avoid dpkg warnings and help with reproducible builds. | ||||
| ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     LANG=C.UTF-8 \ | ||||
| @@ -39,7 +37,6 @@ ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     CARGO_HOME="/root/.cargo" \ | ||||
|     USER="root" | ||||
|  | ||||
|  | ||||
| # Create CARGO_HOME folder and don't download rust docs | ||||
| RUN mkdir -pv "${CARGO_HOME}" \ | ||||
|     && rustup set profile minimal | ||||
| @@ -77,9 +74,9 @@ RUN touch src/main.rs | ||||
|  | ||||
| # Builds again, this time it'll just be | ||||
| # your actual source files being built | ||||
| # hadolint ignore=DL3059 | ||||
| RUN cargo build --features ${DB} --release --target=arm-unknown-linux-musleabi | ||||
|  | ||||
|  | ||||
| ######################## RUNTIME IMAGE  ######################## | ||||
| # Create a new stage with a minimal image | ||||
| # because we already have a binary built | ||||
| @@ -91,18 +88,16 @@ ENV ROCKET_PROFILE="release" \ | ||||
|     SSL_CERT_DIR=/etc/ssl/certs | ||||
|  | ||||
|  | ||||
| # hadolint ignore=DL3059 | ||||
| RUN [ "cross-build-start" ] | ||||
|  | ||||
| # Create data folder and Install needed libraries | ||||
| RUN mkdir /data \ | ||||
|     && apk add --no-cache \ | ||||
|         openssl \ | ||||
|         tzdata \ | ||||
|         ca-certificates \ | ||||
|         curl \ | ||||
|         ca-certificates | ||||
|         openssl \ | ||||
|         tzdata | ||||
|  | ||||
| # hadolint ignore=DL3059 | ||||
| RUN [ "cross-build-end" ] | ||||
|  | ||||
| VOLUME /data | ||||
|   | ||||
| @@ -29,8 +29,6 @@ FROM vaultwarden/web-vault@sha256:d5f71fb05c4b87935bf51d84140db0f8716cabfe2974fb | ||||
| ########################## BUILD IMAGE  ########################## | ||||
| FROM rust:1.66-bullseye as build | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| # Build time options to avoid dpkg warnings and help with reproducible builds. | ||||
| ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     LANG=C.UTF-8 \ | ||||
| @@ -39,26 +37,24 @@ ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     CARGO_HOME="/root/.cargo" \ | ||||
|     USER="root" | ||||
| 
 | ||||
| 
 | ||||
| # Create CARGO_HOME folder and don't download rust docs | ||||
| RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry mkdir -pv "${CARGO_HOME}" \ | ||||
|     && rustup set profile minimal | ||||
| 
 | ||||
| # | ||||
| # Install required build libs for armel architecture. | ||||
| # hadolint ignore=DL3059 | ||||
| # Install build dependencies for the armel architecture | ||||
| RUN dpkg --add-architecture armel \ | ||||
|     && apt-get update \ | ||||
|     && apt-get install -y \ | ||||
|         --no-install-recommends \ | ||||
|         libssl-dev:armel \ | ||||
|         gcc-arm-linux-gnueabi \ | ||||
|         libc6-dev:armel \ | ||||
|         libpq5:armel \ | ||||
|         libpq-dev:armel \ | ||||
|         libmariadb3:armel \ | ||||
|         libcap2-bin \ | ||||
|         libmariadb-dev:armel \ | ||||
|         libmariadb-dev-compat:armel \ | ||||
|         gcc-arm-linux-gnueabi \ | ||||
|         libmariadb3:armel \ | ||||
|         libpq-dev:armel \ | ||||
|         libpq5:armel \ | ||||
|         libssl-dev:armel \ | ||||
|     # | ||||
|     # Make sure cargo has the right target config | ||||
|     && echo '[target.arm-unknown-linux-gnueabi]' >> "${CARGO_HOME}/config" \ | ||||
| @@ -71,7 +67,6 @@ ENV CC_arm_unknown_linux_gnueabi="/usr/bin/arm-linux-gnueabi-gcc" \ | ||||
|     OPENSSL_INCLUDE_DIR="/usr/include/arm-linux-gnueabi" \ | ||||
|     OPENSSL_LIB_DIR="/usr/lib/arm-linux-gnueabi" | ||||
| 
 | ||||
| 
 | ||||
| # Creates a dummy project used to grab dependencies | ||||
| RUN USER=root cargo new --bin /app | ||||
| WORKDIR /app | ||||
| @@ -101,9 +96,14 @@ RUN touch src/main.rs | ||||
| 
 | ||||
| # Builds again, this time it'll just be | ||||
| # your actual source files being built | ||||
| # hadolint ignore=DL3059 | ||||
| RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry cargo build --features ${DB} --release --target=arm-unknown-linux-gnueabi | ||||
| 
 | ||||
| # Add the `cap_net_bind_service` capability to allow listening on | ||||
| # privileged (< 1024) ports even when running as a non-root user. | ||||
| # This is only done if building with BuildKit; with the legacy | ||||
| # builder, the `COPY` instruction doesn't carry over capabilities. | ||||
| RUN setcap cap_net_bind_service=+ep target/arm-unknown-linux-gnueabi/release/vaultwarden | ||||
| 
 | ||||
| ######################## RUNTIME IMAGE  ######################## | ||||
| # Create a new stage with a minimal image | ||||
| # because we already have a binary built | ||||
| @@ -113,27 +113,24 @@ ENV ROCKET_PROFILE="release" \ | ||||
|     ROCKET_ADDRESS=0.0.0.0 \ | ||||
|     ROCKET_PORT=80 | ||||
| 
 | ||||
| # hadolint ignore=DL3059 | ||||
| RUN [ "cross-build-start" ] | ||||
| 
 | ||||
| # Create data folder and Install needed libraries | ||||
| RUN mkdir /data \ | ||||
|     && apt-get update && apt-get install -y \ | ||||
|     --no-install-recommends \ | ||||
|     openssl \ | ||||
|     ca-certificates \ | ||||
|     curl \ | ||||
|     libmariadb-dev-compat \ | ||||
|     libpq5 \ | ||||
|     openssl \ | ||||
|     && apt-get clean \ | ||||
|     && rm -rf /var/lib/apt/lists/* | ||||
| 
 | ||||
| # In the Balena Bullseye images for armv6/rpi-debian there is a missing symlink. | ||||
| # This symlink was there in the buster images, and for some reason this is needed. | ||||
| # hadolint ignore=DL3059 | ||||
| RUN ln -v -s /lib/ld-linux-armhf.so.3 /lib/ld-linux.so.3 | ||||
| 
 | ||||
| # hadolint ignore=DL3059 | ||||
| RUN [ "cross-build-end" ] | ||||
| 
 | ||||
| VOLUME /data | ||||
| @@ -29,8 +29,6 @@ FROM vaultwarden/web-vault@sha256:d5f71fb05c4b87935bf51d84140db0f8716cabfe2974fb | ||||
| ########################## BUILD IMAGE  ########################## | ||||
| FROM blackdex/rust-musl:arm-musleabi-stable-1.66.1 as build | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| # Build time options to avoid dpkg warnings and help with reproducible builds. | ||||
| ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     LANG=C.UTF-8 \ | ||||
| @@ -39,7 +37,6 @@ ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     CARGO_HOME="/root/.cargo" \ | ||||
|     USER="root" | ||||
| 
 | ||||
| 
 | ||||
| # Create CARGO_HOME folder and don't download rust docs | ||||
| RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry mkdir -pv "${CARGO_HOME}" \ | ||||
|     && rustup set profile minimal | ||||
| @@ -77,9 +74,14 @@ RUN touch src/main.rs | ||||
| 
 | ||||
| # Builds again, this time it'll just be | ||||
| # your actual source files being built | ||||
| # hadolint ignore=DL3059 | ||||
| RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry cargo build --features ${DB} --release --target=arm-unknown-linux-musleabi | ||||
| 
 | ||||
| # Add the `cap_net_bind_service` capability to allow listening on | ||||
| # privileged (< 1024) ports even when running as a non-root user. | ||||
| # This is only done if building with BuildKit; with the legacy | ||||
| # builder, the `COPY` instruction doesn't carry over capabilities. | ||||
| RUN setcap cap_net_bind_service=+ep target/arm-unknown-linux-musleabi/release/vaultwarden | ||||
| 
 | ||||
| ######################## RUNTIME IMAGE  ######################## | ||||
| # Create a new stage with a minimal image | ||||
| # because we already have a binary built | ||||
| @@ -91,18 +93,16 @@ ENV ROCKET_PROFILE="release" \ | ||||
|     SSL_CERT_DIR=/etc/ssl/certs | ||||
| 
 | ||||
| 
 | ||||
| # hadolint ignore=DL3059 | ||||
| RUN [ "cross-build-start" ] | ||||
| 
 | ||||
| # Create data folder and Install needed libraries | ||||
| RUN mkdir /data \ | ||||
|     && apk add --no-cache \ | ||||
|         openssl \ | ||||
|         tzdata \ | ||||
|         ca-certificates \ | ||||
|         curl \ | ||||
|         ca-certificates | ||||
|         openssl \ | ||||
|         tzdata | ||||
| 
 | ||||
| # hadolint ignore=DL3059 | ||||
| RUN [ "cross-build-end" ] | ||||
| 
 | ||||
| VOLUME /data | ||||
| @@ -29,8 +29,6 @@ FROM vaultwarden/web-vault@sha256:d5f71fb05c4b87935bf51d84140db0f8716cabfe2974fb | ||||
| ########################## BUILD IMAGE  ########################## | ||||
| FROM rust:1.66-bullseye as build | ||||
|  | ||||
|  | ||||
|  | ||||
| # Build time options to avoid dpkg warnings and help with reproducible builds. | ||||
| ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     LANG=C.UTF-8 \ | ||||
| @@ -39,26 +37,24 @@ ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     CARGO_HOME="/root/.cargo" \ | ||||
|     USER="root" | ||||
|  | ||||
|  | ||||
| # Create CARGO_HOME folder and don't download rust docs | ||||
| RUN mkdir -pv "${CARGO_HOME}" \ | ||||
|     && rustup set profile minimal | ||||
|  | ||||
| # | ||||
| # Install required build libs for armhf architecture. | ||||
| # hadolint ignore=DL3059 | ||||
| # Install build dependencies for the armhf architecture | ||||
| RUN dpkg --add-architecture armhf \ | ||||
|     && apt-get update \ | ||||
|     && apt-get install -y \ | ||||
|         --no-install-recommends \ | ||||
|         libssl-dev:armhf \ | ||||
|         gcc-arm-linux-gnueabihf \ | ||||
|         libc6-dev:armhf \ | ||||
|         libpq5:armhf \ | ||||
|         libpq-dev:armhf \ | ||||
|         libmariadb3:armhf \ | ||||
|         libcap2-bin \ | ||||
|         libmariadb-dev:armhf \ | ||||
|         libmariadb-dev-compat:armhf \ | ||||
|         gcc-arm-linux-gnueabihf \ | ||||
|         libmariadb3:armhf \ | ||||
|         libpq-dev:armhf \ | ||||
|         libpq5:armhf \ | ||||
|         libssl-dev:armhf \ | ||||
|     # | ||||
|     # Make sure cargo has the right target config | ||||
|     && echo '[target.armv7-unknown-linux-gnueabihf]' >> "${CARGO_HOME}/config" \ | ||||
| @@ -71,7 +67,6 @@ ENV CC_armv7_unknown_linux_gnueabihf="/usr/bin/arm-linux-gnueabihf-gcc" \ | ||||
|     OPENSSL_INCLUDE_DIR="/usr/include/arm-linux-gnueabihf" \ | ||||
|     OPENSSL_LIB_DIR="/usr/lib/arm-linux-gnueabihf" | ||||
|  | ||||
|  | ||||
| # Creates a dummy project used to grab dependencies | ||||
| RUN USER=root cargo new --bin /app | ||||
| WORKDIR /app | ||||
| @@ -101,9 +96,9 @@ RUN touch src/main.rs | ||||
|  | ||||
| # Builds again, this time it'll just be | ||||
| # your actual source files being built | ||||
| # hadolint ignore=DL3059 | ||||
| RUN cargo build --features ${DB} --release --target=armv7-unknown-linux-gnueabihf | ||||
|  | ||||
|  | ||||
| ######################## RUNTIME IMAGE  ######################## | ||||
| # Create a new stage with a minimal image | ||||
| # because we already have a binary built | ||||
| @@ -113,22 +108,20 @@ ENV ROCKET_PROFILE="release" \ | ||||
|     ROCKET_ADDRESS=0.0.0.0 \ | ||||
|     ROCKET_PORT=80 | ||||
|  | ||||
| # hadolint ignore=DL3059 | ||||
| RUN [ "cross-build-start" ] | ||||
|  | ||||
| # Create data folder and Install needed libraries | ||||
| RUN mkdir /data \ | ||||
|     && apt-get update && apt-get install -y \ | ||||
|     --no-install-recommends \ | ||||
|     openssl \ | ||||
|     ca-certificates \ | ||||
|     curl \ | ||||
|     libmariadb-dev-compat \ | ||||
|     libpq5 \ | ||||
|     openssl \ | ||||
|     && apt-get clean \ | ||||
|     && rm -rf /var/lib/apt/lists/* | ||||
|  | ||||
| # hadolint ignore=DL3059 | ||||
| RUN [ "cross-build-end" ] | ||||
|  | ||||
| VOLUME /data | ||||
|   | ||||
| @@ -29,8 +29,6 @@ FROM vaultwarden/web-vault@sha256:d5f71fb05c4b87935bf51d84140db0f8716cabfe2974fb | ||||
| ########################## BUILD IMAGE  ########################## | ||||
| FROM blackdex/rust-musl:armv7-musleabihf-stable-1.66.1 as build | ||||
|  | ||||
|  | ||||
|  | ||||
| # Build time options to avoid dpkg warnings and help with reproducible builds. | ||||
| ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     LANG=C.UTF-8 \ | ||||
| @@ -39,7 +37,6 @@ ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     CARGO_HOME="/root/.cargo" \ | ||||
|     USER="root" | ||||
|  | ||||
|  | ||||
| # Create CARGO_HOME folder and don't download rust docs | ||||
| RUN mkdir -pv "${CARGO_HOME}" \ | ||||
|     && rustup set profile minimal | ||||
| @@ -75,9 +72,9 @@ RUN touch src/main.rs | ||||
|  | ||||
| # Builds again, this time it'll just be | ||||
| # your actual source files being built | ||||
| # hadolint ignore=DL3059 | ||||
| RUN cargo build --features ${DB} --release --target=armv7-unknown-linux-musleabihf | ||||
|  | ||||
|  | ||||
| ######################## RUNTIME IMAGE  ######################## | ||||
| # Create a new stage with a minimal image | ||||
| # because we already have a binary built | ||||
| @@ -89,18 +86,16 @@ ENV ROCKET_PROFILE="release" \ | ||||
|     SSL_CERT_DIR=/etc/ssl/certs | ||||
|  | ||||
|  | ||||
| # hadolint ignore=DL3059 | ||||
| RUN [ "cross-build-start" ] | ||||
|  | ||||
| # Create data folder and Install needed libraries | ||||
| RUN mkdir /data \ | ||||
|     && apk add --no-cache \ | ||||
|         openssl \ | ||||
|         tzdata \ | ||||
|         ca-certificates \ | ||||
|         curl \ | ||||
|         ca-certificates | ||||
|         openssl \ | ||||
|         tzdata | ||||
|  | ||||
| # hadolint ignore=DL3059 | ||||
| RUN [ "cross-build-end" ] | ||||
|  | ||||
| VOLUME /data | ||||
|   | ||||
| @@ -29,8 +29,6 @@ FROM vaultwarden/web-vault@sha256:d5f71fb05c4b87935bf51d84140db0f8716cabfe2974fb | ||||
| ########################## BUILD IMAGE  ########################## | ||||
| FROM rust:1.66-bullseye as build | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| # Build time options to avoid dpkg warnings and help with reproducible builds. | ||||
| ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     LANG=C.UTF-8 \ | ||||
| @@ -39,26 +37,24 @@ ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     CARGO_HOME="/root/.cargo" \ | ||||
|     USER="root" | ||||
| 
 | ||||
| 
 | ||||
| # Create CARGO_HOME folder and don't download rust docs | ||||
| RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry mkdir -pv "${CARGO_HOME}" \ | ||||
|     && rustup set profile minimal | ||||
| 
 | ||||
| # | ||||
| # Install required build libs for armhf architecture. | ||||
| # hadolint ignore=DL3059 | ||||
| # Install build dependencies for the armhf architecture | ||||
| RUN dpkg --add-architecture armhf \ | ||||
|     && apt-get update \ | ||||
|     && apt-get install -y \ | ||||
|         --no-install-recommends \ | ||||
|         libssl-dev:armhf \ | ||||
|         gcc-arm-linux-gnueabihf \ | ||||
|         libc6-dev:armhf \ | ||||
|         libpq5:armhf \ | ||||
|         libpq-dev:armhf \ | ||||
|         libmariadb3:armhf \ | ||||
|         libcap2-bin \ | ||||
|         libmariadb-dev:armhf \ | ||||
|         libmariadb-dev-compat:armhf \ | ||||
|         gcc-arm-linux-gnueabihf \ | ||||
|         libmariadb3:armhf \ | ||||
|         libpq-dev:armhf \ | ||||
|         libpq5:armhf \ | ||||
|         libssl-dev:armhf \ | ||||
|     # | ||||
|     # Make sure cargo has the right target config | ||||
|     && echo '[target.armv7-unknown-linux-gnueabihf]' >> "${CARGO_HOME}/config" \ | ||||
| @@ -71,7 +67,6 @@ ENV CC_armv7_unknown_linux_gnueabihf="/usr/bin/arm-linux-gnueabihf-gcc" \ | ||||
|     OPENSSL_INCLUDE_DIR="/usr/include/arm-linux-gnueabihf" \ | ||||
|     OPENSSL_LIB_DIR="/usr/lib/arm-linux-gnueabihf" | ||||
| 
 | ||||
| 
 | ||||
| # Creates a dummy project used to grab dependencies | ||||
| RUN USER=root cargo new --bin /app | ||||
| WORKDIR /app | ||||
| @@ -101,9 +96,14 @@ RUN touch src/main.rs | ||||
| 
 | ||||
| # Builds again, this time it'll just be | ||||
| # your actual source files being built | ||||
| # hadolint ignore=DL3059 | ||||
| RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry cargo build --features ${DB} --release --target=armv7-unknown-linux-gnueabihf | ||||
| 
 | ||||
| # Add the `cap_net_bind_service` capability to allow listening on | ||||
| # privileged (< 1024) ports even when running as a non-root user. | ||||
| # This is only done if building with BuildKit; with the legacy | ||||
| # builder, the `COPY` instruction doesn't carry over capabilities. | ||||
| RUN setcap cap_net_bind_service=+ep target/armv7-unknown-linux-gnueabihf/release/vaultwarden | ||||
| 
 | ||||
| ######################## RUNTIME IMAGE  ######################## | ||||
| # Create a new stage with a minimal image | ||||
| # because we already have a binary built | ||||
| @@ -113,22 +113,20 @@ ENV ROCKET_PROFILE="release" \ | ||||
|     ROCKET_ADDRESS=0.0.0.0 \ | ||||
|     ROCKET_PORT=80 | ||||
| 
 | ||||
| # hadolint ignore=DL3059 | ||||
| RUN [ "cross-build-start" ] | ||||
| 
 | ||||
| # Create data folder and Install needed libraries | ||||
| RUN mkdir /data \ | ||||
|     && apt-get update && apt-get install -y \ | ||||
|     --no-install-recommends \ | ||||
|     openssl \ | ||||
|     ca-certificates \ | ||||
|     curl \ | ||||
|     libmariadb-dev-compat \ | ||||
|     libpq5 \ | ||||
|     openssl \ | ||||
|     && apt-get clean \ | ||||
|     && rm -rf /var/lib/apt/lists/* | ||||
| 
 | ||||
| # hadolint ignore=DL3059 | ||||
| RUN [ "cross-build-end" ] | ||||
| 
 | ||||
| VOLUME /data | ||||
| @@ -29,8 +29,6 @@ FROM vaultwarden/web-vault@sha256:d5f71fb05c4b87935bf51d84140db0f8716cabfe2974fb | ||||
| ########################## BUILD IMAGE  ########################## | ||||
| FROM blackdex/rust-musl:armv7-musleabihf-stable-1.66.1 as build | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| # Build time options to avoid dpkg warnings and help with reproducible builds. | ||||
| ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     LANG=C.UTF-8 \ | ||||
| @@ -39,7 +37,6 @@ ENV DEBIAN_FRONTEND=noninteractive \ | ||||
|     CARGO_HOME="/root/.cargo" \ | ||||
|     USER="root" | ||||
| 
 | ||||
| 
 | ||||
| # Create CARGO_HOME folder and don't download rust docs | ||||
| RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry mkdir -pv "${CARGO_HOME}" \ | ||||
|     && rustup set profile minimal | ||||
| @@ -75,9 +72,14 @@ RUN touch src/main.rs | ||||
| 
 | ||||
| # Builds again, this time it'll just be | ||||
| # your actual source files being built | ||||
| # hadolint ignore=DL3059 | ||||
| RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry cargo build --features ${DB} --release --target=armv7-unknown-linux-musleabihf | ||||
| 
 | ||||
| # Add the `cap_net_bind_service` capability to allow listening on | ||||
| # privileged (< 1024) ports even when running as a non-root user. | ||||
| # This is only done if building with BuildKit; with the legacy | ||||
| # builder, the `COPY` instruction doesn't carry over capabilities. | ||||
| RUN setcap cap_net_bind_service=+ep target/armv7-unknown-linux-musleabihf/release/vaultwarden | ||||
| 
 | ||||
| ######################## RUNTIME IMAGE  ######################## | ||||
| # Create a new stage with a minimal image | ||||
| # because we already have a binary built | ||||
| @@ -89,18 +91,16 @@ ENV ROCKET_PROFILE="release" \ | ||||
|     SSL_CERT_DIR=/etc/ssl/certs | ||||
| 
 | ||||
| 
 | ||||
| # hadolint ignore=DL3059 | ||||
| RUN [ "cross-build-start" ] | ||||
| 
 | ||||
| # Create data folder and Install needed libraries | ||||
| RUN mkdir /data \ | ||||
|     && apk add --no-cache \ | ||||
|         openssl \ | ||||
|         tzdata \ | ||||
|         ca-certificates \ | ||||
|         curl \ | ||||
|         ca-certificates | ||||
|         openssl \ | ||||
|         tzdata | ||||
| 
 | ||||
| # hadolint ignore=DL3059 | ||||
| RUN [ "cross-build-end" ] | ||||
| 
 | ||||
| VOLUME /data | ||||
| @@ -23,7 +23,7 @@ LABELS=( | ||||
|     # https://github.com/opencontainers/image-spec/blob/master/annotations.md | ||||
|     org.opencontainers.image.created="$(date --utc --iso-8601=seconds)" | ||||
|     org.opencontainers.image.documentation="https://github.com/dani-garcia/vaultwarden/wiki" | ||||
|     org.opencontainers.image.licenses="GPL-3.0-only" | ||||
|     org.opencontainers.image.licenses="AGPL-3.0-only" | ||||
|     org.opencontainers.image.revision="${SOURCE_COMMIT}" | ||||
|     org.opencontainers.image.source="${SOURCE_REPOSITORY_URL}" | ||||
|     org.opencontainers.image.url="https://hub.docker.com/r/${DOCKER_REPO#*/}" | ||||
| @@ -34,9 +34,9 @@ for label in "${LABELS[@]}"; do | ||||
|     LABEL_ARGS+=(--label "${label}") | ||||
| done | ||||
|  | ||||
| # Check if DOCKER_BUILDKIT is set, if so, use the Dockerfile.buildx as template | ||||
| # Check if DOCKER_BUILDKIT is set, if so, use the Dockerfile.buildkit as template | ||||
| if [[ -n "${DOCKER_BUILDKIT}" ]]; then | ||||
|     buildx_suffix=.buildx | ||||
|     buildkit_suffix=.buildkit | ||||
| fi | ||||
|  | ||||
| set -ex | ||||
| @@ -45,6 +45,6 @@ for arch in "${arches[@]}"; do | ||||
|     docker build \ | ||||
|            "${LABEL_ARGS[@]}" \ | ||||
|            -t "${DOCKER_REPO}:${DOCKER_TAG}-${arch}" \ | ||||
|            -f docker/${arch}/Dockerfile${buildx_suffix}${distro_suffix} \ | ||||
|            -f docker/${arch}/Dockerfile${buildkit_suffix}${distro_suffix} \ | ||||
|            . | ||||
| done | ||||
|   | ||||
| @@ -0,0 +1,2 @@ | ||||
| ALTER TABLE users_organizations | ||||
| ADD COLUMN reset_password_key TEXT; | ||||
| @@ -0,0 +1,2 @@ | ||||
| ALTER TABLE users_organizations | ||||
| ADD COLUMN reset_password_key TEXT; | ||||
| @@ -0,0 +1,2 @@ | ||||
| ALTER TABLE users_organizations | ||||
| ADD COLUMN reset_password_key TEXT; | ||||
| @@ -123,7 +123,9 @@ async fn post_emergency_access( | ||||
|  | ||||
|     emergency_access.atype = new_type; | ||||
|     emergency_access.wait_time_days = data.WaitTimeDays; | ||||
|     if data.KeyEncrypted.is_some() { | ||||
|         emergency_access.key_encrypted = data.KeyEncrypted; | ||||
|     } | ||||
|  | ||||
|     emergency_access.save(&mut conn).await?; | ||||
|     Ok(Json(emergency_access.to_json())) | ||||
|   | ||||
| @@ -62,6 +62,7 @@ pub fn routes() -> Vec<Route> { | ||||
|         get_plans_tax_rates, | ||||
|         import, | ||||
|         post_org_keys, | ||||
|         get_organization_keys, | ||||
|         bulk_public_keys, | ||||
|         deactivate_organization_user, | ||||
|         bulk_deactivate_organization_user, | ||||
| @@ -86,6 +87,9 @@ pub fn routes() -> Vec<Route> { | ||||
|         put_user_groups, | ||||
|         delete_group_user, | ||||
|         post_delete_group_user, | ||||
|         put_reset_password_enrollment, | ||||
|         get_reset_password_details, | ||||
|         put_reset_password, | ||||
|         get_org_export | ||||
|     ] | ||||
| } | ||||
| @@ -882,6 +886,7 @@ async fn _reinvite_user(org_id: &str, user_org: &str, invited_by_email: &str, co | ||||
| #[allow(non_snake_case)] | ||||
| struct AcceptData { | ||||
|     Token: String, | ||||
|     ResetPasswordKey: Option<String>, | ||||
| } | ||||
|  | ||||
| #[post("/organizations/<org_id>/users/<_org_user_id>/accept", data = "<data>")] | ||||
| @@ -909,6 +914,11 @@ async fn accept_invite( | ||||
|                     err!("User already accepted the invitation") | ||||
|                 } | ||||
|  | ||||
|                 let master_password_required = OrgPolicy::org_is_reset_password_auto_enroll(org, &mut conn).await; | ||||
|                 if data.ResetPasswordKey.is_none() && master_password_required { | ||||
|                     err!("Reset password key is required, but not provided."); | ||||
|                 } | ||||
|  | ||||
|                 // This check is also done at accept_invite(), _confirm_invite, _activate_user(), edit_user(), admin::update_user_org_type | ||||
|                 // It returns different error messages per function. | ||||
|                 if user_org.atype < UserOrgType::Admin { | ||||
| @@ -924,6 +934,11 @@ async fn accept_invite( | ||||
|                 } | ||||
|  | ||||
|                 user_org.status = UserOrgStatus::Accepted as i32; | ||||
|  | ||||
|                 if master_password_required { | ||||
|                     user_org.reset_password_key = data.ResetPasswordKey; | ||||
|                 } | ||||
|  | ||||
|                 user_org.save(&mut conn).await?; | ||||
|             } | ||||
|         } | ||||
| @@ -2460,6 +2475,204 @@ async fn delete_group_user( | ||||
|     GroupUser::delete_by_group_id_and_user_id(&group_id, &org_user_id, &mut conn).await | ||||
| } | ||||
|  | ||||
| #[derive(Deserialize)] | ||||
| #[allow(non_snake_case)] | ||||
| struct OrganizationUserResetPasswordEnrollmentRequest { | ||||
|     ResetPasswordKey: Option<String>, | ||||
| } | ||||
|  | ||||
| #[derive(Deserialize)] | ||||
| #[allow(non_snake_case)] | ||||
| struct OrganizationUserResetPasswordRequest { | ||||
|     NewMasterPasswordHash: String, | ||||
|     Key: String, | ||||
| } | ||||
|  | ||||
| #[get("/organizations/<org_id>/keys")] | ||||
| async fn get_organization_keys(org_id: String, mut conn: DbConn) -> JsonResult { | ||||
|     let org = match Organization::find_by_uuid(&org_id, &mut conn).await { | ||||
|         Some(organization) => organization, | ||||
|         None => err!("Organization not found"), | ||||
|     }; | ||||
|  | ||||
|     Ok(Json(json!({ | ||||
|         "Object": "organizationKeys", | ||||
|         "PublicKey": org.public_key, | ||||
|         "PrivateKey": org.private_key, | ||||
|     }))) | ||||
| } | ||||
|  | ||||
| #[put("/organizations/<org_id>/users/<org_user_id>/reset-password", data = "<data>")] | ||||
| async fn put_reset_password( | ||||
|     org_id: String, | ||||
|     org_user_id: String, | ||||
|     headers: AdminHeaders, | ||||
|     data: JsonUpcase<OrganizationUserResetPasswordRequest>, | ||||
|     mut conn: DbConn, | ||||
|     ip: ClientIp, | ||||
|     nt: Notify<'_>, | ||||
| ) -> EmptyResult { | ||||
|     let org = match Organization::find_by_uuid(&org_id, &mut conn).await { | ||||
|         Some(org) => org, | ||||
|         None => err!("Required organization not found"), | ||||
|     }; | ||||
|  | ||||
|     let org_user = match UserOrganization::find_by_uuid_and_org(&org_user_id, &org.uuid, &mut conn).await { | ||||
|         Some(user) => user, | ||||
|         None => err!("User to reset isn't member of required organization"), | ||||
|     }; | ||||
|  | ||||
|     let mut user = match User::find_by_uuid(&org_user.user_uuid, &mut conn).await { | ||||
|         Some(user) => user, | ||||
|         None => err!("User not found"), | ||||
|     }; | ||||
|  | ||||
|     check_reset_password_applicable_and_permissions(&org_id, &org_user_id, &headers, &mut conn).await?; | ||||
|  | ||||
|     if org_user.reset_password_key.is_none() { | ||||
|         err!("Password reset not or not correctly enrolled"); | ||||
|     } | ||||
|     if org_user.status != (UserOrgStatus::Confirmed as i32) { | ||||
|         err!("Organization user must be confirmed for password reset functionality"); | ||||
|     } | ||||
|  | ||||
|     // Sending email before resetting password to ensure working email configuration and the resulting | ||||
|     // user notification. Also this might add some protection against security flaws and misuse | ||||
|     if let Err(e) = mail::send_admin_reset_password(&user.email, &user.name, &org.name).await { | ||||
|         error!("Error sending user reset password email: {:#?}", e); | ||||
|     } | ||||
|  | ||||
|     let reset_request = data.into_inner().data; | ||||
|  | ||||
|     user.set_password(reset_request.NewMasterPasswordHash.as_str(), Some(reset_request.Key), true, None); | ||||
|     user.save(&mut conn).await?; | ||||
|  | ||||
|     nt.send_logout(&user, None).await; | ||||
|  | ||||
|     log_event( | ||||
|         EventType::OrganizationUserAdminResetPassword as i32, | ||||
|         &org_user_id, | ||||
|         org.uuid.clone(), | ||||
|         headers.user.uuid.clone(), | ||||
|         headers.device.atype, | ||||
|         &ip.ip, | ||||
|         &mut conn, | ||||
|     ) | ||||
|     .await; | ||||
|  | ||||
|     Ok(()) | ||||
| } | ||||
|  | ||||
| #[get("/organizations/<org_id>/users/<org_user_id>/reset-password-details")] | ||||
| async fn get_reset_password_details( | ||||
|     org_id: String, | ||||
|     org_user_id: String, | ||||
|     headers: AdminHeaders, | ||||
|     mut conn: DbConn, | ||||
| ) -> JsonResult { | ||||
|     let org = match Organization::find_by_uuid(&org_id, &mut conn).await { | ||||
|         Some(org) => org, | ||||
|         None => err!("Required organization not found"), | ||||
|     }; | ||||
|  | ||||
|     let org_user = match UserOrganization::find_by_uuid_and_org(&org_user_id, &org_id, &mut conn).await { | ||||
|         Some(user) => user, | ||||
|         None => err!("User to reset isn't member of required organization"), | ||||
|     }; | ||||
|  | ||||
|     let user = match User::find_by_uuid(&org_user.user_uuid, &mut conn).await { | ||||
|         Some(user) => user, | ||||
|         None => err!("User not found"), | ||||
|     }; | ||||
|  | ||||
|     check_reset_password_applicable_and_permissions(&org_id, &org_user_id, &headers, &mut conn).await?; | ||||
|  | ||||
|     Ok(Json(json!({ | ||||
|         "Object": "organizationUserResetPasswordDetails", | ||||
|         "Kdf":user.client_kdf_type, | ||||
|         "KdfIterations":user.client_kdf_iter, | ||||
|         "ResetPasswordKey":org_user.reset_password_key, | ||||
|         "EncryptedPrivateKey":org.private_key , | ||||
|  | ||||
|     }))) | ||||
| } | ||||
|  | ||||
| async fn check_reset_password_applicable_and_permissions( | ||||
|     org_id: &str, | ||||
|     org_user_id: &str, | ||||
|     headers: &AdminHeaders, | ||||
|     conn: &mut DbConn, | ||||
| ) -> EmptyResult { | ||||
|     check_reset_password_applicable(org_id, conn).await?; | ||||
|  | ||||
|     let target_user = match UserOrganization::find_by_uuid_and_org(org_user_id, org_id, conn).await { | ||||
|         Some(user) => user, | ||||
|         None => err!("Reset target user not found"), | ||||
|     }; | ||||
|  | ||||
|     // Resetting user must be higher/equal to user to reset | ||||
|     match headers.org_user_type { | ||||
|         UserOrgType::Owner => Ok(()), | ||||
|         UserOrgType::Admin if target_user.atype <= UserOrgType::Admin => Ok(()), | ||||
|         _ => err!("No permission to reset this user's password"), | ||||
|     } | ||||
| } | ||||
|  | ||||
| async fn check_reset_password_applicable(org_id: &str, conn: &mut DbConn) -> EmptyResult { | ||||
|     if !CONFIG.mail_enabled() { | ||||
|         err!("Password reset is not supported on an email-disabled instance."); | ||||
|     } | ||||
|  | ||||
|     let policy = match OrgPolicy::find_by_org_and_type(org_id, OrgPolicyType::ResetPassword, conn).await { | ||||
|         Some(p) => p, | ||||
|         None => err!("Policy not found"), | ||||
|     }; | ||||
|  | ||||
|     if !policy.enabled { | ||||
|         err!("Reset password policy not enabled"); | ||||
|     } | ||||
|  | ||||
|     Ok(()) | ||||
| } | ||||
|  | ||||
| #[put("/organizations/<org_id>/users/<org_user_id>/reset-password-enrollment", data = "<data>")] | ||||
| async fn put_reset_password_enrollment( | ||||
|     org_id: String, | ||||
|     org_user_id: String, | ||||
|     headers: Headers, | ||||
|     data: JsonUpcase<OrganizationUserResetPasswordEnrollmentRequest>, | ||||
|     mut conn: DbConn, | ||||
|     ip: ClientIp, | ||||
| ) -> EmptyResult { | ||||
|     let mut org_user = match UserOrganization::find_by_user_and_org(&headers.user.uuid, &org_id, &mut conn).await { | ||||
|         Some(u) => u, | ||||
|         None => err!("User to enroll isn't member of required organization"), | ||||
|     }; | ||||
|  | ||||
|     check_reset_password_applicable(&org_id, &mut conn).await?; | ||||
|  | ||||
|     let reset_request = data.into_inner().data; | ||||
|  | ||||
|     if reset_request.ResetPasswordKey.is_none() | ||||
|         && OrgPolicy::org_is_reset_password_auto_enroll(&org_id, &mut conn).await | ||||
|     { | ||||
|         err!("Reset password can't be withdrawed due to an enterprise policy"); | ||||
|     } | ||||
|  | ||||
|     org_user.reset_password_key = reset_request.ResetPasswordKey; | ||||
|     org_user.save(&mut conn).await?; | ||||
|  | ||||
|     let log_id = if org_user.reset_password_key.is_some() { | ||||
|         EventType::OrganizationUserResetPasswordEnroll as i32 | ||||
|     } else { | ||||
|         EventType::OrganizationUserResetPasswordWithdraw as i32 | ||||
|     }; | ||||
|  | ||||
|     log_event(log_id, &org_user_id, org_id, headers.user.uuid.clone(), headers.device.atype, &ip.ip, &mut conn).await; | ||||
|  | ||||
|     Ok(()) | ||||
| } | ||||
|  | ||||
| // This is a new function active since the v2022.9.x clients. | ||||
| // It combines the previous two calls done before. | ||||
| // We call those two functions here and combine them our selfs. | ||||
|   | ||||
| @@ -1138,6 +1138,7 @@ where | ||||
|     reg!("email/email_footer"); | ||||
|     reg!("email/email_footer_text"); | ||||
|  | ||||
|     reg!("email/admin_reset_password", ".html"); | ||||
|     reg!("email/change_email", ".html"); | ||||
|     reg!("email/delete_account", ".html"); | ||||
|     reg!("email/emergency_access_invite_accepted", ".html"); | ||||
|   | ||||
| @@ -87,9 +87,9 @@ pub enum EventType { | ||||
|     OrganizationUserRemoved = 1503, | ||||
|     OrganizationUserUpdatedGroups = 1504, | ||||
|     // OrganizationUserUnlinkedSso = 1505, // Not supported | ||||
|     // OrganizationUserResetPasswordEnroll = 1506, // Not supported | ||||
|     // OrganizationUserResetPasswordWithdraw = 1507, // Not supported | ||||
|     // OrganizationUserAdminResetPassword = 1508, // Not supported | ||||
|     OrganizationUserResetPasswordEnroll = 1506, | ||||
|     OrganizationUserResetPasswordWithdraw = 1507, | ||||
|     OrganizationUserAdminResetPassword = 1508, | ||||
|     // OrganizationUserResetSsoLink = 1509, // Not supported | ||||
|     // OrganizationUserFirstSsoLogin = 1510, // Not supported | ||||
|     OrganizationUserRevoked = 1511, | ||||
|   | ||||
| @@ -32,7 +32,7 @@ pub enum OrgPolicyType { | ||||
|     PersonalOwnership = 5, | ||||
|     DisableSend = 6, | ||||
|     SendOptions = 7, | ||||
|     // ResetPassword = 8, // Not supported | ||||
|     ResetPassword = 8, | ||||
|     // MaximumVaultTimeout = 9, // Not supported (Not AGPLv3 Licensed) | ||||
|     // DisablePersonalVaultExport = 10, // Not supported (Not AGPLv3 Licensed) | ||||
| } | ||||
| @@ -44,6 +44,13 @@ pub struct SendOptionsPolicyData { | ||||
|     pub DisableHideEmail: bool, | ||||
| } | ||||
|  | ||||
| // https://github.com/bitwarden/server/blob/5cbdee137921a19b1f722920f0fa3cd45af2ef0f/src/Core/Models/Data/Organizations/Policies/ResetPasswordDataModel.cs | ||||
| #[derive(Deserialize)] | ||||
| #[allow(non_snake_case)] | ||||
| pub struct ResetPasswordDataModel { | ||||
|     pub AutoEnrollEnabled: bool, | ||||
| } | ||||
|  | ||||
| pub type OrgPolicyResult = Result<(), OrgPolicyErr>; | ||||
|  | ||||
| #[derive(Debug)] | ||||
| @@ -298,6 +305,20 @@ impl OrgPolicy { | ||||
|         Ok(()) | ||||
|     } | ||||
|  | ||||
|     pub async fn org_is_reset_password_auto_enroll(org_uuid: &str, conn: &mut DbConn) -> bool { | ||||
|         match OrgPolicy::find_by_org_and_type(org_uuid, OrgPolicyType::ResetPassword, conn).await { | ||||
|             Some(policy) => match serde_json::from_str::<UpCase<ResetPasswordDataModel>>(&policy.data) { | ||||
|                 Ok(opts) => { | ||||
|                     return opts.data.AutoEnrollEnabled; | ||||
|                 } | ||||
|                 _ => error!("Failed to deserialize ResetPasswordDataModel: {}", policy.data), | ||||
|             }, | ||||
|             None => return false, | ||||
|         } | ||||
|  | ||||
|         false | ||||
|     } | ||||
|  | ||||
|     /// Returns true if the user belongs to an org that has enabled the `DisableHideEmail` | ||||
|     /// option of the `Send Options` policy, and the user is not an owner or admin of that org. | ||||
|     pub async fn is_hide_email_disabled(user_uuid: &str, conn: &mut DbConn) -> bool { | ||||
|   | ||||
| @@ -29,6 +29,7 @@ db_object! { | ||||
|         pub akey: String, | ||||
|         pub status: i32, | ||||
|         pub atype: i32, | ||||
|         pub reset_password_key: Option<String>, | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -158,7 +159,7 @@ impl Organization { | ||||
|             "SelfHost": true, | ||||
|             "UseApi": false, // Not supported | ||||
|             "HasPublicAndPrivateKeys": self.private_key.is_some() && self.public_key.is_some(), | ||||
|             "UseResetPassword": false, // Not supported | ||||
|             "UseResetPassword": CONFIG.mail_enabled(), | ||||
|  | ||||
|             "BusinessName": null, | ||||
|             "BusinessAddress1": null, | ||||
| @@ -194,6 +195,7 @@ impl UserOrganization { | ||||
|             akey: String::new(), | ||||
|             status: UserOrgStatus::Accepted as i32, | ||||
|             atype: UserOrgType::User as i32, | ||||
|             reset_password_key: None, | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -311,7 +313,8 @@ impl UserOrganization { | ||||
|             "UseApi": false, // Not supported | ||||
|             "SelfHost": true, | ||||
|             "HasPublicAndPrivateKeys": org.private_key.is_some() && org.public_key.is_some(), | ||||
|             "ResetPasswordEnrolled": false, // Not supported | ||||
|             "ResetPasswordEnrolled": self.reset_password_key.is_some(), | ||||
|             "UseResetPassword": CONFIG.mail_enabled(), | ||||
|             "SsoBound": false, // Not supported | ||||
|             "UseSso": false, // Not supported | ||||
|             "ProviderId": null, | ||||
| @@ -377,6 +380,7 @@ impl UserOrganization { | ||||
|             "Type": self.atype, | ||||
|             "AccessAll": self.access_all, | ||||
|             "TwoFactorEnabled": twofactor_enabled, | ||||
|             "ResetPasswordEnrolled":self.reset_password_key.is_some(), | ||||
|  | ||||
|             "Object": "organizationUserUserDetails", | ||||
|         }) | ||||
|   | ||||
| @@ -222,6 +222,7 @@ table! { | ||||
|         akey -> Text, | ||||
|         status -> Integer, | ||||
|         atype -> Integer, | ||||
|         reset_password_key -> Nullable<Text>, | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -222,6 +222,7 @@ table! { | ||||
|         akey -> Text, | ||||
|         status -> Integer, | ||||
|         atype -> Integer, | ||||
|         reset_password_key -> Nullable<Text>, | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -222,6 +222,7 @@ table! { | ||||
|         akey -> Text, | ||||
|         status -> Integer, | ||||
|         atype -> Integer, | ||||
|         reset_password_key -> Nullable<Text>, | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										13
									
								
								src/mail.rs
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								src/mail.rs
									
									
									
									
									
								
							| @@ -496,6 +496,19 @@ pub async fn send_test(address: &str) -> EmptyResult { | ||||
|     send_email(address, &subject, body_html, body_text).await | ||||
| } | ||||
|  | ||||
| pub async fn send_admin_reset_password(address: &str, user_name: &str, org_name: &str) -> EmptyResult { | ||||
|     let (subject, body_html, body_text) = get_text( | ||||
|         "email/admin_reset_password", | ||||
|         json!({ | ||||
|             "url": CONFIG.domain(), | ||||
|             "img_src": CONFIG._smtp_img_src(), | ||||
|             "user_name": user_name, | ||||
|             "org_name": org_name, | ||||
|         }), | ||||
|     )?; | ||||
|     send_email(address, &subject, body_html, body_text).await | ||||
| } | ||||
|  | ||||
| async fn send_email(address: &str, subject: &str, body_html: String, body_text: String) -> EmptyResult { | ||||
|     let smtp_from = &CONFIG.smtp_from(); | ||||
|  | ||||
|   | ||||
| @@ -47,7 +47,7 @@ | ||||
|                             <div class="row my-2 align-items-center pt-3 border-top" title="Send a test email to given email address"> | ||||
|                                 <label for="smtp-test-email" class="col-sm-3 col-form-label">Test SMTP</label> | ||||
|                                 <div class="col-sm-8 input-group"> | ||||
|                                     <input class="form-control" id="smtp-test-email" type="email" placeholder="Enter test email" required> | ||||
|                                     <input class="form-control" id="smtp-test-email" type="email" placeholder="Enter test email" required spellcheck="false"> | ||||
|                                     <button type="button" class="btn btn-outline-primary input-group-text" id="smtpTest">Send test email</button> | ||||
|                                     <div class="invalid-tooltip">Please provide a valid email address</div> | ||||
|                                 </div> | ||||
| @@ -85,7 +85,7 @@ | ||||
|                                     <input readonly class="form-control" id="input_{{name}}" type="password" value="{{value}}" {{#if default}} placeholder="Default: {{default}}" {{/if}}> | ||||
|                                     <button class="btn btn-outline-secondary" type="button" data-vw-pw-toggle="input_{{name}}">Show/hide</button> | ||||
|                                 {{else}} | ||||
|                                     <input readonly class="form-control" id="input_{{name}}" type="{{type}}" value="{{value}}" {{#if default}} placeholder="Default: {{default}}" {{/if}}> | ||||
|                                     <input readonly class="form-control" id="input_{{name}}" type="{{type}}" value="{{value}}" {{#if default}} placeholder="Default: {{default}}" {{/if}} spellcheck="false"> | ||||
|                                     {{#case type "password"}} | ||||
|                                     <button class="btn btn-outline-secondary" type="button" data-vw-pw-toggle="input_{{name}}">Show/hide</button> | ||||
|                                     {{/case}} | ||||
|   | ||||
| @@ -96,7 +96,7 @@ | ||||
|             <small>Email:</small> | ||||
|  | ||||
|             <form class="form-inline input-group w-50" id="inviteUserForm"> | ||||
|                 <input type="email" class="form-control me-2" id="inviteEmail" placeholder="Enter email" required> | ||||
|                 <input type="email" class="form-control me-2" id="inviteEmail" placeholder="Enter email" required spellcheck="false"> | ||||
|                 <button type="submit" class="btn btn-primary">Invite</button> | ||||
|             </form> | ||||
|         </div> | ||||
|   | ||||
							
								
								
									
										6
									
								
								src/static/templates/email/admin_reset_password.hbs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/static/templates/email/admin_reset_password.hbs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| Master Password Has Been Changed | ||||
| <!----------------> | ||||
| The master password for {{user_name}} has been changed by an administrator in your {{org_name}} organization. If you did not initiate this request, please reach out to your administrator immediately. | ||||
|  | ||||
| === | ||||
| Github: https://github.com/dani-garcia/vaultwarden | ||||
							
								
								
									
										11
									
								
								src/static/templates/email/admin_reset_password.html.hbs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/static/templates/email/admin_reset_password.html.hbs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| Master Password Has Been Changed | ||||
| <!----------------> | ||||
| {{> email/email_header }} | ||||
| <table width="100%" cellpadding="0" cellspacing="0" style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;"> | ||||
|     <tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;"> | ||||
|         <td class="content-block" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0 0 10px; -webkit-text-size-adjust: none;" valign="top"> | ||||
|             The master password for <b style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">{{user_name}}</b> has been changed by an administrator in your <b style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">{{org_name}}</b> organization. If you did not initiate this request, please reach out to your administrator immediately. | ||||
|         </td> | ||||
|     </tr> | ||||
| </table> | ||||
| {{> email/email_footer }} | ||||
		Reference in New Issue
	
	Block a user