From 20535065d752300104f2831dfa88c2ec3e6edb82 Mon Sep 17 00:00:00 2001 From: BlackDex Date: Sat, 28 Aug 2021 17:29:13 +0200 Subject: [PATCH 01/68] Build Docker Hub images via Github Actions Since docker hub stopped Autobuild, we need to switch to something else. This will trigger building of images on Github Actions and pushes them to Docker Hub. You only need to add 3 secrets before you merge this PR to have it working directly. - DOCKERHUB_USERNAME : The username of the account you are going to push the builds to - DOCKERHUB_TOKEN : The token needed to login and push builds - DOCKERHUB_REPO : The repo name in the following form `index.docker.io//` So for vaultwarden that would be `index.docker.io/vaultwarden/server` Also some small modifications to the other workflows. --- .github/workflows/build.yml | 45 +++++--------- .github/workflows/hadolint.yml | 5 +- .github/workflows/release.yml | 105 +++++++++++++++++++++++++++++++++ hooks/push | 12 +++- 4 files changed, 133 insertions(+), 34 deletions(-) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 26fcb663..0f80b950 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,36 +2,23 @@ name: Build on: push: - paths-ignore: - - "*.md" - - "*.txt" - - ".dockerignore" - - ".env.template" - - ".gitattributes" - - ".gitignore" - - "azure-pipelines.yml" - - "docker/**" - - "hooks/**" - - "tools/**" - - ".github/FUNDING.yml" - - ".github/ISSUE_TEMPLATE/**" - - ".github/security-contact.gif" + paths: + - ".github/workflows/build.yml" + - "src/**" + - "migrations/**" + - "Cargo.*" + - "build.rs" + - "diesel.toml" + - "rust-toolchain" pull_request: - # Ignore when there are only changes done too one of these paths - paths-ignore: - - "*.md" - - "*.txt" - - ".dockerignore" - - ".env.template" - - ".gitattributes" - - ".gitignore" - - "azure-pipelines.yml" - - "docker/**" - - "hooks/**" - - "tools/**" - - ".github/FUNDING.yml" - - ".github/ISSUE_TEMPLATE/**" - - ".github/security-contact.gif" + paths: + - ".github/workflows/build.yml" + - "src/**" + - "migrations/**" + - "Cargo.*" + - "build.rs" + - "diesel.toml" + - "rust-toolchain" jobs: build: diff --git a/.github/workflows/hadolint.yml b/.github/workflows/hadolint.yml index 36406cb8..3a766c89 100644 --- a/.github/workflows/hadolint.yml +++ b/.github/workflows/hadolint.yml @@ -2,11 +2,10 @@ name: Hadolint on: push: - # Ignore when there are only changes done too one of these paths paths: - "docker/**" + pull_request: - # Ignore when there are only changes done too one of these paths paths: - "docker/**" @@ -28,7 +27,7 @@ jobs: sudo curl -L https://github.com/hadolint/hadolint/releases/download/v${HADOLINT_VERSION}/hadolint-$(uname -s)-$(uname -m) -o /usr/local/bin/hadolint && \ sudo chmod +x /usr/local/bin/hadolint env: - HADOLINT_VERSION: 2.6.1 + HADOLINT_VERSION: 2.7.0 # End Download hadolint # Test Dockerfiles diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..3e8b9607 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,105 @@ +name: Release + +on: + push: + paths: + - ".github/workflows/release.yml" + - "src/**" + - "migrations/**" + - "hooks/**" + - "docker/**" + - "Cargo.*" + - "build.rs" + - "diesel.toml" + - "rust-toolchain" + + branches: # Only on paths above + - main + + tags: # Always, regardless of paths above + - '*' + +jobs: + # https://github.com/marketplace/actions/skip-duplicate-actions + # Some checks to determine if we need to continue with building a new docker. + # We will skip this check if we are creating a tag, because that has the same hash as a previous run already. + skip_check: + runs-on: ubuntu-latest + if: ${{ github.repository == 'dani-garcia/vaultwarden' }} + outputs: + should_skip: ${{ steps.skip_check.outputs.should_skip }} + steps: + - name: Skip Duplicates Actions + id: skip_check + uses: fkirc/skip-duplicate-actions@master + with: + cancel_others: 'true' + # Only run this when not creating a tag + if: ${{ startsWith(github.ref, 'refs/heads/') }} + + docker-build: + runs-on: ubuntu-latest + needs: skip_check + if: ${{ needs.skip_check.outputs.should_skip != 'true' }} + env: + # DOCKER_BUILDKIT: 1 # Disabled for now, but we should look at this because it will speedup building! + # DOCKER_REPO/secrets.DOCKERHUB_REPO needs to be 'index.docker.io//' + DOCKER_REPO: ${{ secrets.DOCKERHUB_REPO }} + SOURCE_COMMIT: ${{ github.sha }} + SOURCE_REPOSITORY_URL: "https://github.com/${{ github.repository }}" + steps: + # Checkout the repo + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + # Login to Docker Hub + - name: Login to Docker Hub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + # Determine Docker Tag + - name: Init Variables + id: vars + shell: bash + run: | + # Check which main tag we are going to build determined by github.ref + if [[ "${{ github.ref }}" == refs/tags/* ]]; then + echo "set-output name=DOCKER_TAG::${GITHUB_REF#refs/*/}" + echo "::set-output name=DOCKER_TAG::${GITHUB_REF#refs/*/}" + elif [[ "${{ github.ref }}" == refs/heads/* ]]; then + echo "set-output name=DOCKER_TAG::testing" + echo "::set-output name=DOCKER_TAG::testing" + fi + # End Determine Docker Tag + + - name: Build Debian based images + shell: bash + env: + DOCKER_TAG: ${{steps.vars.outputs.DOCKER_TAG}} + run: | + ./hooks/build + + - name: Push Debian based images + shell: bash + env: + DOCKER_TAG: ${{steps.vars.outputs.DOCKER_TAG}} + run: | + ./hooks/push + + - name: Build Alpine based images + shell: bash + env: + DOCKER_TAG: "${{steps.vars.outputs.DOCKER_TAG}}-alpine" + run: | + ./hooks/build + + - name: Push Alpine based images + shell: bash + env: + DOCKER_TAG: "${{steps.vars.outputs.DOCKER_TAG}}-alpine" + run: | + ./hooks/push diff --git a/hooks/push b/hooks/push index f50e48b9..4c690eb0 100755 --- a/hooks/push +++ b/hooks/push @@ -25,7 +25,10 @@ echo ">>> Starting local Docker registry..." # Use host networking so the buildx container can access the registry via # localhost. # -docker run -d --name registry --network host registry:2 # defaults to port 5000 +# First check if there already is a registry container running, else skip it. +# This will only happen either locally or running it via Github Actions +# +docker start registry > /dev/null 2>&1 || docker run -d --name registry --network host registry:2 # defaults to port 5000 # Docker Hub sets a `DOCKER_REPO` env var with the format `index.docker.io/user/repo`. # Strip the registry portion to construct a local repo path for use in `Dockerfile.buildx`. @@ -49,7 +52,12 @@ echo ">>> Setting up Docker Buildx..." # # Ref: https://github.com/docker/buildx/issues/94#issuecomment-534367714 # -docker buildx create --name builder --use --driver-opt network=host +# Check if there already is a builder running, else skip this and use the existing. +# This will only happen either locally or running it via Github Actions +# +if ! docker buildx inspect builder > /dev/null 2>&1 ; then + docker buildx create --name builder --use --driver-opt network=host +fi echo ">>> Running Docker Buildx..." From 0cdc0cb147e39a382a1e8345191f19ac69df6217 Mon Sep 17 00:00:00 2001 From: Jeremy Lin Date: Sun, 29 Aug 2021 15:35:25 -0700 Subject: [PATCH 02/68] Fix incorrect WebAuthn origin This mainly affects users running Vaultwarden under a subpath. Refs: * https://github.com/kanidm/webauthn-rs/blob/b2cbb34/src/core.rs#L941-L948 * https://github.com/kanidm/webauthn-rs/blob/b2cbb34/src/core.rs#L316 * https://w3c.github.io/webauthn/#dictionary-client-data --- src/api/core/two_factor/webauthn.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/api/core/two_factor/webauthn.rs b/src/api/core/two_factor/webauthn.rs index 03daf43b..1730d4f0 100644 --- a/src/api/core/two_factor/webauthn.rs +++ b/src/api/core/two_factor/webauthn.rs @@ -22,12 +22,14 @@ pub fn routes() -> Vec { struct WebauthnConfig { url: String, + origin: String, rpid: String, } impl WebauthnConfig { fn load() -> Webauthn { let domain = CONFIG.domain(); + let domain_origin = CONFIG.domain_origin(); Webauthn::new(Self { rpid: reqwest::Url::parse(&domain) .map(|u| u.domain().map(str::to_owned)) @@ -35,6 +37,7 @@ impl WebauthnConfig { .flatten() .unwrap_or_default(), url: domain, + origin: domain_origin, }) } } @@ -45,7 +48,7 @@ impl webauthn_rs::WebauthnConfig for WebauthnConfig { } fn get_origin(&self) -> &str { - &self.url + &self.origin } fn get_relying_party_id(&self) -> &str { From 4350e9d24132be04cdf90ed6ed3db11e9d665df2 Mon Sep 17 00:00:00 2001 From: Jeremy Lin Date: Sat, 4 Sep 2021 00:47:06 -0700 Subject: [PATCH 03/68] Update Debian base images to bullseye --- docker/Dockerfile.j2 | 10 +++++----- docker/amd64/Dockerfile | 4 ++-- docker/arm64/Dockerfile | 4 ++-- docker/armv6/Dockerfile | 4 ++-- docker/armv7/Dockerfile | 4 ++-- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docker/Dockerfile.j2 b/docker/Dockerfile.j2 index 52109775..1fc83996 100644 --- a/docker/Dockerfile.j2 +++ b/docker/Dockerfile.j2 @@ -1,7 +1,7 @@ # This file was generated using a Jinja2 template. # Please make your changes in `Dockerfile.j2` and then `make` the individual Dockerfiles. -{% set build_stage_base_image = "rust:1.54" %} +{% set build_stage_base_image = "rust:1.54-bullseye" %} {% if "alpine" in target_file %} {% if "amd64" in target_file %} {% set build_stage_base_image = "clux/muslrust:nightly-2021-08-22" %} @@ -13,19 +13,19 @@ {% set package_arch_target = "armv7-unknown-linux-musleabihf" %} {% endif %} {% elif "amd64" in target_file %} -{% set runtime_stage_base_image = "debian:buster-slim" %} +{% set runtime_stage_base_image = "debian:bullseye-slim" %} {% elif "arm64" in target_file %} -{% set runtime_stage_base_image = "balenalib/aarch64-debian:buster" %} +{% set runtime_stage_base_image = "balenalib/aarch64-debian:bullseye" %} {% set package_arch_name = "arm64" %} {% set package_arch_target = "aarch64-unknown-linux-gnu" %} {% set package_cross_compiler = "aarch64-linux-gnu" %} {% elif "armv6" in target_file %} -{% set runtime_stage_base_image = "balenalib/rpi-debian:buster" %} +{% set runtime_stage_base_image = "balenalib/rpi-debian:bullseye" %} {% set package_arch_name = "armel" %} {% set package_arch_target = "arm-unknown-linux-gnueabi" %} {% set package_cross_compiler = "arm-linux-gnueabi" %} {% elif "armv7" in target_file %} -{% set runtime_stage_base_image = "balenalib/armv7hf-debian:buster" %} +{% set runtime_stage_base_image = "balenalib/armv7hf-debian:bullseye" %} {% set package_arch_name = "armhf" %} {% set package_arch_target = "armv7-unknown-linux-gnueabihf" %} {% set package_cross_compiler = "arm-linux-gnueabihf" %} diff --git a/docker/amd64/Dockerfile b/docker/amd64/Dockerfile index 1c067c11..8f448ccc 100644 --- a/docker/amd64/Dockerfile +++ b/docker/amd64/Dockerfile @@ -25,7 +25,7 @@ FROM vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5 as vault ########################## BUILD IMAGE ########################## -FROM rust:1.54 as build +FROM rust:1.54-bullseye as build # Debian-based builds support multidb ARG DB=sqlite,mysql,postgresql @@ -73,7 +73,7 @@ RUN cargo build --features ${DB} --release ######################## RUNTIME IMAGE ######################## # Create a new stage with a minimal image # because we already have a binary built -FROM debian:buster-slim +FROM debian:bullseye-slim ENV ROCKET_ENV "staging" ENV ROCKET_PORT=80 diff --git a/docker/arm64/Dockerfile b/docker/arm64/Dockerfile index 2358568d..ddda4f98 100644 --- a/docker/arm64/Dockerfile +++ b/docker/arm64/Dockerfile @@ -25,7 +25,7 @@ FROM vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5 as vault ########################## BUILD IMAGE ########################## -FROM rust:1.54 as build +FROM rust:1.54-bullseye as build # Debian-based builds support multidb ARG DB=sqlite,mysql,postgresql @@ -109,7 +109,7 @@ 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 -FROM balenalib/aarch64-debian:buster +FROM balenalib/aarch64-debian:bullseye ENV ROCKET_ENV "staging" ENV ROCKET_PORT=80 diff --git a/docker/armv6/Dockerfile b/docker/armv6/Dockerfile index 4511c69e..1935517f 100644 --- a/docker/armv6/Dockerfile +++ b/docker/armv6/Dockerfile @@ -25,7 +25,7 @@ FROM vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5 as vault ########################## BUILD IMAGE ########################## -FROM rust:1.54 as build +FROM rust:1.54-bullseye as build # Debian-based builds support multidb ARG DB=sqlite,mysql,postgresql @@ -109,7 +109,7 @@ 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 -FROM balenalib/rpi-debian:buster +FROM balenalib/rpi-debian:bullseye ENV ROCKET_ENV "staging" ENV ROCKET_PORT=80 diff --git a/docker/armv7/Dockerfile b/docker/armv7/Dockerfile index 04cd92f1..9172b90e 100644 --- a/docker/armv7/Dockerfile +++ b/docker/armv7/Dockerfile @@ -25,7 +25,7 @@ FROM vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5 as vault ########################## BUILD IMAGE ########################## -FROM rust:1.54 as build +FROM rust:1.54-bullseye as build # Debian-based builds support multidb ARG DB=sqlite,mysql,postgresql @@ -109,7 +109,7 @@ RUN cargo build --features ${DB} --release --target=armv7-unknown-linux-gnueabih ######################## RUNTIME IMAGE ######################## # Create a new stage with a minimal image # because we already have a binary built -FROM balenalib/armv7hf-debian:buster +FROM balenalib/armv7hf-debian:bullseye ENV ROCKET_ENV "staging" ENV ROCKET_PORT=80 From 80f23e6d78d24c166ebf28a48a02815aac38b1e1 Mon Sep 17 00:00:00 2001 From: Jeremy Lin Date: Wed, 8 Sep 2021 23:26:15 -0700 Subject: [PATCH 04/68] Enforce Personal Ownership policy on imports Upstream PR: https://github.com/bitwarden/server/pull/1565 --- src/api/core/ciphers.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs index e4e8491f..b5a9737a 100644 --- a/src/api/core/ciphers.rs +++ b/src/api/core/ciphers.rs @@ -248,7 +248,7 @@ fn post_ciphers_create(data: JsonUpcase, headers: Headers, conn // This check is usually only needed in update_cipher_from_data(), but we // need it here as well to avoid creating an empty cipher in the call to // cipher.save() below. - enforce_personal_ownership_policy(&data.Cipher, &headers, &conn)?; + enforce_personal_ownership_policy(Some(&data.Cipher), &headers, &conn)?; let mut cipher = Cipher::new(data.Cipher.Type, data.Cipher.Name.clone()); cipher.user_uuid = Some(headers.user.uuid.clone()); @@ -289,8 +289,8 @@ fn post_ciphers(data: JsonUpcase, headers: Headers, conn: DbConn, nt /// allowed to delete or share such ciphers to an org, however. /// /// Ref: https://bitwarden.com/help/article/policies/#personal-ownership -fn enforce_personal_ownership_policy(data: &CipherData, headers: &Headers, conn: &DbConn) -> EmptyResult { - if data.OrganizationId.is_none() { +fn enforce_personal_ownership_policy(data: Option<&CipherData>, headers: &Headers, conn: &DbConn) -> EmptyResult { + if data.is_none() || data.unwrap().OrganizationId.is_none() { let user_uuid = &headers.user.uuid; let policy_type = OrgPolicyType::PersonalOwnership; if OrgPolicy::is_applicable_to_user(user_uuid, policy_type, conn) { @@ -309,7 +309,7 @@ pub fn update_cipher_from_data( nt: &Notify, ut: UpdateType, ) -> EmptyResult { - enforce_personal_ownership_policy(&data, headers, conn)?; + enforce_personal_ownership_policy(Some(&data), headers, conn)?; // Check that the client isn't updating an existing cipher with stale data. if let Some(dt) = data.LastKnownRevisionDate { @@ -458,6 +458,8 @@ struct RelationsData { #[post("/ciphers/import", data = "")] fn post_ciphers_import(data: JsonUpcase, headers: Headers, conn: DbConn, nt: Notify) -> EmptyResult { + enforce_personal_ownership_policy(None, &headers, &conn)?; + let data: ImportData = data.into_inner().data; // Read and create the folders From 10d5c7738afad9f81958e24baa923530314a587f Mon Sep 17 00:00:00 2001 From: BlackDex Date: Thu, 9 Sep 2021 13:50:18 +0200 Subject: [PATCH 05/68] Fix issue when using uppercase chars in emails In the case when SMTP is disabled and. when inviting new users either via the admin interface or into an organization and using uppercase letters, this would fail for those users to be able to register since the checks which were done are case-sensitive and never matched. This PR fixes that issue by ensuring everything is lowercase. Fixes #1963 --- src/api/admin.rs | 2 +- src/api/core/accounts.rs | 17 +++++++++-------- src/api/core/organizations.rs | 7 ++++--- src/db/models/user.rs | 7 ++++--- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/api/admin.rs b/src/api/admin.rs index 46e39502..3fe4f947 100644 --- a/src/api/admin.rs +++ b/src/api/admin.rs @@ -269,7 +269,7 @@ fn invite_user(data: Json, _token: AdminToken, conn: DbConn) -> Json if CONFIG.mail_enabled() { mail::send_invite(&user.email, &user.uuid, None, None, &CONFIG.invitation_org_name(), None)?; } else { - let invitation = Invitation::new(data.email); + let invitation = Invitation::new(user.email.clone()); invitation.save(&conn)?; } diff --git a/src/api/core/accounts.rs b/src/api/core/accounts.rs index a38a496b..ee97e82f 100644 --- a/src/api/core/accounts.rs +++ b/src/api/core/accounts.rs @@ -62,11 +62,12 @@ struct KeysData { #[post("/accounts/register", data = "")] fn register(data: JsonUpcase, conn: DbConn) -> EmptyResult { let data: RegisterData = data.into_inner().data; + let email = data.Email.to_lowercase(); - let mut user = match User::find_by_mail(&data.Email, &conn) { + let mut user = match User::find_by_mail(&email, &conn) { Some(user) => { if !user.password_hash.is_empty() { - if CONFIG.is_signup_allowed(&data.Email) { + if CONFIG.is_signup_allowed(&email) { err!("User already exists") } else { err!("Registration not allowed or user already exists") @@ -75,19 +76,19 @@ fn register(data: JsonUpcase, conn: DbConn) -> EmptyResult { if let Some(token) = data.Token { let claims = decode_invite(&token)?; - if claims.email == data.Email { + if claims.email == email { user } else { err!("Registration email does not match invite email") } - } else if Invitation::take(&data.Email, &conn) { + } else if Invitation::take(&email, &conn) { for mut user_org in UserOrganization::find_invited_by_user(&user.uuid, &conn).iter_mut() { user_org.status = UserOrgStatus::Accepted as i32; user_org.save(&conn)?; } user - } else if CONFIG.is_signup_allowed(&data.Email) { + } else if CONFIG.is_signup_allowed(&email) { err!("Account with this email already exists") } else { err!("Registration not allowed or user already exists") @@ -97,8 +98,8 @@ fn register(data: JsonUpcase, conn: DbConn) -> EmptyResult { // Order is important here; the invitation check must come first // because the vaultwarden admin can invite anyone, regardless // of other signup restrictions. - if Invitation::take(&data.Email, &conn) || CONFIG.is_signup_allowed(&data.Email) { - User::new(data.Email.clone()) + if Invitation::take(&email, &conn) || CONFIG.is_signup_allowed(&email) { + User::new(email.clone()) } else { err!("Registration not allowed or user already exists") } @@ -106,7 +107,7 @@ fn register(data: JsonUpcase, conn: DbConn) -> EmptyResult { }; // Make sure we don't leave a lingering invitation. - Invitation::take(&data.Email, &conn); + Invitation::take(&email, &conn); if let Some(client_kdf_iter) = data.KdfIterations { user.client_kdf_iter = client_kdf_iter; diff --git a/src/api/core/organizations.rs b/src/api/core/organizations.rs index c1d2326c..fe8dab10 100644 --- a/src/api/core/organizations.rs +++ b/src/api/core/organizations.rs @@ -540,18 +540,19 @@ fn send_invite(org_id: String, data: JsonUpcase, headers: AdminHeade } for email in data.Emails.iter() { + let email = email.to_lowercase(); let mut user_org_status = if CONFIG.mail_enabled() { UserOrgStatus::Invited as i32 } else { UserOrgStatus::Accepted as i32 // Automatically mark user as accepted if no email invites }; - let user = match User::find_by_mail(email, &conn) { + let user = match User::find_by_mail(&email, &conn) { None => { if !CONFIG.invitations_allowed() { err!(format!("User does not exist: {}", email)) } - if !CONFIG.is_email_domain_allowed(email) { + if !CONFIG.is_email_domain_allowed(&email) { err!("Email domain not eligible for invitations") } @@ -601,7 +602,7 @@ fn send_invite(org_id: String, data: JsonUpcase, headers: AdminHeade }; mail::send_invite( - email, + &email, &user.uuid, Some(org_id.clone()), Some(new_user.uuid), diff --git a/src/db/models/user.rs b/src/db/models/user.rs index fb7d5fcd..3c2120e1 100644 --- a/src/db/models/user.rs +++ b/src/db/models/user.rs @@ -73,9 +73,9 @@ impl User { pub const CLIENT_KDF_TYPE_DEFAULT: i32 = 0; // PBKDF2: 0 pub const CLIENT_KDF_ITER_DEFAULT: i32 = 100_000; - pub fn new(mail: String) -> Self { + pub fn new(email: String) -> Self { let now = Utc::now().naive_utc(); - let email = mail.to_lowercase(); + let email = email.to_lowercase(); Self { uuid: crate::util::get_uuid(), @@ -349,7 +349,8 @@ impl User { } impl Invitation { - pub const fn new(email: String) -> Self { + pub fn new(email: String) -> Self { + let email = email.to_lowercase(); Self { email, } From ca0fd7a31b724d06ba4eca203bfeda9e38c5e767 Mon Sep 17 00:00:00 2001 From: BlackDex Date: Mon, 13 Sep 2021 12:00:52 +0200 Subject: [PATCH 06/68] Optimize release workflow. - Split Debian and Alpine into different build matrix This starts building both Debian and Alpine based images at the same time - Make use of Docker BuildKit, which improves speed also. - Use BuildKit caching for Rust Cargo across docker images. This prevents downloading the same crates multiple times. - Use Github Actions Services to start a docker registry, starting it via the build script sometimes caused issues. - Updated the Build workflow to use Ubuntu 20.04 which is more close to the Bullseye Debian release regarding package versions. --- .github/workflows/build.yml | 45 ++----- .github/workflows/hadolint.yml | 2 +- .github/workflows/release.yml | 28 +++-- docker/Dockerfile.j2 | 109 ++++++++++------- docker/Makefile | 6 + docker/amd64/Dockerfile | 26 ++-- docker/amd64/Dockerfile.alpine | 16 ++- docker/amd64/Dockerfile.buildx | 126 +++++++++++++++++++ docker/amd64/Dockerfile.buildx.alpine | 118 ++++++++++++++++++ docker/arm64/Dockerfile | 75 +++++++----- docker/arm64/Dockerfile.buildx | 169 ++++++++++++++++++++++++++ docker/armv6/Dockerfile | 75 +++++++----- docker/armv6/Dockerfile.buildx | 169 ++++++++++++++++++++++++++ docker/armv7/Dockerfile | 75 +++++++----- docker/armv7/Dockerfile.alpine | 16 ++- docker/armv7/Dockerfile.buildx | 169 ++++++++++++++++++++++++++ docker/armv7/Dockerfile.buildx.alpine | 125 +++++++++++++++++++ hooks/build | 7 +- hooks/push | 7 +- 19 files changed, 1170 insertions(+), 193 deletions(-) create mode 100644 docker/amd64/Dockerfile.buildx create mode 100644 docker/amd64/Dockerfile.buildx.alpine create mode 100644 docker/arm64/Dockerfile.buildx create mode 100644 docker/armv6/Dockerfile.buildx create mode 100644 docker/armv7/Dockerfile.buildx create mode 100644 docker/armv7/Dockerfile.buildx.alpine diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0f80b950..f92e6e54 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -31,30 +31,22 @@ jobs: matrix: channel: - nightly - # - stable target-triple: - x86_64-unknown-linux-gnu - # - x86_64-unknown-linux-musl include: - target-triple: x86_64-unknown-linux-gnu host-triple: x86_64-unknown-linux-gnu features: [sqlite,mysql,postgresql] # Remember to update the `cargo test` to match the amount of features channel: nightly - os: ubuntu-18.04 + os: ubuntu-20.04 ext: "" - # - target-triple: x86_64-unknown-linux-gnu - # host-triple: x86_64-unknown-linux-gnu - # features: "sqlite,mysql,postgresql" - # channel: stable - # os: ubuntu-18.04 - # ext: "" name: Building ${{ matrix.channel }}-${{ matrix.target-triple }} runs-on: ${{ matrix.os }} steps: # Checkout the repo - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4 # End Checkout the repo @@ -73,13 +65,13 @@ jobs: # Enable Rust Caching - - uses: Swatinem/rust-cache@v1 + - uses: Swatinem/rust-cache@842ef286fff290e445b90b4002cc9807c3669641 # v1.3.0 # End Enable Rust Caching # Uses the rust-toolchain file to determine version - name: 'Install ${{ matrix.channel }}-${{ matrix.host-triple }} for target: ${{ matrix.target-triple }}' - uses: actions-rs/toolchain@v1 + uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f # v1.0.6 with: profile: minimal target: ${{ matrix.target-triple }} @@ -90,28 +82,28 @@ jobs: # Run cargo tests (In release mode to speed up future builds) # First test all features together, afterwards test them separately. - name: "`cargo test --release --features ${{ join(matrix.features, ',') }} --target ${{ matrix.target-triple }}`" - uses: actions-rs/cargo@v1 + uses: actions-rs/cargo@ae10961054e4aa8b4aa7dffede299aaf087aa33b # v1.0.1 with: command: test args: --release --features ${{ join(matrix.features, ',') }} --target ${{ matrix.target-triple }} # Test single features # 0: sqlite - name: "`cargo test --release --features ${{ matrix.features[0] }} --target ${{ matrix.target-triple }}`" - uses: actions-rs/cargo@v1 + uses: actions-rs/cargo@ae10961054e4aa8b4aa7dffede299aaf087aa33b # v1.0.1 with: command: test args: --release --features ${{ matrix.features[0] }} --target ${{ matrix.target-triple }} if: ${{ matrix.features[0] != '' }} # 1: mysql - name: "`cargo test --release --features ${{ matrix.features[1] }} --target ${{ matrix.target-triple }}`" - uses: actions-rs/cargo@v1 + uses: actions-rs/cargo@ae10961054e4aa8b4aa7dffede299aaf087aa33b # v1.0.1 with: command: test args: --release --features ${{ matrix.features[1] }} --target ${{ matrix.target-triple }} if: ${{ matrix.features[1] != '' }} # 2: postgresql - name: "`cargo test --release --features ${{ matrix.features[2] }} --target ${{ matrix.target-triple }}`" - uses: actions-rs/cargo@v1 + uses: actions-rs/cargo@ae10961054e4aa8b4aa7dffede299aaf087aa33b # v1.0.1 with: command: test args: --release --features ${{ matrix.features[2] }} --target ${{ matrix.target-triple }} @@ -121,7 +113,7 @@ jobs: # Run cargo clippy, and fail on warnings (In release mode to speed up future builds) - name: "`cargo clippy --release --features ${{ join(matrix.features, ',') }} --target ${{ matrix.target-triple }}`" - uses: actions-rs/cargo@v1 + uses: actions-rs/cargo@ae10961054e4aa8b4aa7dffede299aaf087aa33b # v1.0.1 with: command: clippy args: --release --features ${{ join(matrix.features, ',') }} --target ${{ matrix.target-triple }} -- -D warnings @@ -130,7 +122,7 @@ jobs: # Run cargo fmt - name: '`cargo fmt`' - uses: actions-rs/cargo@v1 + uses: actions-rs/cargo@ae10961054e4aa8b4aa7dffede299aaf087aa33b # v1.0.1 with: command: fmt args: --all -- --check @@ -139,7 +131,7 @@ jobs: # Build the binary - name: "`cargo build --release --features ${{ join(matrix.features, ',') }} --target ${{ matrix.target-triple }}`" - uses: actions-rs/cargo@v1 + uses: actions-rs/cargo@ae10961054e4aa8b4aa7dffede299aaf087aa33b # v1.0.1 with: command: build args: --release --features ${{ join(matrix.features, ',') }} --target ${{ matrix.target-triple }} @@ -148,21 +140,8 @@ jobs: # Upload artifact to Github Actions - name: Upload artifact - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@27121b0bdffd731efa15d66772be8dc71245d074 # v2.2.4 with: name: vaultwarden-${{ matrix.target-triple }}${{ matrix.ext }} path: target/${{ matrix.target-triple }}/release/vaultwarden${{ matrix.ext }} # End Upload artifact to Github Actions - - - ## This is not used at the moment - ## We could start using this when we can build static binaries - # Upload to github actions release - # - name: Release - # uses: Shopify/upload-to-release@1 - # if: startsWith(github.ref, 'refs/tags/') - # with: - # name: vaultwarden-${{ matrix.target-triple }}${{ matrix.ext }} - # path: target/${{ matrix.target-triple }}/release/vaultwarden${{ matrix.ext }} - # repo-token: ${{ secrets.GITHUB_TOKEN }} - # End Upload to github actions release diff --git a/.github/workflows/hadolint.yml b/.github/workflows/hadolint.yml index 3a766c89..375e437a 100644 --- a/.github/workflows/hadolint.yml +++ b/.github/workflows/hadolint.yml @@ -16,7 +16,7 @@ jobs: steps: # Checkout the repo - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4 # End Checkout the repo diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3e8b9607..4b425c01 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,7 +31,7 @@ jobs: steps: - name: Skip Duplicates Actions id: skip_check - uses: fkirc/skip-duplicate-actions@master + uses: fkirc/skip-duplicate-actions@f75dd6564bb646f95277dc8c3b80612e46a4a1ea # v3.4.1 with: cancel_others: 'true' # Only run this when not creating a tag @@ -40,23 +40,33 @@ jobs: docker-build: runs-on: ubuntu-latest needs: skip_check - if: ${{ needs.skip_check.outputs.should_skip != 'true' }} + # Start a local docker registry to be used to generate multi-arch images. + services: + registry: + image: registry:2 + ports: + - 5000:5000 env: - # DOCKER_BUILDKIT: 1 # Disabled for now, but we should look at this because it will speedup building! + DOCKER_BUILDKIT: 1 # Disabled for now, but we should look at this because it will speedup building! # DOCKER_REPO/secrets.DOCKERHUB_REPO needs to be 'index.docker.io//' DOCKER_REPO: ${{ secrets.DOCKERHUB_REPO }} SOURCE_COMMIT: ${{ github.sha }} SOURCE_REPOSITORY_URL: "https://github.com/${{ github.repository }}" + if: ${{ needs.skip_check.outputs.should_skip != 'true' && github.repository == 'dani-garcia/vaultwarden' }} + strategy: + matrix: + base_image: ["debian","alpine"] + steps: # Checkout the repo - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4 with: fetch-depth: 0 # Login to Docker Hub - name: Login to Docker Hub - uses: docker/login-action@v1 + uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 # v1.10.0 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} @@ -79,16 +89,18 @@ jobs: - name: Build Debian based images shell: bash env: - DOCKER_TAG: ${{steps.vars.outputs.DOCKER_TAG}} + DOCKER_TAG: "${{steps.vars.outputs.DOCKER_TAG}}" run: | ./hooks/build + if: ${{ matrix.base_image == 'debian' }} - name: Push Debian based images shell: bash env: - DOCKER_TAG: ${{steps.vars.outputs.DOCKER_TAG}} + DOCKER_TAG: "${{steps.vars.outputs.DOCKER_TAG}}" run: | ./hooks/push + if: ${{ matrix.base_image == 'debian' }} - name: Build Alpine based images shell: bash @@ -96,6 +108,7 @@ jobs: DOCKER_TAG: "${{steps.vars.outputs.DOCKER_TAG}}-alpine" run: | ./hooks/build + if: ${{ matrix.base_image == 'alpine' }} - name: Push Alpine based images shell: bash @@ -103,3 +116,4 @@ jobs: DOCKER_TAG: "${{steps.vars.outputs.DOCKER_TAG}}-alpine" run: | ./hooks/push + if: ${{ matrix.base_image == 'alpine' }} diff --git a/docker/Dockerfile.j2 b/docker/Dockerfile.j2 index 1fc83996..2a849a5b 100644 --- a/docker/Dockerfile.j2 +++ b/docker/Dockerfile.j2 @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1 + # This file was generated using a Jinja2 template. # Please make your changes in `Dockerfile.j2` and then `make` the individual Dockerfiles. @@ -40,6 +42,11 @@ {% else %} {% set package_arch_target_param = "" %} {% endif %} +{% if "buildx" 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 = "" %} +{% endif %} # Using multistage build: # https://docs.docker.com/develop/develop-images/multistage-build/ # https://whitfin.io/speeding-up-rust-docker-builds/ @@ -86,22 +93,39 @@ ARG DB=sqlite,mysql,postgresql {% endif %} # Build time options to avoid dpkg warnings and help with reproducible builds. -ENV DEBIAN_FRONTEND=noninteractive LANG=C.UTF-8 TZ=UTC TERM=xterm-256color +ENV DEBIAN_FRONTEND=noninteractive \ + LANG=C.UTF-8 \ + TZ=UTC \ + TERM=xterm-256color \ + CARGO_HOME="/root/.cargo" \ + USER="root" -# Don't download rust docs -RUN rustup set profile minimal +{# {% if "alpine" not in target_file and "buildx" in target_file %} +# Debian based Buildx builds can use some special apt caching to speedup building. +# By default Debian based images have some rules to keep docker builds clean, we need to remove this. +# See: https://hub.docker.com/r/docker/dockerfile +RUN rm -f /etc/apt/apt.conf.d/docker-clean; echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache +{% endif %} #} + +# Create CARGO_HOME folder and don't download rust docs +RUN {{ mount_rust_cache -}} mkdir -pv "${CARGO_HOME}" \ + && rustup set profile minimal {% if "alpine" in target_file %} -ENV USER "root" ENV RUSTFLAGS='-C link-arg=-s' {% if "armv7" in target_file %} ENV CFLAGS_armv7_unknown_linux_musleabihf="-mfpu=vfpv3-d16" {% endif %} {% elif "arm" in target_file %} +# NOTE: Any apt-get/dpkg after this stage will fail because of broken dependencies. +# For Diesel-RS migrations_macros to compile with MySQL/MariaDB we need to do some magic. +# We at least need libmariadb3:amd64 installed for the x86_64 version of libmariadb.so (client) +# We also need the libmariadb-dev-compat:amd64 but it can not be installed together with the {{ package_arch_prefix }} version. +# What we can do is a force install, because nothing important is overlapping each other. +# # Install required build libs for {{ package_arch_name }} architecture. # To compile both mysql and postgresql we need some extra packages for both host arch and target arch -RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > \ - /etc/apt/sources.list.d/deb-src.list \ +RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > /etc/apt/sources.list.d/deb-src.list \ && dpkg --add-architecture {{ package_arch_name }} \ && apt-get update \ && apt-get install -y \ @@ -110,24 +134,43 @@ RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > \ libc6-dev{{ package_arch_prefix }} \ libpq5{{ package_arch_prefix }} \ libpq-dev \ + libmariadb3:amd64 \ libmariadb-dev{{ package_arch_prefix }} \ libmariadb-dev-compat{{ package_arch_prefix }} \ gcc-{{ package_cross_compiler }} \ - && mkdir -p ~/.cargo \ - && echo '[target.{{ package_arch_target }}]' >> ~/.cargo/config \ - && echo 'linker = "{{ package_cross_compiler }}-gcc"' >> ~/.cargo/config \ - && echo 'rustflags = ["-L/usr/lib/{{ package_cross_compiler }}"]' >> ~/.cargo/config + # + # Manual install libmariadb-dev-compat:amd64 ( After this broken dependencies will break apt ) + && apt-get download libmariadb-dev-compat:amd64 \ + && dpkg --force-all -i ./libmariadb-dev-compat*.deb \ + && rm -rvf ./libmariadb-dev-compat*.deb \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* \ + # + # For Diesel-RS migrations_macros to compile with PostgreSQL we need to do some magic. + # The libpq5{{ package_arch_prefix }} package seems to not provide a symlink to libpq.so.5 with the name libpq.so. + # This is only provided by the libpq-dev package which can't be installed for both arch at the same time. + # Without this specific file the ld command will fail and compilation fails with it. + && ln -sfnr /usr/lib/{{ package_cross_compiler }}/libpq.so.5 /usr/lib/{{ package_cross_compiler }}/libpq.so \ + # + # Make sure cargo has the right target config + && echo '[target.{{ package_arch_target }}]' >> "${CARGO_HOME}/config" \ + && echo 'linker = "{{ package_cross_compiler }}-gcc"' >> "${CARGO_HOME}/config" \ + && echo 'rustflags = ["-L/usr/lib/{{ package_cross_compiler }}"]' >> "${CARGO_HOME}/config" -ENV CARGO_HOME "/root/.cargo" -ENV USER "root" -{% endif -%} +# Set arm specific environment values +ENV CC_{{ package_arch_target | replace("-", "_") }}="/usr/bin/{{ package_cross_compiler }}-gcc" +ENV CROSS_COMPILE="1" +ENV OPENSSL_INCLUDE_DIR="/usr/include/{{ package_cross_compiler }}" +ENV OPENSSL_LIB_DIR="/usr/lib/{{ package_cross_compiler }}" -{% if "amd64" in target_file and "alpine" not in target_file %} +{% elif "amd64" in target_file %} # Install DB packages -RUN apt-get update && apt-get install -y \ - --no-install-recommends \ - libmariadb-dev{{ package_arch_prefix }} \ - libpq-dev{{ package_arch_prefix }} \ +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/* {% endif %} @@ -140,37 +183,14 @@ COPY ./Cargo.* ./ COPY ./rust-toolchain ./rust-toolchain COPY ./build.rs ./build.rs -{% if "alpine" not in target_file %} -{% if "arm" in target_file %} -# NOTE: This should be the last apt-get/dpkg for this stage, since after this it will fail because of broken dependencies. -# For Diesel-RS migrations_macros to compile with MySQL/MariaDB we need to do some magic. -# We at least need libmariadb3:amd64 installed for the x86_64 version of libmariadb.so (client) -# We also need the libmariadb-dev-compat:amd64 but it can not be installed together with the {{ package_arch_prefix }} version. -# What we can do is a force install, because nothing important is overlapping each other. -RUN apt-get install -y --no-install-recommends libmariadb3:amd64 \ - && apt-get download libmariadb-dev-compat:amd64 \ - && dpkg --force-all -i ./libmariadb-dev-compat*.deb \ - && rm -rvf ./libmariadb-dev-compat*.deb \ - # For Diesel-RS migrations_macros to compile with PostgreSQL we need to do some magic. - # The libpq5{{ package_arch_prefix }} package seems to not provide a symlink to libpq.so.5 with the name libpq.so. - # This is only provided by the libpq-dev package which can't be installed for both arch at the same time. - # Without this specific file the ld command will fail and compilation fails with it. - && ln -sfnr /usr/lib/{{ package_cross_compiler }}/libpq.so.5 /usr/lib/{{ package_cross_compiler }}/libpq.so - -ENV CC_{{ package_arch_target | replace("-", "_") }}="/usr/bin/{{ package_cross_compiler }}-gcc" -ENV CROSS_COMPILE="1" -ENV OPENSSL_INCLUDE_DIR="/usr/include/{{ package_cross_compiler }}" -ENV OPENSSL_LIB_DIR="/usr/lib/{{ package_cross_compiler }}" -{% endif -%} -{% endif %} {% if package_arch_target is defined %} -RUN rustup target add {{ package_arch_target }} +RUN {{ mount_rust_cache -}} rustup target add {{ package_arch_target }} {% endif %} # Builds your dependencies and removes the # dummy project, except the target folder # This folder contains the compiled dependencies -RUN cargo build --features ${DB} --release{{ package_arch_target_param }} \ +RUN {{ mount_rust_cache -}} cargo build --features ${DB} --release{{ package_arch_target_param }} \ && find . -not -path "./target*" -delete # Copies the complete project @@ -182,7 +202,7 @@ RUN touch src/main.rs # Builds again, this time it'll just be # your actual source files being built -RUN cargo build --features ${DB} --release{{ package_arch_target_param }} +RUN {{ mount_rust_cache -}} cargo build --features ${DB} --release{{ package_arch_target_param }} {% if "alpine" in target_file %} {% if "armv7" in target_file %} # hadolint ignore=DL3059 @@ -231,6 +251,7 @@ RUN mkdir /data \ dumb-init \ libmariadb-dev-compat \ libpq5 \ + && apt-get clean \ && rm -rf /var/lib/apt/lists/* {% endif %} diff --git a/docker/Makefile b/docker/Makefile index 86b3b64c..8c939cba 100644 --- a/docker/Makefile +++ b/docker/Makefile @@ -7,3 +7,9 @@ all: $(OBJECTS) %/Dockerfile.alpine: Dockerfile.j2 render_template ./render_template "$<" "{\"target_file\":\"$@\"}" > "$@" + +%/Dockerfile.buildx: Dockerfile.j2 render_template + ./render_template "$<" "{\"target_file\":\"$@\"}" > "$@" + +%/Dockerfile.buildx.alpine: Dockerfile.j2 render_template + ./render_template "$<" "{\"target_file\":\"$@\"}" > "$@" diff --git a/docker/amd64/Dockerfile b/docker/amd64/Dockerfile index 8f448ccc..6769ef4f 100644 --- a/docker/amd64/Dockerfile +++ b/docker/amd64/Dockerfile @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1 + # This file was generated using a Jinja2 template. # Please make your changes in `Dockerfile.j2` and then `make` the individual Dockerfiles. @@ -31,16 +33,25 @@ FROM rust:1.54-bullseye as build ARG DB=sqlite,mysql,postgresql # Build time options to avoid dpkg warnings and help with reproducible builds. -ENV DEBIAN_FRONTEND=noninteractive LANG=C.UTF-8 TZ=UTC TERM=xterm-256color +ENV DEBIAN_FRONTEND=noninteractive \ + LANG=C.UTF-8 \ + TZ=UTC \ + TERM=xterm-256color \ + CARGO_HOME="/root/.cargo" \ + USER="root" + -# Don't download rust docs -RUN rustup set profile minimal +# Create CARGO_HOME folder and don't download rust docs +RUN mkdir -pv "${CARGO_HOME}" \ + && rustup set profile minimal # Install DB packages -RUN apt-get update && apt-get install -y \ - --no-install-recommends \ - libmariadb-dev \ - libpq-dev \ +RUN apt-get update \ + && apt-get install -y \ + --no-install-recommends \ + libmariadb-dev \ + libpq-dev \ + && apt-get clean \ && rm -rf /var/lib/apt/lists/* # Creates a dummy project used to grab dependencies @@ -90,6 +101,7 @@ RUN mkdir /data \ dumb-init \ libmariadb-dev-compat \ libpq5 \ + && apt-get clean \ && rm -rf /var/lib/apt/lists/* diff --git a/docker/amd64/Dockerfile.alpine b/docker/amd64/Dockerfile.alpine index 64963b99..9ac4dc38 100644 --- a/docker/amd64/Dockerfile.alpine +++ b/docker/amd64/Dockerfile.alpine @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1 + # This file was generated using a Jinja2 template. # Please make your changes in `Dockerfile.j2` and then `make` the individual Dockerfiles. @@ -31,12 +33,18 @@ FROM clux/muslrust:nightly-2021-08-22 as build ARG DB=sqlite,postgresql # Build time options to avoid dpkg warnings and help with reproducible builds. -ENV DEBIAN_FRONTEND=noninteractive LANG=C.UTF-8 TZ=UTC TERM=xterm-256color +ENV DEBIAN_FRONTEND=noninteractive \ + LANG=C.UTF-8 \ + TZ=UTC \ + TERM=xterm-256color \ + CARGO_HOME="/root/.cargo" \ + USER="root" + -# Don't download rust docs -RUN rustup set profile minimal +# Create CARGO_HOME folder and don't download rust docs +RUN mkdir -pv "${CARGO_HOME}" \ + && rustup set profile minimal -ENV USER "root" ENV RUSTFLAGS='-C link-arg=-s' # Creates a dummy project used to grab dependencies diff --git a/docker/amd64/Dockerfile.buildx b/docker/amd64/Dockerfile.buildx new file mode 100644 index 00000000..a4aa826a --- /dev/null +++ b/docker/amd64/Dockerfile.buildx @@ -0,0 +1,126 @@ +# syntax=docker/dockerfile:1 + +# This file was generated using a Jinja2 template. +# Please make your changes in `Dockerfile.j2` and then `make` the individual Dockerfiles. + +# Using multistage build: +# https://docs.docker.com/develop/develop-images/multistage-build/ +# https://whitfin.io/speeding-up-rust-docker-builds/ +####################### VAULT BUILD IMAGE ####################### +# The web-vault digest specifies a particular web-vault build on Docker Hub. +# Using the digest instead of the tag name provides better security, +# as the digest of an image is immutable, whereas a tag name can later +# be changed to point to a malicious image. +# +# To verify the current digest for a given tag name: +# - From https://hub.docker.com/r/vaultwarden/web-vault/tags, +# click the tag name to view the digest of the image it currently points to. +# - From the command line: +# $ docker pull vaultwarden/web-vault:v2.21.1 +# $ docker image inspect --format "{{.RepoDigests}}" vaultwarden/web-vault:v2.21.1 +# [vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5] +# +# - Conversely, to get the tag name from the digest: +# $ docker image inspect --format "{{.RepoTags}}" vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5 +# [vaultwarden/web-vault:v2.21.1] +# +FROM vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5 as vault + +########################## BUILD IMAGE ########################## +FROM rust:1.54-bullseye as build + +# Debian-based builds support multidb +ARG DB=sqlite,mysql,postgresql + +# Build time options to avoid dpkg warnings and help with reproducible builds. +ENV DEBIAN_FRONTEND=noninteractive \ + LANG=C.UTF-8 \ + TZ=UTC \ + TERM=xterm-256color \ + 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 +RUN apt-get update \ + && apt-get install -y \ + --no-install-recommends \ + libmariadb-dev \ + libpq-dev \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Creates a dummy project used to grab dependencies +RUN USER=root cargo new --bin /app +WORKDIR /app + +# Copies over *only* your manifests and build files +COPY ./Cargo.* ./ +COPY ./rust-toolchain ./rust-toolchain +COPY ./build.rs ./build.rs + + +# Builds your dependencies and removes the +# dummy project, except the target folder +# This folder contains the compiled dependencies +RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry cargo build --features ${DB} --release \ + && find . -not -path "./target*" -delete + +# Copies the complete project +# To avoid copying unneeded files, use .dockerignore +COPY . . + +# Make sure that we actually build the project +RUN touch src/main.rs + +# Builds again, this time it'll just be +# your actual source files being built +RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry cargo build --features ${DB} --release + +######################## RUNTIME IMAGE ######################## +# Create a new stage with a minimal image +# because we already have a binary built +FROM debian:bullseye-slim + +ENV ROCKET_ENV "staging" +ENV ROCKET_PORT=80 +ENV ROCKET_WORKERS=10 + + +# Create data folder and Install needed libraries +RUN mkdir /data \ + && apt-get update && apt-get install -y \ + --no-install-recommends \ + openssl \ + ca-certificates \ + curl \ + dumb-init \ + libmariadb-dev-compat \ + libpq5 \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + + +VOLUME /data +EXPOSE 80 +EXPOSE 3012 + +# Copies the files from the context (Rocket.toml file and web-vault) +# and the binary from the "build" stage to the current stage +WORKDIR / +COPY Rocket.toml . +COPY --from=vault /web-vault ./web-vault +COPY --from=build /app/target/release/vaultwarden . + +COPY docker/healthcheck.sh /healthcheck.sh +COPY docker/start.sh /start.sh + +HEALTHCHECK --interval=60s --timeout=10s CMD ["/healthcheck.sh"] + +# Configures the startup! +ENTRYPOINT ["/usr/bin/dumb-init", "--"] +CMD ["/start.sh"] diff --git a/docker/amd64/Dockerfile.buildx.alpine b/docker/amd64/Dockerfile.buildx.alpine new file mode 100644 index 00000000..ca666c1a --- /dev/null +++ b/docker/amd64/Dockerfile.buildx.alpine @@ -0,0 +1,118 @@ +# syntax=docker/dockerfile:1 + +# This file was generated using a Jinja2 template. +# Please make your changes in `Dockerfile.j2` and then `make` the individual Dockerfiles. + +# Using multistage build: +# https://docs.docker.com/develop/develop-images/multistage-build/ +# https://whitfin.io/speeding-up-rust-docker-builds/ +####################### VAULT BUILD IMAGE ####################### +# The web-vault digest specifies a particular web-vault build on Docker Hub. +# Using the digest instead of the tag name provides better security, +# as the digest of an image is immutable, whereas a tag name can later +# be changed to point to a malicious image. +# +# To verify the current digest for a given tag name: +# - From https://hub.docker.com/r/vaultwarden/web-vault/tags, +# click the tag name to view the digest of the image it currently points to. +# - From the command line: +# $ docker pull vaultwarden/web-vault:v2.21.1 +# $ docker image inspect --format "{{.RepoDigests}}" vaultwarden/web-vault:v2.21.1 +# [vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5] +# +# - Conversely, to get the tag name from the digest: +# $ docker image inspect --format "{{.RepoTags}}" vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5 +# [vaultwarden/web-vault:v2.21.1] +# +FROM vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5 as vault + +########################## BUILD IMAGE ########################## +FROM clux/muslrust:nightly-2021-08-22 as build + +# Alpine-based AMD64 (musl) does not support mysql/mariadb during compile time. +ARG DB=sqlite,postgresql + +# Build time options to avoid dpkg warnings and help with reproducible builds. +ENV DEBIAN_FRONTEND=noninteractive \ + LANG=C.UTF-8 \ + TZ=UTC \ + TERM=xterm-256color \ + 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 + +ENV RUSTFLAGS='-C link-arg=-s' + +# Creates a dummy project used to grab dependencies +RUN USER=root cargo new --bin /app +WORKDIR /app + +# Copies over *only* your manifests and build files +COPY ./Cargo.* ./ +COPY ./rust-toolchain ./rust-toolchain +COPY ./build.rs ./build.rs + +RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry rustup target add x86_64-unknown-linux-musl + +# Builds your dependencies and removes the +# dummy project, except the target folder +# This folder contains the compiled dependencies +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 \ + && find . -not -path "./target*" -delete + +# Copies the complete project +# To avoid copying unneeded files, use .dockerignore +COPY . . + +# Make sure that we actually build the project +RUN touch src/main.rs + +# Builds again, this time it'll just be +# your actual source files being built +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 + +######################## RUNTIME IMAGE ######################## +# Create a new stage with a minimal image +# because we already have a binary built +FROM alpine:3.14 + +ENV ROCKET_ENV "staging" +ENV ROCKET_PORT=80 +ENV ROCKET_WORKERS=10 +ENV SSL_CERT_DIR=/etc/ssl/certs + + +# Create data folder and Install needed libraries +RUN mkdir /data \ + && apk add --no-cache \ + openssl \ + tzdata \ + curl \ + dumb-init \ + postgresql-libs \ + ca-certificates + + +VOLUME /data +EXPOSE 80 +EXPOSE 3012 + +# Copies the files from the context (Rocket.toml file and web-vault) +# and the binary from the "build" stage to the current stage +WORKDIR / +COPY Rocket.toml . +COPY --from=vault /web-vault ./web-vault +COPY --from=build /app/target/x86_64-unknown-linux-musl/release/vaultwarden . + +COPY docker/healthcheck.sh /healthcheck.sh +COPY docker/start.sh /start.sh + +HEALTHCHECK --interval=60s --timeout=10s CMD ["/healthcheck.sh"] + +# Configures the startup! +ENTRYPOINT ["/usr/bin/dumb-init", "--"] +CMD ["/start.sh"] diff --git a/docker/arm64/Dockerfile b/docker/arm64/Dockerfile index ddda4f98..3e019ba6 100644 --- a/docker/arm64/Dockerfile +++ b/docker/arm64/Dockerfile @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1 + # This file was generated using a Jinja2 template. # Please make your changes in `Dockerfile.j2` and then `make` the individual Dockerfiles. @@ -31,15 +33,27 @@ FROM rust:1.54-bullseye as build ARG DB=sqlite,mysql,postgresql # Build time options to avoid dpkg warnings and help with reproducible builds. -ENV DEBIAN_FRONTEND=noninteractive LANG=C.UTF-8 TZ=UTC TERM=xterm-256color +ENV DEBIAN_FRONTEND=noninteractive \ + LANG=C.UTF-8 \ + TZ=UTC \ + TERM=xterm-256color \ + CARGO_HOME="/root/.cargo" \ + USER="root" + -# Don't download rust docs -RUN rustup set profile minimal +# Create CARGO_HOME folder and don't download rust docs +RUN mkdir -pv "${CARGO_HOME}" \ + && rustup set profile minimal +# NOTE: Any apt-get/dpkg after this stage will fail because of broken dependencies. +# For Diesel-RS migrations_macros to compile with MySQL/MariaDB we need to do some magic. +# We at least need libmariadb3:amd64 installed for the x86_64 version of libmariadb.so (client) +# We also need the libmariadb-dev-compat:amd64 but it can not be installed together with the :arm64 version. +# What we can do is a force install, because nothing important is overlapping each other. +# # Install required build libs for arm64 architecture. # To compile both mysql and postgresql we need some extra packages for both host arch and target arch -RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > \ - /etc/apt/sources.list.d/deb-src.list \ +RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > /etc/apt/sources.list.d/deb-src.list \ && dpkg --add-architecture arm64 \ && apt-get update \ && apt-get install -y \ @@ -48,45 +62,45 @@ RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > \ libc6-dev:arm64 \ libpq5:arm64 \ libpq-dev \ + libmariadb3:amd64 \ libmariadb-dev:arm64 \ libmariadb-dev-compat:arm64 \ gcc-aarch64-linux-gnu \ - && mkdir -p ~/.cargo \ - && echo '[target.aarch64-unknown-linux-gnu]' >> ~/.cargo/config \ - && echo 'linker = "aarch64-linux-gnu-gcc"' >> ~/.cargo/config \ - && echo 'rustflags = ["-L/usr/lib/aarch64-linux-gnu"]' >> ~/.cargo/config - -ENV CARGO_HOME "/root/.cargo" -ENV USER "root" - -# Creates a dummy project used to grab dependencies -RUN USER=root cargo new --bin /app -WORKDIR /app - -# Copies over *only* your manifests and build files -COPY ./Cargo.* ./ -COPY ./rust-toolchain ./rust-toolchain -COPY ./build.rs ./build.rs - -# NOTE: This should be the last apt-get/dpkg for this stage, since after this it will fail because of broken dependencies. -# For Diesel-RS migrations_macros to compile with MySQL/MariaDB we need to do some magic. -# We at least need libmariadb3:amd64 installed for the x86_64 version of libmariadb.so (client) -# We also need the libmariadb-dev-compat:amd64 but it can not be installed together with the :arm64 version. -# What we can do is a force install, because nothing important is overlapping each other. -RUN apt-get install -y --no-install-recommends libmariadb3:amd64 \ + # + # Manual install libmariadb-dev-compat:amd64 ( After this broken dependencies will break apt ) && apt-get download libmariadb-dev-compat:amd64 \ && dpkg --force-all -i ./libmariadb-dev-compat*.deb \ && rm -rvf ./libmariadb-dev-compat*.deb \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* \ + # # For Diesel-RS migrations_macros to compile with PostgreSQL we need to do some magic. # The libpq5:arm64 package seems to not provide a symlink to libpq.so.5 with the name libpq.so. # This is only provided by the libpq-dev package which can't be installed for both arch at the same time. # Without this specific file the ld command will fail and compilation fails with it. - && ln -sfnr /usr/lib/aarch64-linux-gnu/libpq.so.5 /usr/lib/aarch64-linux-gnu/libpq.so - + && ln -sfnr /usr/lib/aarch64-linux-gnu/libpq.so.5 /usr/lib/aarch64-linux-gnu/libpq.so \ + # + # Make sure cargo has the right target config + && echo '[target.aarch64-unknown-linux-gnu]' >> "${CARGO_HOME}/config" \ + && echo 'linker = "aarch64-linux-gnu-gcc"' >> "${CARGO_HOME}/config" \ + && echo 'rustflags = ["-L/usr/lib/aarch64-linux-gnu"]' >> "${CARGO_HOME}/config" + +# Set arm specific environment values ENV CC_aarch64_unknown_linux_gnu="/usr/bin/aarch64-linux-gnu-gcc" ENV CROSS_COMPILE="1" ENV OPENSSL_INCLUDE_DIR="/usr/include/aarch64-linux-gnu" ENV 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 + +# Copies over *only* your manifests and build files +COPY ./Cargo.* ./ +COPY ./rust-toolchain ./rust-toolchain +COPY ./build.rs ./build.rs + RUN rustup target add aarch64-unknown-linux-gnu # Builds your dependencies and removes the @@ -128,6 +142,7 @@ RUN mkdir /data \ dumb-init \ libmariadb-dev-compat \ libpq5 \ + && apt-get clean \ && rm -rf /var/lib/apt/lists/* # hadolint ignore=DL3059 diff --git a/docker/arm64/Dockerfile.buildx b/docker/arm64/Dockerfile.buildx new file mode 100644 index 00000000..afbdd46d --- /dev/null +++ b/docker/arm64/Dockerfile.buildx @@ -0,0 +1,169 @@ +# syntax=docker/dockerfile:1 + +# This file was generated using a Jinja2 template. +# Please make your changes in `Dockerfile.j2` and then `make` the individual Dockerfiles. + +# Using multistage build: +# https://docs.docker.com/develop/develop-images/multistage-build/ +# https://whitfin.io/speeding-up-rust-docker-builds/ +####################### VAULT BUILD IMAGE ####################### +# The web-vault digest specifies a particular web-vault build on Docker Hub. +# Using the digest instead of the tag name provides better security, +# as the digest of an image is immutable, whereas a tag name can later +# be changed to point to a malicious image. +# +# To verify the current digest for a given tag name: +# - From https://hub.docker.com/r/vaultwarden/web-vault/tags, +# click the tag name to view the digest of the image it currently points to. +# - From the command line: +# $ docker pull vaultwarden/web-vault:v2.21.1 +# $ docker image inspect --format "{{.RepoDigests}}" vaultwarden/web-vault:v2.21.1 +# [vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5] +# +# - Conversely, to get the tag name from the digest: +# $ docker image inspect --format "{{.RepoTags}}" vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5 +# [vaultwarden/web-vault:v2.21.1] +# +FROM vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5 as vault + +########################## BUILD IMAGE ########################## +FROM rust:1.54-bullseye as build + +# Debian-based builds support multidb +ARG DB=sqlite,mysql,postgresql + +# Build time options to avoid dpkg warnings and help with reproducible builds. +ENV DEBIAN_FRONTEND=noninteractive \ + LANG=C.UTF-8 \ + TZ=UTC \ + TERM=xterm-256color \ + 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 + +# NOTE: Any apt-get/dpkg after this stage will fail because of broken dependencies. +# For Diesel-RS migrations_macros to compile with MySQL/MariaDB we need to do some magic. +# We at least need libmariadb3:amd64 installed for the x86_64 version of libmariadb.so (client) +# We also need the libmariadb-dev-compat:amd64 but it can not be installed together with the :arm64 version. +# What we can do is a force install, because nothing important is overlapping each other. +# +# Install required build libs for arm64 architecture. +# To compile both mysql and postgresql we need some extra packages for both host arch and target arch +RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > /etc/apt/sources.list.d/deb-src.list \ + && dpkg --add-architecture arm64 \ + && apt-get update \ + && apt-get install -y \ + --no-install-recommends \ + libssl-dev:arm64 \ + libc6-dev:arm64 \ + libpq5:arm64 \ + libpq-dev \ + libmariadb3:amd64 \ + libmariadb-dev:arm64 \ + libmariadb-dev-compat:arm64 \ + gcc-aarch64-linux-gnu \ + # + # Manual install libmariadb-dev-compat:amd64 ( After this broken dependencies will break apt ) + && apt-get download libmariadb-dev-compat:amd64 \ + && dpkg --force-all -i ./libmariadb-dev-compat*.deb \ + && rm -rvf ./libmariadb-dev-compat*.deb \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* \ + # + # For Diesel-RS migrations_macros to compile with PostgreSQL we need to do some magic. + # The libpq5:arm64 package seems to not provide a symlink to libpq.so.5 with the name libpq.so. + # This is only provided by the libpq-dev package which can't be installed for both arch at the same time. + # Without this specific file the ld command will fail and compilation fails with it. + && ln -sfnr /usr/lib/aarch64-linux-gnu/libpq.so.5 /usr/lib/aarch64-linux-gnu/libpq.so \ + # + # Make sure cargo has the right target config + && echo '[target.aarch64-unknown-linux-gnu]' >> "${CARGO_HOME}/config" \ + && echo 'linker = "aarch64-linux-gnu-gcc"' >> "${CARGO_HOME}/config" \ + && echo 'rustflags = ["-L/usr/lib/aarch64-linux-gnu"]' >> "${CARGO_HOME}/config" + +# Set arm specific environment values +ENV CC_aarch64_unknown_linux_gnu="/usr/bin/aarch64-linux-gnu-gcc" +ENV CROSS_COMPILE="1" +ENV OPENSSL_INCLUDE_DIR="/usr/include/aarch64-linux-gnu" +ENV 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 + +# Copies over *only* your manifests and build files +COPY ./Cargo.* ./ +COPY ./rust-toolchain ./rust-toolchain +COPY ./build.rs ./build.rs + +RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry rustup target add aarch64-unknown-linux-gnu + +# Builds your dependencies and removes the +# dummy project, except the target folder +# This folder contains the compiled dependencies +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 \ + && find . -not -path "./target*" -delete + +# Copies the complete project +# To avoid copying unneeded files, use .dockerignore +COPY . . + +# Make sure that we actually build the project +RUN touch src/main.rs + +# Builds again, this time it'll just be +# your actual source files being built +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 + +######################## RUNTIME IMAGE ######################## +# Create a new stage with a minimal image +# because we already have a binary built +FROM balenalib/aarch64-debian:bullseye + +ENV ROCKET_ENV "staging" +ENV ROCKET_PORT=80 +ENV ROCKET_WORKERS=10 + +# 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 \ + dumb-init \ + libmariadb-dev-compat \ + libpq5 \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# hadolint ignore=DL3059 +RUN [ "cross-build-end" ] + +VOLUME /data +EXPOSE 80 +EXPOSE 3012 + +# Copies the files from the context (Rocket.toml file and web-vault) +# and the binary from the "build" stage to the current stage +WORKDIR / +COPY Rocket.toml . +COPY --from=vault /web-vault ./web-vault +COPY --from=build /app/target/aarch64-unknown-linux-gnu/release/vaultwarden . + +COPY docker/healthcheck.sh /healthcheck.sh +COPY docker/start.sh /start.sh + +HEALTHCHECK --interval=60s --timeout=10s CMD ["/healthcheck.sh"] + +# Configures the startup! +ENTRYPOINT ["/usr/bin/dumb-init", "--"] +CMD ["/start.sh"] diff --git a/docker/armv6/Dockerfile b/docker/armv6/Dockerfile index 1935517f..a5d1693b 100644 --- a/docker/armv6/Dockerfile +++ b/docker/armv6/Dockerfile @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1 + # This file was generated using a Jinja2 template. # Please make your changes in `Dockerfile.j2` and then `make` the individual Dockerfiles. @@ -31,15 +33,27 @@ FROM rust:1.54-bullseye as build ARG DB=sqlite,mysql,postgresql # Build time options to avoid dpkg warnings and help with reproducible builds. -ENV DEBIAN_FRONTEND=noninteractive LANG=C.UTF-8 TZ=UTC TERM=xterm-256color +ENV DEBIAN_FRONTEND=noninteractive \ + LANG=C.UTF-8 \ + TZ=UTC \ + TERM=xterm-256color \ + CARGO_HOME="/root/.cargo" \ + USER="root" + -# Don't download rust docs -RUN rustup set profile minimal +# Create CARGO_HOME folder and don't download rust docs +RUN mkdir -pv "${CARGO_HOME}" \ + && rustup set profile minimal +# NOTE: Any apt-get/dpkg after this stage will fail because of broken dependencies. +# For Diesel-RS migrations_macros to compile with MySQL/MariaDB we need to do some magic. +# We at least need libmariadb3:amd64 installed for the x86_64 version of libmariadb.so (client) +# We also need the libmariadb-dev-compat:amd64 but it can not be installed together with the :armel version. +# What we can do is a force install, because nothing important is overlapping each other. +# # Install required build libs for armel architecture. # To compile both mysql and postgresql we need some extra packages for both host arch and target arch -RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > \ - /etc/apt/sources.list.d/deb-src.list \ +RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > /etc/apt/sources.list.d/deb-src.list \ && dpkg --add-architecture armel \ && apt-get update \ && apt-get install -y \ @@ -48,45 +62,45 @@ RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > \ libc6-dev:armel \ libpq5:armel \ libpq-dev \ + libmariadb3:amd64 \ libmariadb-dev:armel \ libmariadb-dev-compat:armel \ gcc-arm-linux-gnueabi \ - && mkdir -p ~/.cargo \ - && echo '[target.arm-unknown-linux-gnueabi]' >> ~/.cargo/config \ - && echo 'linker = "arm-linux-gnueabi-gcc"' >> ~/.cargo/config \ - && echo 'rustflags = ["-L/usr/lib/arm-linux-gnueabi"]' >> ~/.cargo/config - -ENV CARGO_HOME "/root/.cargo" -ENV USER "root" - -# Creates a dummy project used to grab dependencies -RUN USER=root cargo new --bin /app -WORKDIR /app - -# Copies over *only* your manifests and build files -COPY ./Cargo.* ./ -COPY ./rust-toolchain ./rust-toolchain -COPY ./build.rs ./build.rs - -# NOTE: This should be the last apt-get/dpkg for this stage, since after this it will fail because of broken dependencies. -# For Diesel-RS migrations_macros to compile with MySQL/MariaDB we need to do some magic. -# We at least need libmariadb3:amd64 installed for the x86_64 version of libmariadb.so (client) -# We also need the libmariadb-dev-compat:amd64 but it can not be installed together with the :armel version. -# What we can do is a force install, because nothing important is overlapping each other. -RUN apt-get install -y --no-install-recommends libmariadb3:amd64 \ + # + # Manual install libmariadb-dev-compat:amd64 ( After this broken dependencies will break apt ) && apt-get download libmariadb-dev-compat:amd64 \ && dpkg --force-all -i ./libmariadb-dev-compat*.deb \ && rm -rvf ./libmariadb-dev-compat*.deb \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* \ + # # For Diesel-RS migrations_macros to compile with PostgreSQL we need to do some magic. # The libpq5:armel package seems to not provide a symlink to libpq.so.5 with the name libpq.so. # This is only provided by the libpq-dev package which can't be installed for both arch at the same time. # Without this specific file the ld command will fail and compilation fails with it. - && ln -sfnr /usr/lib/arm-linux-gnueabi/libpq.so.5 /usr/lib/arm-linux-gnueabi/libpq.so - + && ln -sfnr /usr/lib/arm-linux-gnueabi/libpq.so.5 /usr/lib/arm-linux-gnueabi/libpq.so \ + # + # Make sure cargo has the right target config + && echo '[target.arm-unknown-linux-gnueabi]' >> "${CARGO_HOME}/config" \ + && echo 'linker = "arm-linux-gnueabi-gcc"' >> "${CARGO_HOME}/config" \ + && echo 'rustflags = ["-L/usr/lib/arm-linux-gnueabi"]' >> "${CARGO_HOME}/config" + +# Set arm specific environment values ENV CC_arm_unknown_linux_gnueabi="/usr/bin/arm-linux-gnueabi-gcc" ENV CROSS_COMPILE="1" ENV OPENSSL_INCLUDE_DIR="/usr/include/arm-linux-gnueabi" ENV 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 + +# Copies over *only* your manifests and build files +COPY ./Cargo.* ./ +COPY ./rust-toolchain ./rust-toolchain +COPY ./build.rs ./build.rs + RUN rustup target add arm-unknown-linux-gnueabi # Builds your dependencies and removes the @@ -128,6 +142,7 @@ RUN mkdir /data \ dumb-init \ libmariadb-dev-compat \ libpq5 \ + && apt-get clean \ && rm -rf /var/lib/apt/lists/* # hadolint ignore=DL3059 diff --git a/docker/armv6/Dockerfile.buildx b/docker/armv6/Dockerfile.buildx new file mode 100644 index 00000000..5d7dc057 --- /dev/null +++ b/docker/armv6/Dockerfile.buildx @@ -0,0 +1,169 @@ +# syntax=docker/dockerfile:1 + +# This file was generated using a Jinja2 template. +# Please make your changes in `Dockerfile.j2` and then `make` the individual Dockerfiles. + +# Using multistage build: +# https://docs.docker.com/develop/develop-images/multistage-build/ +# https://whitfin.io/speeding-up-rust-docker-builds/ +####################### VAULT BUILD IMAGE ####################### +# The web-vault digest specifies a particular web-vault build on Docker Hub. +# Using the digest instead of the tag name provides better security, +# as the digest of an image is immutable, whereas a tag name can later +# be changed to point to a malicious image. +# +# To verify the current digest for a given tag name: +# - From https://hub.docker.com/r/vaultwarden/web-vault/tags, +# click the tag name to view the digest of the image it currently points to. +# - From the command line: +# $ docker pull vaultwarden/web-vault:v2.21.1 +# $ docker image inspect --format "{{.RepoDigests}}" vaultwarden/web-vault:v2.21.1 +# [vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5] +# +# - Conversely, to get the tag name from the digest: +# $ docker image inspect --format "{{.RepoTags}}" vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5 +# [vaultwarden/web-vault:v2.21.1] +# +FROM vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5 as vault + +########################## BUILD IMAGE ########################## +FROM rust:1.54-bullseye as build + +# Debian-based builds support multidb +ARG DB=sqlite,mysql,postgresql + +# Build time options to avoid dpkg warnings and help with reproducible builds. +ENV DEBIAN_FRONTEND=noninteractive \ + LANG=C.UTF-8 \ + TZ=UTC \ + TERM=xterm-256color \ + 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 + +# NOTE: Any apt-get/dpkg after this stage will fail because of broken dependencies. +# For Diesel-RS migrations_macros to compile with MySQL/MariaDB we need to do some magic. +# We at least need libmariadb3:amd64 installed for the x86_64 version of libmariadb.so (client) +# We also need the libmariadb-dev-compat:amd64 but it can not be installed together with the :armel version. +# What we can do is a force install, because nothing important is overlapping each other. +# +# Install required build libs for armel architecture. +# To compile both mysql and postgresql we need some extra packages for both host arch and target arch +RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > /etc/apt/sources.list.d/deb-src.list \ + && dpkg --add-architecture armel \ + && apt-get update \ + && apt-get install -y \ + --no-install-recommends \ + libssl-dev:armel \ + libc6-dev:armel \ + libpq5:armel \ + libpq-dev \ + libmariadb3:amd64 \ + libmariadb-dev:armel \ + libmariadb-dev-compat:armel \ + gcc-arm-linux-gnueabi \ + # + # Manual install libmariadb-dev-compat:amd64 ( After this broken dependencies will break apt ) + && apt-get download libmariadb-dev-compat:amd64 \ + && dpkg --force-all -i ./libmariadb-dev-compat*.deb \ + && rm -rvf ./libmariadb-dev-compat*.deb \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* \ + # + # For Diesel-RS migrations_macros to compile with PostgreSQL we need to do some magic. + # The libpq5:armel package seems to not provide a symlink to libpq.so.5 with the name libpq.so. + # This is only provided by the libpq-dev package which can't be installed for both arch at the same time. + # Without this specific file the ld command will fail and compilation fails with it. + && ln -sfnr /usr/lib/arm-linux-gnueabi/libpq.so.5 /usr/lib/arm-linux-gnueabi/libpq.so \ + # + # Make sure cargo has the right target config + && echo '[target.arm-unknown-linux-gnueabi]' >> "${CARGO_HOME}/config" \ + && echo 'linker = "arm-linux-gnueabi-gcc"' >> "${CARGO_HOME}/config" \ + && echo 'rustflags = ["-L/usr/lib/arm-linux-gnueabi"]' >> "${CARGO_HOME}/config" + +# Set arm specific environment values +ENV CC_arm_unknown_linux_gnueabi="/usr/bin/arm-linux-gnueabi-gcc" +ENV CROSS_COMPILE="1" +ENV OPENSSL_INCLUDE_DIR="/usr/include/arm-linux-gnueabi" +ENV 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 + +# Copies over *only* your manifests and build files +COPY ./Cargo.* ./ +COPY ./rust-toolchain ./rust-toolchain +COPY ./build.rs ./build.rs + +RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry rustup target add arm-unknown-linux-gnueabi + +# Builds your dependencies and removes the +# dummy project, except the target folder +# This folder contains the compiled dependencies +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 \ + && find . -not -path "./target*" -delete + +# Copies the complete project +# To avoid copying unneeded files, use .dockerignore +COPY . . + +# Make sure that we actually build the project +RUN touch src/main.rs + +# Builds again, this time it'll just be +# your actual source files being built +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 + +######################## RUNTIME IMAGE ######################## +# Create a new stage with a minimal image +# because we already have a binary built +FROM balenalib/rpi-debian:bullseye + +ENV ROCKET_ENV "staging" +ENV ROCKET_PORT=80 +ENV ROCKET_WORKERS=10 + +# 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 \ + dumb-init \ + libmariadb-dev-compat \ + libpq5 \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# hadolint ignore=DL3059 +RUN [ "cross-build-end" ] + +VOLUME /data +EXPOSE 80 +EXPOSE 3012 + +# Copies the files from the context (Rocket.toml file and web-vault) +# and the binary from the "build" stage to the current stage +WORKDIR / +COPY Rocket.toml . +COPY --from=vault /web-vault ./web-vault +COPY --from=build /app/target/arm-unknown-linux-gnueabi/release/vaultwarden . + +COPY docker/healthcheck.sh /healthcheck.sh +COPY docker/start.sh /start.sh + +HEALTHCHECK --interval=60s --timeout=10s CMD ["/healthcheck.sh"] + +# Configures the startup! +ENTRYPOINT ["/usr/bin/dumb-init", "--"] +CMD ["/start.sh"] diff --git a/docker/armv7/Dockerfile b/docker/armv7/Dockerfile index 9172b90e..9a168f65 100644 --- a/docker/armv7/Dockerfile +++ b/docker/armv7/Dockerfile @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1 + # This file was generated using a Jinja2 template. # Please make your changes in `Dockerfile.j2` and then `make` the individual Dockerfiles. @@ -31,15 +33,27 @@ FROM rust:1.54-bullseye as build ARG DB=sqlite,mysql,postgresql # Build time options to avoid dpkg warnings and help with reproducible builds. -ENV DEBIAN_FRONTEND=noninteractive LANG=C.UTF-8 TZ=UTC TERM=xterm-256color +ENV DEBIAN_FRONTEND=noninteractive \ + LANG=C.UTF-8 \ + TZ=UTC \ + TERM=xterm-256color \ + CARGO_HOME="/root/.cargo" \ + USER="root" + -# Don't download rust docs -RUN rustup set profile minimal +# Create CARGO_HOME folder and don't download rust docs +RUN mkdir -pv "${CARGO_HOME}" \ + && rustup set profile minimal +# NOTE: Any apt-get/dpkg after this stage will fail because of broken dependencies. +# For Diesel-RS migrations_macros to compile with MySQL/MariaDB we need to do some magic. +# We at least need libmariadb3:amd64 installed for the x86_64 version of libmariadb.so (client) +# We also need the libmariadb-dev-compat:amd64 but it can not be installed together with the :armhf version. +# What we can do is a force install, because nothing important is overlapping each other. +# # Install required build libs for armhf architecture. # To compile both mysql and postgresql we need some extra packages for both host arch and target arch -RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > \ - /etc/apt/sources.list.d/deb-src.list \ +RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > /etc/apt/sources.list.d/deb-src.list \ && dpkg --add-architecture armhf \ && apt-get update \ && apt-get install -y \ @@ -48,45 +62,45 @@ RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > \ libc6-dev:armhf \ libpq5:armhf \ libpq-dev \ + libmariadb3:amd64 \ libmariadb-dev:armhf \ libmariadb-dev-compat:armhf \ gcc-arm-linux-gnueabihf \ - && mkdir -p ~/.cargo \ - && echo '[target.armv7-unknown-linux-gnueabihf]' >> ~/.cargo/config \ - && echo 'linker = "arm-linux-gnueabihf-gcc"' >> ~/.cargo/config \ - && echo 'rustflags = ["-L/usr/lib/arm-linux-gnueabihf"]' >> ~/.cargo/config - -ENV CARGO_HOME "/root/.cargo" -ENV USER "root" - -# Creates a dummy project used to grab dependencies -RUN USER=root cargo new --bin /app -WORKDIR /app - -# Copies over *only* your manifests and build files -COPY ./Cargo.* ./ -COPY ./rust-toolchain ./rust-toolchain -COPY ./build.rs ./build.rs - -# NOTE: This should be the last apt-get/dpkg for this stage, since after this it will fail because of broken dependencies. -# For Diesel-RS migrations_macros to compile with MySQL/MariaDB we need to do some magic. -# We at least need libmariadb3:amd64 installed for the x86_64 version of libmariadb.so (client) -# We also need the libmariadb-dev-compat:amd64 but it can not be installed together with the :armhf version. -# What we can do is a force install, because nothing important is overlapping each other. -RUN apt-get install -y --no-install-recommends libmariadb3:amd64 \ + # + # Manual install libmariadb-dev-compat:amd64 ( After this broken dependencies will break apt ) && apt-get download libmariadb-dev-compat:amd64 \ && dpkg --force-all -i ./libmariadb-dev-compat*.deb \ && rm -rvf ./libmariadb-dev-compat*.deb \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* \ + # # For Diesel-RS migrations_macros to compile with PostgreSQL we need to do some magic. # The libpq5:armhf package seems to not provide a symlink to libpq.so.5 with the name libpq.so. # This is only provided by the libpq-dev package which can't be installed for both arch at the same time. # Without this specific file the ld command will fail and compilation fails with it. - && ln -sfnr /usr/lib/arm-linux-gnueabihf/libpq.so.5 /usr/lib/arm-linux-gnueabihf/libpq.so - + && ln -sfnr /usr/lib/arm-linux-gnueabihf/libpq.so.5 /usr/lib/arm-linux-gnueabihf/libpq.so \ + # + # Make sure cargo has the right target config + && echo '[target.armv7-unknown-linux-gnueabihf]' >> "${CARGO_HOME}/config" \ + && echo 'linker = "arm-linux-gnueabihf-gcc"' >> "${CARGO_HOME}/config" \ + && echo 'rustflags = ["-L/usr/lib/arm-linux-gnueabihf"]' >> "${CARGO_HOME}/config" + +# Set arm specific environment values ENV CC_armv7_unknown_linux_gnueabihf="/usr/bin/arm-linux-gnueabihf-gcc" ENV CROSS_COMPILE="1" ENV OPENSSL_INCLUDE_DIR="/usr/include/arm-linux-gnueabihf" ENV 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 + +# Copies over *only* your manifests and build files +COPY ./Cargo.* ./ +COPY ./rust-toolchain ./rust-toolchain +COPY ./build.rs ./build.rs + RUN rustup target add armv7-unknown-linux-gnueabihf # Builds your dependencies and removes the @@ -128,6 +142,7 @@ RUN mkdir /data \ dumb-init \ libmariadb-dev-compat \ libpq5 \ + && apt-get clean \ && rm -rf /var/lib/apt/lists/* # hadolint ignore=DL3059 diff --git a/docker/armv7/Dockerfile.alpine b/docker/armv7/Dockerfile.alpine index a6ca1582..f78168cf 100644 --- a/docker/armv7/Dockerfile.alpine +++ b/docker/armv7/Dockerfile.alpine @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1 + # This file was generated using a Jinja2 template. # Please make your changes in `Dockerfile.j2` and then `make` the individual Dockerfiles. @@ -32,12 +34,18 @@ FROM messense/rust-musl-cross:armv7-musleabihf as build ARG DB=sqlite,vendored_openssl # Build time options to avoid dpkg warnings and help with reproducible builds. -ENV DEBIAN_FRONTEND=noninteractive LANG=C.UTF-8 TZ=UTC TERM=xterm-256color +ENV DEBIAN_FRONTEND=noninteractive \ + LANG=C.UTF-8 \ + TZ=UTC \ + TERM=xterm-256color \ + CARGO_HOME="/root/.cargo" \ + USER="root" + -# Don't download rust docs -RUN rustup set profile minimal +# Create CARGO_HOME folder and don't download rust docs +RUN mkdir -pv "${CARGO_HOME}" \ + && rustup set profile minimal -ENV USER "root" ENV RUSTFLAGS='-C link-arg=-s' ENV CFLAGS_armv7_unknown_linux_musleabihf="-mfpu=vfpv3-d16" diff --git a/docker/armv7/Dockerfile.buildx b/docker/armv7/Dockerfile.buildx new file mode 100644 index 00000000..938abd58 --- /dev/null +++ b/docker/armv7/Dockerfile.buildx @@ -0,0 +1,169 @@ +# syntax=docker/dockerfile:1 + +# This file was generated using a Jinja2 template. +# Please make your changes in `Dockerfile.j2` and then `make` the individual Dockerfiles. + +# Using multistage build: +# https://docs.docker.com/develop/develop-images/multistage-build/ +# https://whitfin.io/speeding-up-rust-docker-builds/ +####################### VAULT BUILD IMAGE ####################### +# The web-vault digest specifies a particular web-vault build on Docker Hub. +# Using the digest instead of the tag name provides better security, +# as the digest of an image is immutable, whereas a tag name can later +# be changed to point to a malicious image. +# +# To verify the current digest for a given tag name: +# - From https://hub.docker.com/r/vaultwarden/web-vault/tags, +# click the tag name to view the digest of the image it currently points to. +# - From the command line: +# $ docker pull vaultwarden/web-vault:v2.21.1 +# $ docker image inspect --format "{{.RepoDigests}}" vaultwarden/web-vault:v2.21.1 +# [vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5] +# +# - Conversely, to get the tag name from the digest: +# $ docker image inspect --format "{{.RepoTags}}" vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5 +# [vaultwarden/web-vault:v2.21.1] +# +FROM vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5 as vault + +########################## BUILD IMAGE ########################## +FROM rust:1.54-bullseye as build + +# Debian-based builds support multidb +ARG DB=sqlite,mysql,postgresql + +# Build time options to avoid dpkg warnings and help with reproducible builds. +ENV DEBIAN_FRONTEND=noninteractive \ + LANG=C.UTF-8 \ + TZ=UTC \ + TERM=xterm-256color \ + 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 + +# NOTE: Any apt-get/dpkg after this stage will fail because of broken dependencies. +# For Diesel-RS migrations_macros to compile with MySQL/MariaDB we need to do some magic. +# We at least need libmariadb3:amd64 installed for the x86_64 version of libmariadb.so (client) +# We also need the libmariadb-dev-compat:amd64 but it can not be installed together with the :armhf version. +# What we can do is a force install, because nothing important is overlapping each other. +# +# Install required build libs for armhf architecture. +# To compile both mysql and postgresql we need some extra packages for both host arch and target arch +RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > /etc/apt/sources.list.d/deb-src.list \ + && dpkg --add-architecture armhf \ + && apt-get update \ + && apt-get install -y \ + --no-install-recommends \ + libssl-dev:armhf \ + libc6-dev:armhf \ + libpq5:armhf \ + libpq-dev \ + libmariadb3:amd64 \ + libmariadb-dev:armhf \ + libmariadb-dev-compat:armhf \ + gcc-arm-linux-gnueabihf \ + # + # Manual install libmariadb-dev-compat:amd64 ( After this broken dependencies will break apt ) + && apt-get download libmariadb-dev-compat:amd64 \ + && dpkg --force-all -i ./libmariadb-dev-compat*.deb \ + && rm -rvf ./libmariadb-dev-compat*.deb \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* \ + # + # For Diesel-RS migrations_macros to compile with PostgreSQL we need to do some magic. + # The libpq5:armhf package seems to not provide a symlink to libpq.so.5 with the name libpq.so. + # This is only provided by the libpq-dev package which can't be installed for both arch at the same time. + # Without this specific file the ld command will fail and compilation fails with it. + && ln -sfnr /usr/lib/arm-linux-gnueabihf/libpq.so.5 /usr/lib/arm-linux-gnueabihf/libpq.so \ + # + # Make sure cargo has the right target config + && echo '[target.armv7-unknown-linux-gnueabihf]' >> "${CARGO_HOME}/config" \ + && echo 'linker = "arm-linux-gnueabihf-gcc"' >> "${CARGO_HOME}/config" \ + && echo 'rustflags = ["-L/usr/lib/arm-linux-gnueabihf"]' >> "${CARGO_HOME}/config" + +# Set arm specific environment values +ENV CC_armv7_unknown_linux_gnueabihf="/usr/bin/arm-linux-gnueabihf-gcc" +ENV CROSS_COMPILE="1" +ENV OPENSSL_INCLUDE_DIR="/usr/include/arm-linux-gnueabihf" +ENV 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 + +# Copies over *only* your manifests and build files +COPY ./Cargo.* ./ +COPY ./rust-toolchain ./rust-toolchain +COPY ./build.rs ./build.rs + +RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry rustup target add armv7-unknown-linux-gnueabihf + +# Builds your dependencies and removes the +# dummy project, except the target folder +# This folder contains the compiled dependencies +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 \ + && find . -not -path "./target*" -delete + +# Copies the complete project +# To avoid copying unneeded files, use .dockerignore +COPY . . + +# Make sure that we actually build the project +RUN touch src/main.rs + +# Builds again, this time it'll just be +# your actual source files being built +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 + +######################## RUNTIME IMAGE ######################## +# Create a new stage with a minimal image +# because we already have a binary built +FROM balenalib/armv7hf-debian:bullseye + +ENV ROCKET_ENV "staging" +ENV ROCKET_PORT=80 +ENV ROCKET_WORKERS=10 + +# 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 \ + dumb-init \ + libmariadb-dev-compat \ + libpq5 \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# hadolint ignore=DL3059 +RUN [ "cross-build-end" ] + +VOLUME /data +EXPOSE 80 +EXPOSE 3012 + +# Copies the files from the context (Rocket.toml file and web-vault) +# and the binary from the "build" stage to the current stage +WORKDIR / +COPY Rocket.toml . +COPY --from=vault /web-vault ./web-vault +COPY --from=build /app/target/armv7-unknown-linux-gnueabihf/release/vaultwarden . + +COPY docker/healthcheck.sh /healthcheck.sh +COPY docker/start.sh /start.sh + +HEALTHCHECK --interval=60s --timeout=10s CMD ["/healthcheck.sh"] + +# Configures the startup! +ENTRYPOINT ["/usr/bin/dumb-init", "--"] +CMD ["/start.sh"] diff --git a/docker/armv7/Dockerfile.buildx.alpine b/docker/armv7/Dockerfile.buildx.alpine new file mode 100644 index 00000000..8b72d1d3 --- /dev/null +++ b/docker/armv7/Dockerfile.buildx.alpine @@ -0,0 +1,125 @@ +# syntax=docker/dockerfile:1 + +# This file was generated using a Jinja2 template. +# Please make your changes in `Dockerfile.j2` and then `make` the individual Dockerfiles. + +# Using multistage build: +# https://docs.docker.com/develop/develop-images/multistage-build/ +# https://whitfin.io/speeding-up-rust-docker-builds/ +####################### VAULT BUILD IMAGE ####################### +# The web-vault digest specifies a particular web-vault build on Docker Hub. +# Using the digest instead of the tag name provides better security, +# as the digest of an image is immutable, whereas a tag name can later +# be changed to point to a malicious image. +# +# To verify the current digest for a given tag name: +# - From https://hub.docker.com/r/vaultwarden/web-vault/tags, +# click the tag name to view the digest of the image it currently points to. +# - From the command line: +# $ docker pull vaultwarden/web-vault:v2.21.1 +# $ docker image inspect --format "{{.RepoDigests}}" vaultwarden/web-vault:v2.21.1 +# [vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5] +# +# - Conversely, to get the tag name from the digest: +# $ docker image inspect --format "{{.RepoTags}}" vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5 +# [vaultwarden/web-vault:v2.21.1] +# +FROM vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5 as vault + +########################## BUILD IMAGE ########################## +FROM messense/rust-musl-cross:armv7-musleabihf as build + +# Alpine-based ARM (musl) only supports sqlite during compile time. +# We now also need to add vendored_openssl, because the current base image we use to build has OpenSSL removed. +ARG DB=sqlite,vendored_openssl + +# Build time options to avoid dpkg warnings and help with reproducible builds. +ENV DEBIAN_FRONTEND=noninteractive \ + LANG=C.UTF-8 \ + TZ=UTC \ + TERM=xterm-256color \ + 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 + +ENV RUSTFLAGS='-C link-arg=-s' +ENV CFLAGS_armv7_unknown_linux_musleabihf="-mfpu=vfpv3-d16" + +# Creates a dummy project used to grab dependencies +RUN USER=root cargo new --bin /app +WORKDIR /app + +# Copies over *only* your manifests and build files +COPY ./Cargo.* ./ +COPY ./rust-toolchain ./rust-toolchain +COPY ./build.rs ./build.rs + +RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry rustup target add armv7-unknown-linux-musleabihf + +# Builds your dependencies and removes the +# dummy project, except the target folder +# This folder contains the compiled dependencies +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 \ + && find . -not -path "./target*" -delete + +# Copies the complete project +# To avoid copying unneeded files, use .dockerignore +COPY . . + +# Make sure that we actually build the project +RUN touch src/main.rs + +# Builds again, this time it'll just be +# your actual source files being built +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 +# hadolint ignore=DL3059 +RUN musl-strip target/armv7-unknown-linux-musleabihf/release/vaultwarden + +######################## RUNTIME IMAGE ######################## +# Create a new stage with a minimal image +# because we already have a binary built +FROM balenalib/armv7hf-alpine:3.14 + +ENV ROCKET_ENV "staging" +ENV ROCKET_PORT=80 +ENV ROCKET_WORKERS=10 +ENV 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 \ + curl \ + dumb-init \ + ca-certificates + +# hadolint ignore=DL3059 +RUN [ "cross-build-end" ] + +VOLUME /data +EXPOSE 80 +EXPOSE 3012 + +# Copies the files from the context (Rocket.toml file and web-vault) +# and the binary from the "build" stage to the current stage +WORKDIR / +COPY Rocket.toml . +COPY --from=vault /web-vault ./web-vault +COPY --from=build /app/target/armv7-unknown-linux-musleabihf/release/vaultwarden . + +COPY docker/healthcheck.sh /healthcheck.sh +COPY docker/start.sh /start.sh + +HEALTHCHECK --interval=60s --timeout=10s CMD ["/healthcheck.sh"] + +# Configures the startup! +ENTRYPOINT ["/usr/bin/dumb-init", "--"] +CMD ["/start.sh"] diff --git a/hooks/build b/hooks/build index f18c58bf..96f04d15 100755 --- a/hooks/build +++ b/hooks/build @@ -34,12 +34,17 @@ for label in "${LABELS[@]}"; do LABEL_ARGS+=(--label "${label}") done +# Check if DOCKER_BUILDKIT is set, if so, use the Dockerfile.buildx as template +if [[ -n "${DOCKER_BUILDKIT}" ]]; then + buildx_suffix=.buildx +fi + set -ex for arch in "${arches[@]}"; do docker build \ "${LABEL_ARGS[@]}" \ -t "${DOCKER_REPO}:${DOCKER_TAG}-${arch}" \ - -f docker/${arch}/Dockerfile${distro_suffix} \ + -f docker/${arch}/Dockerfile${buildx_suffix}${distro_suffix} \ . done diff --git a/hooks/push b/hooks/push index 4c690eb0..de8d24e8 100755 --- a/hooks/push +++ b/hooks/push @@ -10,7 +10,7 @@ join() { local IFS="$1"; shift; echo "$*"; } set -ex -echo ">>> Starting local Docker registry..." +echo ">>> Starting local Docker registry when needed..." # Docker Buildx's `docker-container` driver is needed for multi-platform # builds, but it can't access existing images on the Docker host (like the @@ -28,7 +28,10 @@ echo ">>> Starting local Docker registry..." # First check if there already is a registry container running, else skip it. # This will only happen either locally or running it via Github Actions # -docker start registry > /dev/null 2>&1 || docker run -d --name registry --network host registry:2 # defaults to port 5000 +if ! timeout 5 bash -c 'cat < /dev/null > /dev/tcp/localhost/5000'; then + # defaults to port 5000 + docker run -d --name registry --network host registry:2 +fi # Docker Hub sets a `DOCKER_REPO` env var with the format `index.docker.io/user/repo`. # Strip the registry portion to construct a local repo path for use in `Dockerfile.buildx`. From 9bef2c120c3a429f4dfffdc831dde624444b2672 Mon Sep 17 00:00:00 2001 From: Ben Armstead Date: Thu, 16 Sep 2021 14:21:06 +0100 Subject: [PATCH 07/68] Update dependencies --- Cargo.lock | 304 ++++++++++++++++++++++++++--------------------------- 1 file changed, 152 insertions(+), 152 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5072c529..a1e9961a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -236,15 +236,15 @@ dependencies = [ [[package]] name = "bytes" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" [[package]] name = "cc" -version = "1.0.69" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" +checksum = "d26a6ce4b6a484fa3edb70f7efa6fc430fd2b87285fe8b84304fd0936faa0dc0" [[package]] name = "cfg-if" @@ -345,7 +345,7 @@ dependencies = [ "cookie 0.15.1", "idna 0.2.3", "log 0.4.14", - "publicsuffix 2.1.0", + "publicsuffix 2.1.1", "serde", "serde_json", "time 0.2.27", @@ -370,9 +370,9 @@ checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" [[package]] name = "cpufeatures" -version = "0.1.5" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef" +checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" dependencies = [ "libc", ] @@ -455,9 +455,9 @@ version = "0.3.0" source = "git+https://github.com/SergioBenitez/Devise.git?rev=e58b3ac9a#e58b3ac9afc3b6ff10a8aaf02a3e768a8f530089" dependencies = [ "bitflags", - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", - "syn 1.0.75", + "syn 1.0.76", ] [[package]] @@ -483,9 +483,9 @@ version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45f5098f628d02a7a0f68ddba586fb61e80edec3bdc1be3b921f4ceec60858d3" dependencies = [ - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", - "syn 1.0.75", + "syn 1.0.76", ] [[package]] @@ -579,9 +579,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd3aec53de10fe96d7d8c565eb17f2c687bb5518a2ec453b5b1252964526abe0" +checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" dependencies = [ "cfg-if 1.0.0", "crc32fast", @@ -660,9 +660,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adc00f486adfc9ce99f77d717836f0c5aa84965eb0b4f051f4e83f7cab53f8b" +checksum = "a12aa0eb539080d55c3f2d45a67c3b58b6b0773c1a3ca2dfec66d58c97fd66ca" dependencies = [ "futures-channel", "futures-core", @@ -675,9 +675,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74ed2411805f6e4e3d9bc904c95d5d423b89b3b25dc0250aa74729de20629ff9" +checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888" dependencies = [ "futures-core", "futures-sink", @@ -685,15 +685,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af51b1b4a7fdff033703db39de8802c673eb91855f2e0d47dcf3bf2c0ef01f99" +checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d" [[package]] name = "futures-executor" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d0d535a57b87e1ae31437b892713aee90cd2d7b0ee48727cd11fc72ef54761c" +checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c" dependencies = [ "futures-core", "futures-task", @@ -702,40 +702,40 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b0e06c393068f3a6ef246c75cdca793d6a46347e75286933e5e75fd2fd11582" +checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377" [[package]] name = "futures-macro" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54913bae956fb8df7f4dc6fc90362aa72e69148e3f39041fbe8742d21e0ac57" +checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb" dependencies = [ "autocfg", "proc-macro-hack", - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", - "syn 1.0.75", + "syn 1.0.76", ] [[package]] name = "futures-sink" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0f30aaa67363d119812743aa5f33c201a7a66329f97d1a887022971feea4b53" +checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11" [[package]] name = "futures-task" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe54a98670017f3be909561f6ad13e810d9a51f3f061b902062ca3da80799f2" +checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99" [[package]] name = "futures-util" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eb846bfd58e44a8481a00049e82c43e0ccb5d61f8dc071057cb19249dd4d78" +checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481" dependencies = [ "autocfg", "futures-channel", @@ -811,7 +811,7 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7f3675cfef6a30c8031cf9e6493ebdc3bb3272a3fea3923c4210d1830e6a472" dependencies = [ - "bytes 1.0.1", + "bytes 1.1.0", "fnv", "futures-core", "futures-sink", @@ -832,9 +832,9 @@ checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3" [[package]] name = "handlebars" -version = "4.1.2" +version = "4.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd85ecabdb47308d28d3a4113224fefcab2510ccb4e463aee0a1362eb84c756a" +checksum = "66b09e2322d20d14bc2572401ce7c1d60b4748580a76c230ed9c1f8938f0c833" dependencies = [ "log 0.4.14", "pest", @@ -900,9 +900,9 @@ dependencies = [ "log 0.4.14", "mac", "markup5ever", - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", - "syn 1.0.75", + "syn 1.0.76", ] [[package]] @@ -911,7 +911,7 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11" dependencies = [ - "bytes 1.0.1", + "bytes 1.1.0", "fnv", "itoa", ] @@ -922,7 +922,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "399c583b2979440c60be0821a6199eca73bc3c8dcd9d070d75ac726e2c6186e5" dependencies = [ - "bytes 1.0.1", + "bytes 1.1.0", "http", "pin-project-lite", ] @@ -960,11 +960,11 @@ dependencies = [ [[package]] name = "hyper" -version = "0.14.11" +version = "0.14.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b61cf2d1aebcf6e6352c97b81dc2244ca29194be1b276f5d8ad5c6330fffb11" +checksum = "13f67199e765030fa08fe0bd581af683f0d5bc04ea09c2b1102012c5fb90e7fd" dependencies = [ - "bytes 1.0.1", + "bytes 1.1.0", "futures-channel", "futures-core", "futures-util", @@ -1000,8 +1000,8 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ - "bytes 1.0.1", - "hyper 0.14.11", + "bytes 1.1.0", + "hyper 0.14.12", "native-tls", "tokio", "tokio-native-tls", @@ -1081,9 +1081,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.53" +version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4bf49d50e2961077d9c99f4b7997d770a1114f087c3c2e0069b36c13fc2979d" +checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" dependencies = [ "wasm-bindgen", ] @@ -1153,9 +1153,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.100" +version = "0.2.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1fa8cddc8fbbee11227ef194b5317ed014b8acbf15139bd716a18ad3fe99ec5" +checksum = "a2a5ac8f984bfcf3a823267e5fde638acc3325f6496633a5da6bb6eb2171e103" [[package]] name = "libsqlite3-sys" @@ -1170,9 +1170,9 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb" +checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" dependencies = [ "scopeguard", ] @@ -1273,9 +1273,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9753f12909fd8d923f75ae5c3258cae1ed3c8ec052e1b38c93c21a6d157f789c" dependencies = [ "migrations_internals", - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", - "syn 1.0.75", + "syn 1.0.76", ] [[package]] @@ -1488,9 +1488,9 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" dependencies = [ - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", - "syn 1.0.75", + "syn 1.0.76", ] [[package]] @@ -1524,9 +1524,9 @@ dependencies = [ [[package]] name = "object" -version = "0.26.1" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee2766204889d09937d00bfbb7fec56bb2a199e2ade963cab19185d8a6104c7c" +checksum = "39f37e50073ccad23b6d09bcb5b263f4e76d3bb6038e4a3c08e52162ffa8abc2" dependencies = [ "memchr", ] @@ -1571,9 +1571,9 @@ checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" [[package]] name = "openssl-src" -version = "111.15.0+1.1.1k" +version = "111.16.0+1.1.1l" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a5f6ae2ac04393b217ea9f700cd04fa9bf3d93fae2872069f3d15d908af70a" +checksum = "7ab2173f69416cf3ec12debb5823d244127d23a9b127d5a5189aa97c5fa2859f" dependencies = [ "cc", ] @@ -1631,13 +1631,13 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" dependencies = [ "instant", "lock_api", - "parking_lot_core 0.8.3", + "parking_lot_core 0.8.5", ] [[package]] @@ -1654,9 +1654,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" dependencies = [ "cfg-if 1.0.0", "instant", @@ -1753,9 +1753,9 @@ checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55" dependencies = [ "pest", "pest_meta", - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", - "syn 1.0.75", + "syn 1.0.76", ] [[package]] @@ -1875,9 +1875,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" +checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d" dependencies = [ "unicode-xid 0.2.2", ] @@ -1900,9 +1900,9 @@ dependencies = [ [[package]] name = "publicsuffix" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ac055aef7cc7a1caefbc65144be879e862467dcd9b8a8d57b64a13e7dce15d" +checksum = "292972edad6bbecc137ab84c5e36421a4a6c979ea31d3cc73540dd04315b33e1" dependencies = [ "byteorder", "hashbrown", @@ -1937,7 +1937,7 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" dependencies = [ - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", ] [[package]] @@ -1953,7 +1953,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "545c5bc2b880973c9c10e4067418407a0ccaa3091781d1671d46eb35107cb26f" dependencies = [ "log 0.4.14", - "parking_lot 0.11.1", + "parking_lot 0.11.2", "scheduled-thread-pool", ] @@ -2134,7 +2134,7 @@ checksum = "246e9f61b9bb77df069a947682be06e31ac43ea37862e244a69f177694ea6d22" dependencies = [ "async-compression", "base64 0.13.0", - "bytes 1.0.1", + "bytes 1.1.0", "cookie 0.14.4", "cookie_store 0.12.0", "encoding_rs", @@ -2142,7 +2142,7 @@ dependencies = [ "futures-util", "http", "http-body", - "hyper 0.14.11", + "hyper 0.14.12", "hyper-tls", "ipnet", "js-sys", @@ -2267,9 +2267,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dead70b0b5e03e9c814bcb6b01e03e68f7c57a80aa48c72ec92152ab3e818d49" +checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" [[package]] name = "rustc_version" @@ -2330,7 +2330,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc6f74fd1204073fa02d5d5d68bec8021be4c38690b61264b2fdb48083d0e7d7" dependencies = [ - "parking_lot 0.11.1", + "parking_lot 0.11.2", ] [[package]] @@ -2351,9 +2351,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.3.1" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23a2ac85147a3a11d77ecf1bc7166ec0b92febfa4461c37944e180f319ece467" +checksum = "525bc1abfda2e1998d152c45cf13e696f76d0a4972310b22fac1658b05df7c87" dependencies = [ "bitflags", "core-foundation", @@ -2364,9 +2364,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.3.0" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e4effb91b4b8b6fb7732e670b6cee160278ff8e6bf485c7805d9e319d76e284" +checksum = "a9dd14d83160b528b7bfd66439110573efcfbe281b17fc2ca9f39f550d619c7e" dependencies = [ "core-foundation-sys", "libc", @@ -2389,9 +2389,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.128" +version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1056a0db1978e9dbf0f6e4fca677f6f9143dc1c19de346f22cac23e422196834" +checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" dependencies = [ "serde_derive", ] @@ -2417,20 +2417,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.128" +version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13af2fbb8b60a8950d6c72a56d2095c28870367cc8e10c55e9745bac4995a2c4" +checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" dependencies = [ - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", - "syn 1.0.75", + "syn 1.0.76", ] [[package]] name = "serde_json" -version = "1.0.66" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127" +checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8" dependencies = [ "itoa", "ryu", @@ -2463,9 +2463,9 @@ dependencies = [ [[package]] name = "sha-1" -version = "0.9.7" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a0c8611594e2ab4ebbf06ec7cbbf0a99450b8570e96cbf5188b5d5f6ef18d81" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" dependencies = [ "block-buffer 0.9.0", "cfg-if 1.0.0", @@ -2482,9 +2482,9 @@ checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" [[package]] name = "sha2" -version = "0.9.5" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12" +checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa" dependencies = [ "block-buffer 0.9.0", "cfg-if 1.0.0", @@ -2506,9 +2506,9 @@ dependencies = [ [[package]] name = "siphasher" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "729a25c17d72b06c68cb47955d44fda88ad2d3e7d77e025663fdd69b93dd71a1" +checksum = "533494a8f9b724d33625ab53c6c4800f7cc445895924a8ef649222dcb76e938b" [[package]] name = "slab" @@ -2533,9 +2533,9 @@ checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" [[package]] name = "socket2" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "765f090f0e423d2b55843402a07915add955e7d60657db13707a159727326cad" +checksum = "5dc90fe6c7be1a323296982db1836d1ea9e47b6839496dde9a541bc496df3516" dependencies = [ "libc", "winapi 0.3.9", @@ -2588,11 +2588,11 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" dependencies = [ - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", "serde", "serde_derive", - "syn 1.0.75", + "syn 1.0.76", ] [[package]] @@ -2602,13 +2602,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" dependencies = [ "base-x", - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", "serde", "serde_derive", "serde_json", "sha1", - "syn 1.0.75", + "syn 1.0.76", ] [[package]] @@ -2638,7 +2638,7 @@ checksum = "f24c8e5e19d22a726626f1a5e16fe15b132dcf21d10177fa5a45ce7962996b97" dependencies = [ "phf_generator", "phf_shared", - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", ] @@ -2661,11 +2661,11 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.75" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7f58f7e8eaa0009c5fec437aabf511bd9933e4b2d7407bd05273c01a8906ea7" +checksum = "c6f107db402c2c2055242dbf4d2af0e69197202e9faacbef9571bbe47f5a1b84" dependencies = [ - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", "unicode-xid 0.2.2", ] @@ -2715,22 +2715,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.26" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" +checksum = "602eca064b2d83369e2b2f34b09c70b605402801927c65c11071ac911d299b88" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.26" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" +checksum = "bad553cc2c78e8de258400763a647e80e6d1b31ee237275d756f6836d204494c" dependencies = [ - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", - "syn 1.0.75", + "syn 1.0.76", ] [[package]] @@ -2785,17 +2785,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd3c141a1b43194f3f56a1411225df8646c55781d5f26db825b3d98507eb482f" dependencies = [ "proc-macro-hack", - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", "standback", - "syn 1.0.75", + "syn 1.0.76", ] [[package]] name = "tinyvec" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338" +checksum = "5241dd6f21443a3606b432718b166d3cedc962fd4b8bea54a8bc7f514ebda986" dependencies = [ "tinyvec_macros", ] @@ -2808,12 +2808,12 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cf844b23c6131f624accf65ce0e4e9956a8bb329400ea5bcc26ae3a5c20b0b" +checksum = "b4efe6fc2395938c8155973d7be49fe8d03a843726e285e100a8a383cc0154ce" dependencies = [ "autocfg", - "bytes 1.0.1", + "bytes 1.1.0", "libc", "memchr", "mio 0.7.13", @@ -2846,11 +2846,11 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1caa0b0c8d94a049db56b5acf8cba99dc0623aab1b26d5b5f5e2d945846b3592" +checksum = "08d3725d3efa29485e87311c5b699de63cde14b00ed4d256b8318aa30ca452cd" dependencies = [ - "bytes 1.0.1", + "bytes 1.1.0", "futures-core", "futures-sink", "log 0.4.14", @@ -2875,7 +2875,7 @@ checksum = "b18009e8be74bfb2e2cc59a63d078d95c042858a1ca1128a294e1f9ce225148b" dependencies = [ "digest 0.9.0", "hmac 0.11.0", - "sha-1 0.9.7", + "sha-1 0.9.8", "sha2", ] @@ -2887,9 +2887,9 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" [[package]] name = "tracing" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" +checksum = "c2ba9ab62b7d6497a8638dfda5e5c4fb3b2d5a7fca4118f2b96151c8ef1a437e" dependencies = [ "cfg-if 1.0.0", "log 0.4.14", @@ -2900,20 +2900,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42e6fa53307c8a17e4ccd4dc81cf5ec38db9209f59b222210375b54ee40d1e2" +checksum = "98863d0dd09fa59a1b79c6750ad80dbda6b75f4e71c437a6a1a8cb91a8bcbd77" dependencies = [ - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", - "syn 1.0.75", + "syn 1.0.76", ] [[package]] name = "tracing-core" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ca517f43f0fb96e0c3072ed5c275fe5eece87e8cb52f4a77b69226d3b1c9df8" +checksum = "46125608c26121c81b0c6d693eab5a420e416da7e43c426d2e8f7df8da8a3acf" dependencies = [ "lazy_static", ] @@ -2947,9 +2947,9 @@ checksum = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" [[package]] name = "typenum" -version = "1.13.0" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" +checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" [[package]] name = "u2f" @@ -3068,7 +3068,7 @@ name = "vaultwarden" version = "1.0.0" dependencies = [ "backtrace", - "bytes 1.0.1", + "bytes 1.1.0", "chashmap", "chrono", "chrono-tz", @@ -3171,9 +3171,9 @@ checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" [[package]] name = "wasm-bindgen" -version = "0.2.76" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce9b1b516211d33767048e5d47fa2a381ed8b76fc48d2ce4aa39877f9f183e0" +checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" dependencies = [ "cfg-if 1.0.0", "serde", @@ -3183,24 +3183,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.76" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfe8dc78e2326ba5f845f4b5bf548401604fa20b1dd1d365fb73b6c1d6364041" +checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" dependencies = [ "bumpalo", "lazy_static", "log 0.4.14", - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", - "syn 1.0.75", + "syn 1.0.76", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.26" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fded345a6559c2cfee778d562300c581f7d4ff3edb9b0d230d69800d213972" +checksum = "8e8d7523cb1f2a4c96c1317ca690031b714a51cc14e05f712446691f413f5d39" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -3210,9 +3210,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.76" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44468aa53335841d9d6b6c023eaab07c0cd4bddbcfdee3e2bb1e8d2cb8069fef" +checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" dependencies = [ "quote 1.0.9", "wasm-bindgen-macro-support", @@ -3220,28 +3220,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.76" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0195807922713af1e67dc66132c7328206ed9766af3858164fb583eedc25fbad" +checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" dependencies = [ - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", - "syn 1.0.75", + "syn 1.0.76", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.76" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acdb075a845574a1fa5f09fd77e43f7747599301ea3417a9fbffdeedfc1f4a29" +checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" [[package]] name = "web-sys" -version = "0.3.53" +version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224b2f6b67919060055ef1a67807367c2066ed520c3862cc013d26cf893a783c" +checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb" dependencies = [ "js-sys", "wasm-bindgen", @@ -3383,7 +3383,7 @@ dependencies = [ "hmac 0.10.1", "rand 0.8.4", "reqwest", - "sha-1 0.9.7", + "sha-1 0.9.8", "threadpool", "url 1.7.2", ] From 8af4b593fa7b3e83ed2fc0ff7f9478ee41756dc5 Mon Sep 17 00:00:00 2001 From: Ben Armstead Date: Thu, 16 Sep 2021 15:58:49 +0100 Subject: [PATCH 08/68] Update dependencies in cargo.toml --- Cargo.toml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2f9dc2e9..e132c6df 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,7 @@ reqwest = { version = "0.11.4", features = ["blocking", "json", "gzip", "brotli" # Used for custom short lived cookie jar cookie = "0.15.1" cookie_store = "0.15.0" -bytes = "1.0.1" +bytes = "1.1.0" url = "2.2.2" # multipart/form-data support @@ -53,8 +53,8 @@ rmpv = "1.0.0" chashmap = "2.2.2" # A generic serialization/deserialization framework -serde = { version = "1.0.128", features = ["derive"] } -serde_json = "1.0.66" +serde = { version = "1.0.130", features = ["derive"] } +serde_json = "1.0.68" # Logging log = "0.4.14" @@ -109,11 +109,11 @@ num-traits = "0.2.14" num-derive = "0.3.3" # Email libraries -tracing = { version = "0.1.26", features = ["log"] } # Needed to have lettre trace logging used when SMTP_DEBUG is enabled. +tracing = { version = "0.1.27", features = ["log"] } # Needed to have lettre trace logging used when SMTP_DEBUG is enabled. lettre = { version = "0.10.0-rc.3", features = ["smtp-transport", "builder", "serde", "native-tls", "hostname", "tracing"], default-features = false } # Template library -handlebars = { version = "4.1.2", features = ["dir_source"] } +handlebars = { version = "4.1.3", features = ["dir_source"] } # For favicon extraction from main website html5ever = "0.25.1" From a1a5e00ff5ea438242d964cd52606521694bc39f Mon Sep 17 00:00:00 2001 From: Ben Armstead Date: Thu, 16 Sep 2021 15:59:24 +0100 Subject: [PATCH 09/68] Update dependencies in Cargo.lock --- Cargo.lock | 304 ++++++++++++++++++++++++++--------------------------- 1 file changed, 152 insertions(+), 152 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5072c529..a1e9961a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -236,15 +236,15 @@ dependencies = [ [[package]] name = "bytes" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" [[package]] name = "cc" -version = "1.0.69" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" +checksum = "d26a6ce4b6a484fa3edb70f7efa6fc430fd2b87285fe8b84304fd0936faa0dc0" [[package]] name = "cfg-if" @@ -345,7 +345,7 @@ dependencies = [ "cookie 0.15.1", "idna 0.2.3", "log 0.4.14", - "publicsuffix 2.1.0", + "publicsuffix 2.1.1", "serde", "serde_json", "time 0.2.27", @@ -370,9 +370,9 @@ checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" [[package]] name = "cpufeatures" -version = "0.1.5" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef" +checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" dependencies = [ "libc", ] @@ -455,9 +455,9 @@ version = "0.3.0" source = "git+https://github.com/SergioBenitez/Devise.git?rev=e58b3ac9a#e58b3ac9afc3b6ff10a8aaf02a3e768a8f530089" dependencies = [ "bitflags", - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", - "syn 1.0.75", + "syn 1.0.76", ] [[package]] @@ -483,9 +483,9 @@ version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45f5098f628d02a7a0f68ddba586fb61e80edec3bdc1be3b921f4ceec60858d3" dependencies = [ - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", - "syn 1.0.75", + "syn 1.0.76", ] [[package]] @@ -579,9 +579,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd3aec53de10fe96d7d8c565eb17f2c687bb5518a2ec453b5b1252964526abe0" +checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" dependencies = [ "cfg-if 1.0.0", "crc32fast", @@ -660,9 +660,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adc00f486adfc9ce99f77d717836f0c5aa84965eb0b4f051f4e83f7cab53f8b" +checksum = "a12aa0eb539080d55c3f2d45a67c3b58b6b0773c1a3ca2dfec66d58c97fd66ca" dependencies = [ "futures-channel", "futures-core", @@ -675,9 +675,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74ed2411805f6e4e3d9bc904c95d5d423b89b3b25dc0250aa74729de20629ff9" +checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888" dependencies = [ "futures-core", "futures-sink", @@ -685,15 +685,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af51b1b4a7fdff033703db39de8802c673eb91855f2e0d47dcf3bf2c0ef01f99" +checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d" [[package]] name = "futures-executor" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d0d535a57b87e1ae31437b892713aee90cd2d7b0ee48727cd11fc72ef54761c" +checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c" dependencies = [ "futures-core", "futures-task", @@ -702,40 +702,40 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b0e06c393068f3a6ef246c75cdca793d6a46347e75286933e5e75fd2fd11582" +checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377" [[package]] name = "futures-macro" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54913bae956fb8df7f4dc6fc90362aa72e69148e3f39041fbe8742d21e0ac57" +checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb" dependencies = [ "autocfg", "proc-macro-hack", - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", - "syn 1.0.75", + "syn 1.0.76", ] [[package]] name = "futures-sink" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0f30aaa67363d119812743aa5f33c201a7a66329f97d1a887022971feea4b53" +checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11" [[package]] name = "futures-task" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe54a98670017f3be909561f6ad13e810d9a51f3f061b902062ca3da80799f2" +checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99" [[package]] name = "futures-util" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eb846bfd58e44a8481a00049e82c43e0ccb5d61f8dc071057cb19249dd4d78" +checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481" dependencies = [ "autocfg", "futures-channel", @@ -811,7 +811,7 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7f3675cfef6a30c8031cf9e6493ebdc3bb3272a3fea3923c4210d1830e6a472" dependencies = [ - "bytes 1.0.1", + "bytes 1.1.0", "fnv", "futures-core", "futures-sink", @@ -832,9 +832,9 @@ checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3" [[package]] name = "handlebars" -version = "4.1.2" +version = "4.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd85ecabdb47308d28d3a4113224fefcab2510ccb4e463aee0a1362eb84c756a" +checksum = "66b09e2322d20d14bc2572401ce7c1d60b4748580a76c230ed9c1f8938f0c833" dependencies = [ "log 0.4.14", "pest", @@ -900,9 +900,9 @@ dependencies = [ "log 0.4.14", "mac", "markup5ever", - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", - "syn 1.0.75", + "syn 1.0.76", ] [[package]] @@ -911,7 +911,7 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11" dependencies = [ - "bytes 1.0.1", + "bytes 1.1.0", "fnv", "itoa", ] @@ -922,7 +922,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "399c583b2979440c60be0821a6199eca73bc3c8dcd9d070d75ac726e2c6186e5" dependencies = [ - "bytes 1.0.1", + "bytes 1.1.0", "http", "pin-project-lite", ] @@ -960,11 +960,11 @@ dependencies = [ [[package]] name = "hyper" -version = "0.14.11" +version = "0.14.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b61cf2d1aebcf6e6352c97b81dc2244ca29194be1b276f5d8ad5c6330fffb11" +checksum = "13f67199e765030fa08fe0bd581af683f0d5bc04ea09c2b1102012c5fb90e7fd" dependencies = [ - "bytes 1.0.1", + "bytes 1.1.0", "futures-channel", "futures-core", "futures-util", @@ -1000,8 +1000,8 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ - "bytes 1.0.1", - "hyper 0.14.11", + "bytes 1.1.0", + "hyper 0.14.12", "native-tls", "tokio", "tokio-native-tls", @@ -1081,9 +1081,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.53" +version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4bf49d50e2961077d9c99f4b7997d770a1114f087c3c2e0069b36c13fc2979d" +checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" dependencies = [ "wasm-bindgen", ] @@ -1153,9 +1153,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.100" +version = "0.2.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1fa8cddc8fbbee11227ef194b5317ed014b8acbf15139bd716a18ad3fe99ec5" +checksum = "a2a5ac8f984bfcf3a823267e5fde638acc3325f6496633a5da6bb6eb2171e103" [[package]] name = "libsqlite3-sys" @@ -1170,9 +1170,9 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb" +checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" dependencies = [ "scopeguard", ] @@ -1273,9 +1273,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9753f12909fd8d923f75ae5c3258cae1ed3c8ec052e1b38c93c21a6d157f789c" dependencies = [ "migrations_internals", - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", - "syn 1.0.75", + "syn 1.0.76", ] [[package]] @@ -1488,9 +1488,9 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" dependencies = [ - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", - "syn 1.0.75", + "syn 1.0.76", ] [[package]] @@ -1524,9 +1524,9 @@ dependencies = [ [[package]] name = "object" -version = "0.26.1" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee2766204889d09937d00bfbb7fec56bb2a199e2ade963cab19185d8a6104c7c" +checksum = "39f37e50073ccad23b6d09bcb5b263f4e76d3bb6038e4a3c08e52162ffa8abc2" dependencies = [ "memchr", ] @@ -1571,9 +1571,9 @@ checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" [[package]] name = "openssl-src" -version = "111.15.0+1.1.1k" +version = "111.16.0+1.1.1l" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a5f6ae2ac04393b217ea9f700cd04fa9bf3d93fae2872069f3d15d908af70a" +checksum = "7ab2173f69416cf3ec12debb5823d244127d23a9b127d5a5189aa97c5fa2859f" dependencies = [ "cc", ] @@ -1631,13 +1631,13 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" dependencies = [ "instant", "lock_api", - "parking_lot_core 0.8.3", + "parking_lot_core 0.8.5", ] [[package]] @@ -1654,9 +1654,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" dependencies = [ "cfg-if 1.0.0", "instant", @@ -1753,9 +1753,9 @@ checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55" dependencies = [ "pest", "pest_meta", - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", - "syn 1.0.75", + "syn 1.0.76", ] [[package]] @@ -1875,9 +1875,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" +checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d" dependencies = [ "unicode-xid 0.2.2", ] @@ -1900,9 +1900,9 @@ dependencies = [ [[package]] name = "publicsuffix" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ac055aef7cc7a1caefbc65144be879e862467dcd9b8a8d57b64a13e7dce15d" +checksum = "292972edad6bbecc137ab84c5e36421a4a6c979ea31d3cc73540dd04315b33e1" dependencies = [ "byteorder", "hashbrown", @@ -1937,7 +1937,7 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" dependencies = [ - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", ] [[package]] @@ -1953,7 +1953,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "545c5bc2b880973c9c10e4067418407a0ccaa3091781d1671d46eb35107cb26f" dependencies = [ "log 0.4.14", - "parking_lot 0.11.1", + "parking_lot 0.11.2", "scheduled-thread-pool", ] @@ -2134,7 +2134,7 @@ checksum = "246e9f61b9bb77df069a947682be06e31ac43ea37862e244a69f177694ea6d22" dependencies = [ "async-compression", "base64 0.13.0", - "bytes 1.0.1", + "bytes 1.1.0", "cookie 0.14.4", "cookie_store 0.12.0", "encoding_rs", @@ -2142,7 +2142,7 @@ dependencies = [ "futures-util", "http", "http-body", - "hyper 0.14.11", + "hyper 0.14.12", "hyper-tls", "ipnet", "js-sys", @@ -2267,9 +2267,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dead70b0b5e03e9c814bcb6b01e03e68f7c57a80aa48c72ec92152ab3e818d49" +checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" [[package]] name = "rustc_version" @@ -2330,7 +2330,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc6f74fd1204073fa02d5d5d68bec8021be4c38690b61264b2fdb48083d0e7d7" dependencies = [ - "parking_lot 0.11.1", + "parking_lot 0.11.2", ] [[package]] @@ -2351,9 +2351,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.3.1" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23a2ac85147a3a11d77ecf1bc7166ec0b92febfa4461c37944e180f319ece467" +checksum = "525bc1abfda2e1998d152c45cf13e696f76d0a4972310b22fac1658b05df7c87" dependencies = [ "bitflags", "core-foundation", @@ -2364,9 +2364,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.3.0" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e4effb91b4b8b6fb7732e670b6cee160278ff8e6bf485c7805d9e319d76e284" +checksum = "a9dd14d83160b528b7bfd66439110573efcfbe281b17fc2ca9f39f550d619c7e" dependencies = [ "core-foundation-sys", "libc", @@ -2389,9 +2389,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.128" +version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1056a0db1978e9dbf0f6e4fca677f6f9143dc1c19de346f22cac23e422196834" +checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" dependencies = [ "serde_derive", ] @@ -2417,20 +2417,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.128" +version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13af2fbb8b60a8950d6c72a56d2095c28870367cc8e10c55e9745bac4995a2c4" +checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" dependencies = [ - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", - "syn 1.0.75", + "syn 1.0.76", ] [[package]] name = "serde_json" -version = "1.0.66" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127" +checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8" dependencies = [ "itoa", "ryu", @@ -2463,9 +2463,9 @@ dependencies = [ [[package]] name = "sha-1" -version = "0.9.7" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a0c8611594e2ab4ebbf06ec7cbbf0a99450b8570e96cbf5188b5d5f6ef18d81" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" dependencies = [ "block-buffer 0.9.0", "cfg-if 1.0.0", @@ -2482,9 +2482,9 @@ checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" [[package]] name = "sha2" -version = "0.9.5" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12" +checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa" dependencies = [ "block-buffer 0.9.0", "cfg-if 1.0.0", @@ -2506,9 +2506,9 @@ dependencies = [ [[package]] name = "siphasher" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "729a25c17d72b06c68cb47955d44fda88ad2d3e7d77e025663fdd69b93dd71a1" +checksum = "533494a8f9b724d33625ab53c6c4800f7cc445895924a8ef649222dcb76e938b" [[package]] name = "slab" @@ -2533,9 +2533,9 @@ checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" [[package]] name = "socket2" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "765f090f0e423d2b55843402a07915add955e7d60657db13707a159727326cad" +checksum = "5dc90fe6c7be1a323296982db1836d1ea9e47b6839496dde9a541bc496df3516" dependencies = [ "libc", "winapi 0.3.9", @@ -2588,11 +2588,11 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" dependencies = [ - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", "serde", "serde_derive", - "syn 1.0.75", + "syn 1.0.76", ] [[package]] @@ -2602,13 +2602,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" dependencies = [ "base-x", - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", "serde", "serde_derive", "serde_json", "sha1", - "syn 1.0.75", + "syn 1.0.76", ] [[package]] @@ -2638,7 +2638,7 @@ checksum = "f24c8e5e19d22a726626f1a5e16fe15b132dcf21d10177fa5a45ce7962996b97" dependencies = [ "phf_generator", "phf_shared", - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", ] @@ -2661,11 +2661,11 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.75" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7f58f7e8eaa0009c5fec437aabf511bd9933e4b2d7407bd05273c01a8906ea7" +checksum = "c6f107db402c2c2055242dbf4d2af0e69197202e9faacbef9571bbe47f5a1b84" dependencies = [ - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", "unicode-xid 0.2.2", ] @@ -2715,22 +2715,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.26" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" +checksum = "602eca064b2d83369e2b2f34b09c70b605402801927c65c11071ac911d299b88" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.26" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" +checksum = "bad553cc2c78e8de258400763a647e80e6d1b31ee237275d756f6836d204494c" dependencies = [ - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", - "syn 1.0.75", + "syn 1.0.76", ] [[package]] @@ -2785,17 +2785,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd3c141a1b43194f3f56a1411225df8646c55781d5f26db825b3d98507eb482f" dependencies = [ "proc-macro-hack", - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", "standback", - "syn 1.0.75", + "syn 1.0.76", ] [[package]] name = "tinyvec" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338" +checksum = "5241dd6f21443a3606b432718b166d3cedc962fd4b8bea54a8bc7f514ebda986" dependencies = [ "tinyvec_macros", ] @@ -2808,12 +2808,12 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cf844b23c6131f624accf65ce0e4e9956a8bb329400ea5bcc26ae3a5c20b0b" +checksum = "b4efe6fc2395938c8155973d7be49fe8d03a843726e285e100a8a383cc0154ce" dependencies = [ "autocfg", - "bytes 1.0.1", + "bytes 1.1.0", "libc", "memchr", "mio 0.7.13", @@ -2846,11 +2846,11 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1caa0b0c8d94a049db56b5acf8cba99dc0623aab1b26d5b5f5e2d945846b3592" +checksum = "08d3725d3efa29485e87311c5b699de63cde14b00ed4d256b8318aa30ca452cd" dependencies = [ - "bytes 1.0.1", + "bytes 1.1.0", "futures-core", "futures-sink", "log 0.4.14", @@ -2875,7 +2875,7 @@ checksum = "b18009e8be74bfb2e2cc59a63d078d95c042858a1ca1128a294e1f9ce225148b" dependencies = [ "digest 0.9.0", "hmac 0.11.0", - "sha-1 0.9.7", + "sha-1 0.9.8", "sha2", ] @@ -2887,9 +2887,9 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" [[package]] name = "tracing" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" +checksum = "c2ba9ab62b7d6497a8638dfda5e5c4fb3b2d5a7fca4118f2b96151c8ef1a437e" dependencies = [ "cfg-if 1.0.0", "log 0.4.14", @@ -2900,20 +2900,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42e6fa53307c8a17e4ccd4dc81cf5ec38db9209f59b222210375b54ee40d1e2" +checksum = "98863d0dd09fa59a1b79c6750ad80dbda6b75f4e71c437a6a1a8cb91a8bcbd77" dependencies = [ - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", - "syn 1.0.75", + "syn 1.0.76", ] [[package]] name = "tracing-core" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ca517f43f0fb96e0c3072ed5c275fe5eece87e8cb52f4a77b69226d3b1c9df8" +checksum = "46125608c26121c81b0c6d693eab5a420e416da7e43c426d2e8f7df8da8a3acf" dependencies = [ "lazy_static", ] @@ -2947,9 +2947,9 @@ checksum = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" [[package]] name = "typenum" -version = "1.13.0" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" +checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" [[package]] name = "u2f" @@ -3068,7 +3068,7 @@ name = "vaultwarden" version = "1.0.0" dependencies = [ "backtrace", - "bytes 1.0.1", + "bytes 1.1.0", "chashmap", "chrono", "chrono-tz", @@ -3171,9 +3171,9 @@ checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" [[package]] name = "wasm-bindgen" -version = "0.2.76" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce9b1b516211d33767048e5d47fa2a381ed8b76fc48d2ce4aa39877f9f183e0" +checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" dependencies = [ "cfg-if 1.0.0", "serde", @@ -3183,24 +3183,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.76" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfe8dc78e2326ba5f845f4b5bf548401604fa20b1dd1d365fb73b6c1d6364041" +checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" dependencies = [ "bumpalo", "lazy_static", "log 0.4.14", - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", - "syn 1.0.75", + "syn 1.0.76", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.26" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fded345a6559c2cfee778d562300c581f7d4ff3edb9b0d230d69800d213972" +checksum = "8e8d7523cb1f2a4c96c1317ca690031b714a51cc14e05f712446691f413f5d39" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -3210,9 +3210,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.76" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44468aa53335841d9d6b6c023eaab07c0cd4bddbcfdee3e2bb1e8d2cb8069fef" +checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" dependencies = [ "quote 1.0.9", "wasm-bindgen-macro-support", @@ -3220,28 +3220,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.76" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0195807922713af1e67dc66132c7328206ed9766af3858164fb583eedc25fbad" +checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" dependencies = [ - "proc-macro2 1.0.28", + "proc-macro2 1.0.29", "quote 1.0.9", - "syn 1.0.75", + "syn 1.0.76", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.76" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acdb075a845574a1fa5f09fd77e43f7747599301ea3417a9fbffdeedfc1f4a29" +checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" [[package]] name = "web-sys" -version = "0.3.53" +version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224b2f6b67919060055ef1a67807367c2066ed520c3862cc013d26cf893a783c" +checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb" dependencies = [ "js-sys", "wasm-bindgen", @@ -3383,7 +3383,7 @@ dependencies = [ "hmac 0.10.1", "rand 0.8.4", "reqwest", - "sha-1 0.9.7", + "sha-1 0.9.8", "threadpool", "url 1.7.2", ] From f36bd72a7f772fd108b31e5ca1f502238ab1ef00 Mon Sep 17 00:00:00 2001 From: BlackDex Date: Sat, 18 Sep 2021 14:22:14 +0200 Subject: [PATCH 10/68] Add Organization bulk actions support For user management within the organization view you are able to select multiple users to re-invite, confirm or delete them. These actions were not working which this PR fixes by adding support for these endpoints. This will make it easier to confirm and delete multiple users at once instead of having to do this one-by-one. --- src/api/core/organizations.rs | 182 ++++++++++++++++++++++++++++++---- 1 file changed, 165 insertions(+), 17 deletions(-) diff --git a/src/api/core/organizations.rs b/src/api/core/organizations.rs index fe8dab10..0f49a54e 100644 --- a/src/api/core/organizations.rs +++ b/src/api/core/organizations.rs @@ -35,12 +35,15 @@ pub fn routes() -> Vec { get_org_users, send_invite, reinvite_user, + bulk_reinvite_user, confirm_invite, + bulk_confirm_invite, accept_invite, get_user, edit_user, put_organization_user, delete_user, + bulk_delete_user, post_delete_user, post_org_import, list_policies, @@ -52,6 +55,7 @@ pub fn routes() -> Vec { get_plans_tax_rates, import, post_org_keys, + bulk_public_keys, ] } @@ -87,6 +91,12 @@ struct OrgKeyData { PublicKey: String, } +#[derive(Deserialize, Debug)] +#[allow(non_snake_case)] +struct OrgBulkIds { + Ids: Vec, +} + #[post("/organizations", data = "")] fn create_organization(headers: Headers, data: JsonUpcase, conn: DbConn) -> JsonResult { if !CONFIG.is_org_creation_allowed(&headers.user.email) { @@ -615,8 +625,44 @@ fn send_invite(org_id: String, data: JsonUpcase, headers: AdminHeade Ok(()) } +#[post("/organizations//users/reinvite", data = "")] +fn bulk_reinvite_user( + org_id: String, + data: JsonUpcase, + headers: AdminHeaders, + conn: DbConn, +) -> Json { + let data: OrgBulkIds = data.into_inner().data; + + let mut bulk_response = Vec::new(); + for org_user_id in data.Ids { + let err_msg = match _reinvite_user(&org_id, &org_user_id, &headers.user.email, &conn) { + Ok(_) => String::from(""), + Err(e) => format!("{:?}", e), + }; + + bulk_response.push(json!( + { + "Object": "OrganizationBulkConfirmResponseModel", + "Id": org_user_id, + "Error": err_msg + } + )) + } + + Json(json!({ + "Data": bulk_response, + "Object": "list", + "ContinuationToken": null + })) +} + #[post("/organizations//users//reinvite")] fn reinvite_user(org_id: String, user_org: String, headers: AdminHeaders, conn: DbConn) -> EmptyResult { + _reinvite_user(&org_id, &user_org, &headers.user.email, &conn) +} + +fn _reinvite_user(org_id: &str, user_org: &str, invited_by_email: &str, conn: &DbConn) -> EmptyResult { if !CONFIG.invitations_allowed() { err!("Invitations are not allowed.") } @@ -625,7 +671,7 @@ fn reinvite_user(org_id: String, user_org: String, headers: AdminHeaders, conn: err!("SMTP is not configured.") } - let user_org = match UserOrganization::find_by_uuid(&user_org, &conn) { + let user_org = match UserOrganization::find_by_uuid(user_org, conn) { Some(user_org) => user_org, None => err!("The user hasn't been invited to the organization."), }; @@ -634,12 +680,12 @@ fn reinvite_user(org_id: String, user_org: String, headers: AdminHeaders, conn: err!("The user is already accepted or confirmed to the organization") } - let user = match User::find_by_uuid(&user_org.user_uuid, &conn) { + let user = match User::find_by_uuid(&user_org.user_uuid, conn) { Some(user) => user, None => err!("User not found."), }; - let org_name = match Organization::find_by_uuid(&org_id, &conn) { + let org_name = match Organization::find_by_uuid(org_id, conn) { Some(org) => org.name, None => err!("Error looking up organization."), }; @@ -648,14 +694,14 @@ fn reinvite_user(org_id: String, user_org: String, headers: AdminHeaders, conn: mail::send_invite( &user.email, &user.uuid, - Some(org_id), + Some(org_id.to_string()), Some(user_org.uuid), &org_name, - Some(headers.user.email), + Some(invited_by_email.to_string()), )?; } else { let invitation = Invitation::new(user.email); - invitation.save(&conn)?; + invitation.save(conn)?; } Ok(()) @@ -728,6 +774,40 @@ fn accept_invite(_org_id: String, _org_user_id: String, data: JsonUpcase/users/confirm", data = "")] +fn bulk_confirm_invite(org_id: String, data: JsonUpcase, headers: AdminHeaders, conn: DbConn) -> Json { + let data = data.into_inner().data; + + let mut bulk_response = Vec::new(); + match data["Keys"].as_array() { + Some(keys) => { + for invite in keys { + let org_user_id = invite["Id"].as_str().unwrap_or_default(); + let user_key = invite["Key"].as_str().unwrap_or_default(); + let err_msg = match _confirm_invite(&org_id, org_user_id, user_key, &headers, &conn) { + Ok(_) => String::from(""), + Err(e) => format!("{:?}", e), + }; + + bulk_response.push(json!( + { + "Object": "OrganizationBulkConfirmResponseModel", + "Id": org_user_id, + "Error": err_msg + } + )); + } + } + None => error!("No keys to confirm"), + } + + Json(json!({ + "Data": bulk_response, + "Object": "list", + "ContinuationToken": null + })) +} + #[post("/organizations//users//confirm", data = "")] fn confirm_invite( org_id: String, @@ -737,8 +817,16 @@ fn confirm_invite( conn: DbConn, ) -> EmptyResult { let data = data.into_inner().data; + let user_key = data["Key"].as_str().unwrap_or_default(); + _confirm_invite(&org_id, &org_user_id, user_key, &headers, &conn) +} - let mut user_to_confirm = match UserOrganization::find_by_uuid_and_org(&org_user_id, &org_id, &conn) { +fn _confirm_invite(org_id: &str, org_user_id: &str, key: &str, headers: &AdminHeaders, conn: &DbConn) -> EmptyResult { + if key.is_empty() || org_user_id.is_empty() { + err!("Key or UserId is not set, unable to process request"); + } + + let mut user_to_confirm = match UserOrganization::find_by_uuid_and_org(org_user_id, org_id, conn) { Some(user) => user, None => err!("The specified user isn't a member of the organization"), }; @@ -752,24 +840,21 @@ fn confirm_invite( } user_to_confirm.status = UserOrgStatus::Confirmed as i32; - user_to_confirm.akey = match data["Key"].as_str() { - Some(key) => key.to_string(), - None => err!("Invalid key provided"), - }; + user_to_confirm.akey = key.to_string(); if CONFIG.mail_enabled() { - let org_name = match Organization::find_by_uuid(&org_id, &conn) { + let org_name = match Organization::find_by_uuid(org_id, conn) { Some(org) => org.name, None => err!("Error looking up organization."), }; - let address = match User::find_by_uuid(&user_to_confirm.user_uuid, &conn) { + let address = match User::find_by_uuid(&user_to_confirm.user_uuid, conn) { Some(user) => user.email, None => err!("Error looking up user."), }; mail::send_invite_confirmed(&address, &org_name)?; } - user_to_confirm.save(&conn) + user_to_confirm.save(conn) } #[get("/organizations//users/")] @@ -870,9 +955,40 @@ fn edit_user( user_to_edit.save(&conn) } +#[delete("/organizations//users", data = "")] +fn bulk_delete_user(org_id: String, data: JsonUpcase, headers: AdminHeaders, conn: DbConn) -> Json { + let data: OrgBulkIds = data.into_inner().data; + + let mut bulk_response = Vec::new(); + for org_user_id in data.Ids { + let err_msg = match _delete_user(&org_id, &org_user_id, &headers, &conn) { + Ok(_) => String::from(""), + Err(e) => format!("{:?}", e), + }; + + bulk_response.push(json!( + { + "Object": "OrganizationBulkConfirmResponseModel", + "Id": org_user_id, + "Error": err_msg + } + )) + } + + Json(json!({ + "Data": bulk_response, + "Object": "list", + "ContinuationToken": null + })) +} + #[delete("/organizations//users/")] fn delete_user(org_id: String, org_user_id: String, headers: AdminHeaders, conn: DbConn) -> EmptyResult { - let user_to_delete = match UserOrganization::find_by_uuid_and_org(&org_user_id, &org_id, &conn) { + _delete_user(&org_id, &org_user_id, &headers, &conn) +} + +fn _delete_user(org_id: &str, org_user_id: &str, headers: &AdminHeaders, conn: &DbConn) -> EmptyResult { + let user_to_delete = match UserOrganization::find_by_uuid_and_org(org_user_id, org_id, conn) { Some(user) => user, None => err!("User to delete isn't member of the organization"), }; @@ -883,14 +999,14 @@ fn delete_user(org_id: String, org_user_id: String, headers: AdminHeaders, conn: if user_to_delete.atype == UserOrgType::Owner { // Removing owner, check that there are at least another owner - let num_owners = UserOrganization::find_by_org_and_type(&org_id, UserOrgType::Owner as i32, &conn).len(); + let num_owners = UserOrganization::find_by_org_and_type(org_id, UserOrgType::Owner as i32, conn).len(); if num_owners <= 1 { err!("Can't delete the last owner") } } - user_to_delete.delete(&conn) + user_to_delete.delete(conn) } #[post("/organizations//users//delete")] @@ -898,6 +1014,38 @@ fn post_delete_user(org_id: String, org_user_id: String, headers: AdminHeaders, delete_user(org_id, org_user_id, headers, conn) } +#[post("/organizations//users/public-keys", data = "")] +fn bulk_public_keys(org_id: String, data: JsonUpcase, _headers: AdminHeaders, conn: DbConn) -> Json { + let data: OrgBulkIds = data.into_inner().data; + + let mut bulk_response = Vec::new(); + // Check all received UserOrg UUID's and find the matching User to retreive the public-key. + // If the user does not exists, just ignore it, and do not return any information regarding that UserOrg UUID. + // The web-vault will then ignore that user for the folowing steps. + for user_org_id in data.Ids { + match UserOrganization::find_by_uuid_and_org(&user_org_id, &org_id, &conn) { + Some(user_org) => match User::find_by_uuid(&user_org.user_uuid, &conn) { + Some(user) => bulk_response.push(json!( + { + "Object": "organizationUserPublicKeyResponseModel", + "Id": user_org_id, + "UserId": user.uuid, + "Key": user.public_key + } + )), + None => debug!("User doesn't exist"), + }, + None => debug!("UserOrg doesn't exist"), + } + } + + Json(json!({ + "Data": bulk_response, + "Object": "list", + "ContinuationToken": null + })) +} + use super::ciphers::update_cipher_from_data; use super::ciphers::CipherData; From b0a411b7333a5cf68fc3e78b67a61427c01d18fd Mon Sep 17 00:00:00 2001 From: BlackDex Date: Sat, 18 Sep 2021 19:49:44 +0200 Subject: [PATCH 11/68] Update some JS Libraries and fix small issues - Updated JS Libraries - Downgraded bootstrap.css to v5.0.2 which works with Bootstrap-Native. - Fixed issue with settings being able to open/collapse on some systems. - Added .js and .css to the exclude list for the end-of-file-fixer pre-commit --- .pre-commit-config.yaml | 1 + src/static/scripts/bootstrap-native.js | 101 +-- src/static/scripts/bootstrap.css | 882 +++++++----------------- src/static/scripts/datatables.css | 110 ++- src/static/scripts/datatables.js | 810 ++++++++++------------ src/static/templates/admin/settings.hbs | 15 +- 6 files changed, 763 insertions(+), 1156 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f9dfcbf4..b26d8445 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,6 +7,7 @@ repos: - id: check-json - id: check-toml - id: end-of-file-fixer + exclude: "(.*js$|.*css$)" - id: check-case-conflict - id: check-merge-conflict - id: detect-private-key diff --git a/src/static/scripts/bootstrap-native.js b/src/static/scripts/bootstrap-native.js index 82e63f27..2159b3db 100644 --- a/src/static/scripts/bootstrap-native.js +++ b/src/static/scripts/bootstrap-native.js @@ -1,5 +1,5 @@ /*! - * Native JavaScript for Bootstrap v4.0.4 (https://thednp.github.io/bootstrap.native/) + * Native JavaScript for Bootstrap v4.0.6 (https://thednp.github.io/bootstrap.native/) * Copyright 2015-2021 © dnp_theme * Licensed under MIT (https://github.com/thednp/bootstrap.native/blob/master/LICENSE) */ @@ -1467,19 +1467,26 @@ } } - const modalOpenClass = 'modal-open'; const modalBackdropClass = 'modal-backdrop'; + const offcanvasBackdropClass = 'offcanvas-backdrop'; const modalActiveSelector = `.modal.${showClass}`; const offcanvasActiveSelector = `.offcanvas.${showClass}`; - const overlay = document.createElement('div'); - overlay.setAttribute('class', `${modalBackdropClass}`); function getCurrentOpen() { return queryElement(`${modalActiveSelector},${offcanvasActiveSelector}`); } - function appendOverlay(hasFade) { + function toggleOverlayType(isModal) { + const targetClass = isModal ? modalBackdropClass : offcanvasBackdropClass; + [modalBackdropClass, offcanvasBackdropClass].forEach((c) => { + removeClass(overlay, c); + }); + addClass(overlay, targetClass); + } + + function appendOverlay(hasFade, isModal) { + toggleOverlayType(isModal); document.body.appendChild(overlay); if (hasFade) addClass(overlay, fadeClass); } @@ -1499,7 +1506,6 @@ if (!currentOpen) { removeClass(overlay, fadeClass); - removeClass(bd, modalOpenClass); bd.removeChild(overlay); resetScrollbar(); } @@ -1518,7 +1524,6 @@ const modalString = 'modal'; const modalComponent = 'Modal'; const modalSelector = `.${modalString}`; - // const modalActiveSelector = `.${modalString}.${showClass}`; const modalToggleSelector = `[${dataBsToggle}="${modalString}"]`; const modalDismissSelector = `[${dataBsDismiss}="${modalString}"]`; const modalStaticClass = `${modalString}-static`; @@ -1567,8 +1572,11 @@ } function afterModalHide(self) { - const { triggers } = self; - removeOverlay(); + const { triggers, options } = self; + if (!getCurrentOpen()) { + if (options.backdrop) removeOverlay(); + resetScrollbar(); + } self.element.style.paddingRight = ''; self.isAnimating = false; @@ -1594,9 +1602,8 @@ element.style.display = 'block'; setModalScrollbar(self); - if (!queryElement(modalActiveSelector)) { + if (!getCurrentOpen()) { document.body.style.overflow = 'hidden'; - addClass(document.body, modalOpenClass); } addClass(element, showClass); @@ -1609,16 +1616,15 @@ function beforeModalHide(self, force) { const { - element, relatedTarget, hasFade, + element, options, relatedTarget, hasFade, } = self; - const currentOpen = getCurrentOpen(); element.style.display = ''; // force can also be the transitionEvent object, we wanna make sure it's not // call is not forced and overlay is visible - if (!force && hasFade && hasClass(overlay, showClass) - && !currentOpen) { // AND no modal is visible + if (options.backdrop && !force && hasFade && hasClass(overlay, showClass) + && !getCurrentOpen()) { // AND no modal is visible hideOverlay(); emulateTransitionEnd(overlay, () => afterModalHide(self)); } else { @@ -1666,7 +1672,8 @@ if (self.isAnimating) return; - const { isStatic, modalDialog } = self; + const { options, isStatic, modalDialog } = self; + const { backdrop } = options; const { target } = e; const selectedText = document.getSelection().toString().length; const targetInsideDialog = modalDialog.contains(target); @@ -1676,7 +1683,7 @@ addClass(element, modalStaticClass); self.isAnimating = true; emulateTransitionEnd(modalDialog, () => staticTransitionEnd(self)); - } else if (dismiss || (!selectedText && !isStatic && !targetInsideDialog)) { + } else if (dismiss || (!selectedText && !isStatic && !targetInsideDialog && backdrop)) { self.relatedTarget = dismiss || null; self.hide(); e.preventDefault(); @@ -1734,8 +1741,9 @@ show() { const self = this; const { - element, isAnimating, hasFade, relatedTarget, + element, options, isAnimating, hasFade, relatedTarget, } = self; + const { backdrop } = options; let overlayDelay = 0; if (hasClass(element, showClass) && !isAnimating) return; @@ -1744,8 +1752,6 @@ element.dispatchEvent(showModalEvent); if (showModalEvent.defaultPrevented) return; - self.isAnimating = true; - // we elegantly hide any opened modal/offcanvas const currentOpen = getCurrentOpen(); if (currentOpen && currentOpen !== element) { @@ -1755,18 +1761,24 @@ that.hide(); } - if (!queryElement(`.${modalBackdropClass}`)) { - appendOverlay(hasFade); - } - overlayDelay = getElementTransitionDuration(overlay); + self.isAnimating = true; - if (!hasClass(overlay, showClass)) { - showOverlay(); - } + if (backdrop) { + if (!currentOpen && !hasClass(overlay, showClass)) { + appendOverlay(hasFade, 1); + } else { + toggleOverlayType(1); + } + overlayDelay = getElementTransitionDuration(overlay); - if (!currentOpen) { + if (!hasClass(overlay, showClass)) showOverlay(); setTimeout(() => beforeModalShow(self), overlayDelay); - } else beforeModalShow(self); + } else { + beforeModalShow(self); + if (currentOpen && hasClass(overlay, showClass)) { + hideOverlay(); + } + } } hide(force) { @@ -1863,7 +1875,6 @@ const { element, options } = self; if (!options.scroll) { - addClass(document.body, modalOpenClass); document.body.style.overflow = 'hidden'; setOffCanvasScrollbar(self); } @@ -1909,15 +1920,15 @@ const self = element[offcanvasComponent]; if (!self) return; - const { options, open, triggers } = self; + const { options, triggers } = self; const { target } = e; const trigger = target.closest(offcanvasToggleSelector); if (trigger && trigger.tagName === 'A') e.preventDefault(); - if (open && ((!element.contains(target) && options.backdrop + if ((!element.contains(target) && options.backdrop && (!trigger || (trigger && !triggers.includes(trigger)))) - || offCanvasDismiss.contains(target))) { + || offCanvasDismiss.contains(target)) { self.relatedTarget = target === offCanvasDismiss ? offCanvasDismiss : null; self.hide(); } @@ -1965,7 +1976,6 @@ element.removeAttribute(ariaModal); element.removeAttribute('role'); element.style.visibility = ''; - self.open = false; self.isAnimating = false; if (triggers.length) { @@ -1979,7 +1989,6 @@ if (options.backdrop) removeOverlay(); if (!options.scroll) { resetScrollbar(); - removeClass(document.body, modalOpenClass); } } @@ -2005,7 +2014,6 @@ .filter((btn) => getTargetElement(btn) === element); // additional instance property - self.open = false; self.isAnimating = false; self.scrollbarWidth = measureScrollbar(); @@ -2017,7 +2025,8 @@ // ======================== toggle() { const self = this; - return self.open ? self.hide() : self.show(); + if (hasClass(self.element, showClass)) self.hide(); + else self.show(); } show() { @@ -2027,7 +2036,7 @@ } = self; let overlayDelay = 0; - if (self.open || isAnimating) return; + if (hasClass(element, showClass) || isAnimating) return; showOffcanvasEvent.relatedTarget = relatedTarget || null; element.dispatchEvent(showOffcanvasEvent); @@ -2043,12 +2052,13 @@ that.hide(); } - self.open = true; self.isAnimating = true; if (options.backdrop) { - if (!queryElement(`.${modalBackdropClass}`)) { + if (!currentOpen) { appendOverlay(1); + } else { + toggleOverlayType(); } overlayDelay = getElementTransitionDuration(overlay); @@ -2056,14 +2066,19 @@ if (!hasClass(overlay, showClass)) showOverlay(); setTimeout(() => beforeOffcanvasShow(self), overlayDelay); - } else beforeOffcanvasShow(self); + } else { + beforeOffcanvasShow(self); + if (currentOpen && hasClass(overlay, showClass)) { + hideOverlay(); + } + } } hide(force) { const self = this; const { element, isAnimating, relatedTarget } = self; - if (!self.open || isAnimating) return; + if (!hasClass(element, showClass) || isAnimating) return; hideOffcanvasEvent.relatedTarget = relatedTarget || null; element.dispatchEvent(hideOffcanvasEvent); @@ -3483,7 +3498,7 @@ constructor: Tooltip, }; - var version = "4.0.4"; + var version = "4.0.6"; // import { alertInit } from '../components/alert-native.js'; // import { buttonInit } from '../components/button-native.js'; diff --git a/src/static/scripts/bootstrap.css b/src/static/scripts/bootstrap.css index da83b00f..892302a6 100644 --- a/src/static/scripts/bootstrap.css +++ b/src/static/scripts/bootstrap.css @@ -1,6 +1,6 @@ @charset "UTF-8"; /*! - * Bootstrap v5.1.0 (https://getbootstrap.com/) + * Bootstrap v5.0.2 (https://getbootstrap.com/) * Copyright 2011-2021 The Bootstrap Authors * Copyright 2011-2021 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) @@ -19,15 +19,6 @@ --bs-white: #fff; --bs-gray: #6c757d; --bs-gray-dark: #343a40; - --bs-gray-100: #f8f9fa; - --bs-gray-200: #e9ecef; - --bs-gray-300: #dee2e6; - --bs-gray-400: #ced4da; - --bs-gray-500: #adb5bd; - --bs-gray-600: #6c757d; - --bs-gray-700: #495057; - --bs-gray-800: #343a40; - --bs-gray-900: #212529; --bs-primary: #0d6efd; --bs-secondary: #6c757d; --bs-success: #198754; @@ -36,26 +27,9 @@ --bs-danger: #dc3545; --bs-light: #f8f9fa; --bs-dark: #212529; - --bs-primary-rgb: 13, 110, 253; - --bs-secondary-rgb: 108, 117, 125; - --bs-success-rgb: 25, 135, 84; - --bs-info-rgb: 13, 202, 240; - --bs-warning-rgb: 255, 193, 7; - --bs-danger-rgb: 220, 53, 69; - --bs-light-rgb: 248, 249, 250; - --bs-dark-rgb: 33, 37, 41; - --bs-white-rgb: 255, 255, 255; - --bs-black-rgb: 0, 0, 0; - --bs-body-rgb: 33, 37, 41; --bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; --bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0)); - --bs-body-font-family: var(--bs-font-sans-serif); - --bs-body-font-size: 1rem; - --bs-body-font-weight: 400; - --bs-body-line-height: 1.5; - --bs-body-color: #212529; - --bs-body-bg: #fff; } *, @@ -72,13 +46,12 @@ body { margin: 0; - font-family: var(--bs-body-font-family); - font-size: var(--bs-body-font-size); - font-weight: var(--bs-body-font-weight); - line-height: var(--bs-body-line-height); - color: var(--bs-body-color); - text-align: var(--bs-body-text-align); - background-color: var(--bs-body-bg); + font-family: var(--bs-font-sans-serif); + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #212529; + background-color: #fff; -webkit-text-size-adjust: 100%; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } @@ -712,6 +685,206 @@ progress { width: 16.6666666667%; } +@media (min-width: 576px) { + .col-sm { + flex: 1 0 0%; + } + + .row-cols-sm-auto > * { + flex: 0 0 auto; + width: auto; + } + + .row-cols-sm-1 > * { + flex: 0 0 auto; + width: 100%; + } + + .row-cols-sm-2 > * { + flex: 0 0 auto; + width: 50%; + } + + .row-cols-sm-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .row-cols-sm-4 > * { + flex: 0 0 auto; + width: 25%; + } + + .row-cols-sm-5 > * { + flex: 0 0 auto; + width: 20%; + } + + .row-cols-sm-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } +} +@media (min-width: 768px) { + .col-md { + flex: 1 0 0%; + } + + .row-cols-md-auto > * { + flex: 0 0 auto; + width: auto; + } + + .row-cols-md-1 > * { + flex: 0 0 auto; + width: 100%; + } + + .row-cols-md-2 > * { + flex: 0 0 auto; + width: 50%; + } + + .row-cols-md-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .row-cols-md-4 > * { + flex: 0 0 auto; + width: 25%; + } + + .row-cols-md-5 > * { + flex: 0 0 auto; + width: 20%; + } + + .row-cols-md-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } +} +@media (min-width: 992px) { + .col-lg { + flex: 1 0 0%; + } + + .row-cols-lg-auto > * { + flex: 0 0 auto; + width: auto; + } + + .row-cols-lg-1 > * { + flex: 0 0 auto; + width: 100%; + } + + .row-cols-lg-2 > * { + flex: 0 0 auto; + width: 50%; + } + + .row-cols-lg-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .row-cols-lg-4 > * { + flex: 0 0 auto; + width: 25%; + } + + .row-cols-lg-5 > * { + flex: 0 0 auto; + width: 20%; + } + + .row-cols-lg-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } +} +@media (min-width: 1200px) { + .col-xl { + flex: 1 0 0%; + } + + .row-cols-xl-auto > * { + flex: 0 0 auto; + width: auto; + } + + .row-cols-xl-1 > * { + flex: 0 0 auto; + width: 100%; + } + + .row-cols-xl-2 > * { + flex: 0 0 auto; + width: 50%; + } + + .row-cols-xl-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .row-cols-xl-4 > * { + flex: 0 0 auto; + width: 25%; + } + + .row-cols-xl-5 > * { + flex: 0 0 auto; + width: 20%; + } + + .row-cols-xl-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } +} +@media (min-width: 1400px) { + .col-xxl { + flex: 1 0 0%; + } + + .row-cols-xxl-auto > * { + flex: 0 0 auto; + width: auto; + } + + .row-cols-xxl-1 > * { + flex: 0 0 auto; + width: 100%; + } + + .row-cols-xxl-2 > * { + flex: 0 0 auto; + width: 50%; + } + + .row-cols-xxl-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .row-cols-xxl-4 > * { + flex: 0 0 auto; + width: 25%; + } + + .row-cols-xxl-5 > * { + flex: 0 0 auto; + width: 20%; + } + + .row-cols-xxl-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } +} .col-auto { flex: 0 0 auto; width: auto; @@ -882,45 +1055,6 @@ progress { } @media (min-width: 576px) { - .col-sm { - flex: 1 0 0%; - } - - .row-cols-sm-auto > * { - flex: 0 0 auto; - width: auto; - } - - .row-cols-sm-1 > * { - flex: 0 0 auto; - width: 100%; - } - - .row-cols-sm-2 > * { - flex: 0 0 auto; - width: 50%; - } - - .row-cols-sm-3 > * { - flex: 0 0 auto; - width: 33.3333333333%; - } - - .row-cols-sm-4 > * { - flex: 0 0 auto; - width: 25%; - } - - .row-cols-sm-5 > * { - flex: 0 0 auto; - width: 20%; - } - - .row-cols-sm-6 > * { - flex: 0 0 auto; - width: 16.6666666667%; - } - .col-sm-auto { flex: 0 0 auto; width: auto; @@ -1095,45 +1229,6 @@ progress { } } @media (min-width: 768px) { - .col-md { - flex: 1 0 0%; - } - - .row-cols-md-auto > * { - flex: 0 0 auto; - width: auto; - } - - .row-cols-md-1 > * { - flex: 0 0 auto; - width: 100%; - } - - .row-cols-md-2 > * { - flex: 0 0 auto; - width: 50%; - } - - .row-cols-md-3 > * { - flex: 0 0 auto; - width: 33.3333333333%; - } - - .row-cols-md-4 > * { - flex: 0 0 auto; - width: 25%; - } - - .row-cols-md-5 > * { - flex: 0 0 auto; - width: 20%; - } - - .row-cols-md-6 > * { - flex: 0 0 auto; - width: 16.6666666667%; - } - .col-md-auto { flex: 0 0 auto; width: auto; @@ -1299,54 +1394,15 @@ progress { .g-md-5, .gx-md-5 { - --bs-gutter-x: 3rem; - } - - .g-md-5, -.gy-md-5 { - --bs-gutter-y: 3rem; - } -} -@media (min-width: 992px) { - .col-lg { - flex: 1 0 0%; - } - - .row-cols-lg-auto > * { - flex: 0 0 auto; - width: auto; - } - - .row-cols-lg-1 > * { - flex: 0 0 auto; - width: 100%; - } - - .row-cols-lg-2 > * { - flex: 0 0 auto; - width: 50%; - } - - .row-cols-lg-3 > * { - flex: 0 0 auto; - width: 33.3333333333%; - } - - .row-cols-lg-4 > * { - flex: 0 0 auto; - width: 25%; - } - - .row-cols-lg-5 > * { - flex: 0 0 auto; - width: 20%; + --bs-gutter-x: 3rem; } - .row-cols-lg-6 > * { - flex: 0 0 auto; - width: 16.6666666667%; + .g-md-5, +.gy-md-5 { + --bs-gutter-y: 3rem; } - +} +@media (min-width: 992px) { .col-lg-auto { flex: 0 0 auto; width: auto; @@ -1521,45 +1577,6 @@ progress { } } @media (min-width: 1200px) { - .col-xl { - flex: 1 0 0%; - } - - .row-cols-xl-auto > * { - flex: 0 0 auto; - width: auto; - } - - .row-cols-xl-1 > * { - flex: 0 0 auto; - width: 100%; - } - - .row-cols-xl-2 > * { - flex: 0 0 auto; - width: 50%; - } - - .row-cols-xl-3 > * { - flex: 0 0 auto; - width: 33.3333333333%; - } - - .row-cols-xl-4 > * { - flex: 0 0 auto; - width: 25%; - } - - .row-cols-xl-5 > * { - flex: 0 0 auto; - width: 20%; - } - - .row-cols-xl-6 > * { - flex: 0 0 auto; - width: 16.6666666667%; - } - .col-xl-auto { flex: 0 0 auto; width: auto; @@ -1734,45 +1751,6 @@ progress { } } @media (min-width: 1400px) { - .col-xxl { - flex: 1 0 0%; - } - - .row-cols-xxl-auto > * { - flex: 0 0 auto; - width: auto; - } - - .row-cols-xxl-1 > * { - flex: 0 0 auto; - width: 100%; - } - - .row-cols-xxl-2 > * { - flex: 0 0 auto; - width: 50%; - } - - .row-cols-xxl-3 > * { - flex: 0 0 auto; - width: 33.3333333333%; - } - - .row-cols-xxl-4 > * { - flex: 0 0 auto; - width: 25%; - } - - .row-cols-xxl-5 > * { - flex: 0 0 auto; - width: 20%; - } - - .row-cols-xxl-6 > * { - flex: 0 0 auto; - width: 16.6666666667%; - } - .col-xxl-auto { flex: 0 0 auto; width: auto; @@ -2288,7 +2266,7 @@ progress { } .form-control-sm { - min-height: calc(1.5em + 0.5rem + 2px); + min-height: calc(1.5em + (0.5rem + 2px)); padding: 0.25rem 0.5rem; font-size: 0.875rem; border-radius: 0.2rem; @@ -2307,7 +2285,7 @@ progress { } .form-control-lg { - min-height: calc(1.5em + 1rem + 2px); + min-height: calc(1.5em + (1rem + 2px)); padding: 0.5rem 1rem; font-size: 1.25rem; border-radius: 0.3rem; @@ -2326,17 +2304,17 @@ progress { } textarea.form-control { - min-height: calc(1.5em + 0.75rem + 2px); + min-height: calc(1.5em + (0.75rem + 2px)); } textarea.form-control-sm { - min-height: calc(1.5em + 0.5rem + 2px); + min-height: calc(1.5em + (0.5rem + 2px)); } textarea.form-control-lg { - min-height: calc(1.5em + 1rem + 2px); + min-height: calc(1.5em + (1rem + 2px)); } .form-control-color { - width: 3rem; + max-width: 3rem; height: auto; padding: 0.375rem; } @@ -3452,16 +3430,6 @@ textarea.form-control-lg { transition: none; } } -.collapsing.collapse-horizontal { - width: 0; - height: auto; - transition: width 0.35s ease; -} -@media (prefers-reduced-motion: reduce) { - .collapsing.collapse-horizontal { - transition: none; - } -} .dropup, .dropend, @@ -4079,33 +4047,6 @@ textarea.form-control-lg { .navbar-expand-sm .navbar-toggler { display: none; } - .navbar-expand-sm .offcanvas-header { - display: none; - } - .navbar-expand-sm .offcanvas { - position: inherit; - bottom: 0; - z-index: 1000; - flex-grow: 1; - visibility: visible !important; - background-color: transparent; - border-right: 0; - border-left: 0; - transition: none; - transform: none; - } - .navbar-expand-sm .offcanvas-top, -.navbar-expand-sm .offcanvas-bottom { - height: auto; - border-top: 0; - border-bottom: 0; - } - .navbar-expand-sm .offcanvas-body { - display: flex; - flex-grow: 0; - padding: 0; - overflow-y: visible; - } } @media (min-width: 768px) { .navbar-expand-md { @@ -4132,33 +4073,6 @@ textarea.form-control-lg { .navbar-expand-md .navbar-toggler { display: none; } - .navbar-expand-md .offcanvas-header { - display: none; - } - .navbar-expand-md .offcanvas { - position: inherit; - bottom: 0; - z-index: 1000; - flex-grow: 1; - visibility: visible !important; - background-color: transparent; - border-right: 0; - border-left: 0; - transition: none; - transform: none; - } - .navbar-expand-md .offcanvas-top, -.navbar-expand-md .offcanvas-bottom { - height: auto; - border-top: 0; - border-bottom: 0; - } - .navbar-expand-md .offcanvas-body { - display: flex; - flex-grow: 0; - padding: 0; - overflow-y: visible; - } } @media (min-width: 992px) { .navbar-expand-lg { @@ -4185,33 +4099,6 @@ textarea.form-control-lg { .navbar-expand-lg .navbar-toggler { display: none; } - .navbar-expand-lg .offcanvas-header { - display: none; - } - .navbar-expand-lg .offcanvas { - position: inherit; - bottom: 0; - z-index: 1000; - flex-grow: 1; - visibility: visible !important; - background-color: transparent; - border-right: 0; - border-left: 0; - transition: none; - transform: none; - } - .navbar-expand-lg .offcanvas-top, -.navbar-expand-lg .offcanvas-bottom { - height: auto; - border-top: 0; - border-bottom: 0; - } - .navbar-expand-lg .offcanvas-body { - display: flex; - flex-grow: 0; - padding: 0; - overflow-y: visible; - } } @media (min-width: 1200px) { .navbar-expand-xl { @@ -4238,33 +4125,6 @@ textarea.form-control-lg { .navbar-expand-xl .navbar-toggler { display: none; } - .navbar-expand-xl .offcanvas-header { - display: none; - } - .navbar-expand-xl .offcanvas { - position: inherit; - bottom: 0; - z-index: 1000; - flex-grow: 1; - visibility: visible !important; - background-color: transparent; - border-right: 0; - border-left: 0; - transition: none; - transform: none; - } - .navbar-expand-xl .offcanvas-top, -.navbar-expand-xl .offcanvas-bottom { - height: auto; - border-top: 0; - border-bottom: 0; - } - .navbar-expand-xl .offcanvas-body { - display: flex; - flex-grow: 0; - padding: 0; - overflow-y: visible; - } } @media (min-width: 1400px) { .navbar-expand-xxl { @@ -4291,33 +4151,6 @@ textarea.form-control-lg { .navbar-expand-xxl .navbar-toggler { display: none; } - .navbar-expand-xxl .offcanvas-header { - display: none; - } - .navbar-expand-xxl .offcanvas { - position: inherit; - bottom: 0; - z-index: 1000; - flex-grow: 1; - visibility: visible !important; - background-color: transparent; - border-right: 0; - border-left: 0; - transition: none; - transform: none; - } - .navbar-expand-xxl .offcanvas-top, -.navbar-expand-xxl .offcanvas-bottom { - height: auto; - border-top: 0; - border-bottom: 0; - } - .navbar-expand-xxl .offcanvas-body { - display: flex; - flex-grow: 0; - padding: 0; - overflow-y: visible; - } } .navbar-expand { flex-wrap: nowrap; @@ -4343,33 +4176,6 @@ textarea.form-control-lg { .navbar-expand .navbar-toggler { display: none; } -.navbar-expand .offcanvas-header { - display: none; -} -.navbar-expand .offcanvas { - position: inherit; - bottom: 0; - z-index: 1000; - flex-grow: 1; - visibility: visible !important; - background-color: transparent; - border-right: 0; - border-left: 0; - transition: none; - transform: none; -} -.navbar-expand .offcanvas-top, -.navbar-expand .offcanvas-bottom { - height: auto; - border-top: 0; - border-bottom: 0; -} -.navbar-expand .offcanvas-body { - display: flex; - flex-grow: 0; - padding: 0; - overflow-y: visible; -} .navbar-light .navbar-brand { color: rgba(0, 0, 0, 0.9); @@ -4493,6 +4299,9 @@ textarea.form-control-lg { margin-bottom: 0; } +.card-link:hover { + text-decoration: none; +} .card-link + .card-link { margin-left: 1rem; } @@ -5368,10 +5177,10 @@ textarea.form-control-lg { box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); border-radius: 0.25rem; } -.toast.showing { +.toast:not(.showing):not(.show) { opacity: 0; } -.toast:not(.show) { +.toast.hide { display: none; } @@ -5411,7 +5220,7 @@ textarea.form-control-lg { position: fixed; top: 0; left: 0; - z-index: 1055; + z-index: 1060; display: none; width: 100%; height: 100%; @@ -5476,7 +5285,7 @@ textarea.form-control-lg { position: fixed; top: 0; left: 0; - z-index: 1050; + z-index: 1040; width: 100vw; height: 100vh; background-color: #000; @@ -6201,7 +6010,7 @@ textarea.form-control-lg { .offcanvas { position: fixed; bottom: 0; - z-index: 1045; + z-index: 1050; display: flex; flex-direction: column; max-width: 100%; @@ -6217,22 +6026,6 @@ textarea.form-control-lg { } } -.offcanvas-backdrop { - position: fixed; - top: 0; - left: 0; - z-index: 1040; - width: 100vw; - height: 100vh; - background-color: #000; -} -.offcanvas-backdrop.fade { - opacity: 0; -} -.offcanvas-backdrop.show { - opacity: 0.5; -} - .offcanvas-header { display: flex; align-items: center; @@ -6296,69 +6089,6 @@ textarea.form-control-lg { transform: none; } -.placeholder { - display: inline-block; - min-height: 1em; - vertical-align: middle; - cursor: wait; - background-color: currentColor; - opacity: 0.5; -} -.placeholder.btn::before { - display: inline-block; - content: ""; -} - -.placeholder-xs { - min-height: 0.6em; -} - -.placeholder-sm { - min-height: 0.8em; -} - -.placeholder-lg { - min-height: 1.2em; -} - -.placeholder-glow .placeholder { - -webkit-animation: placeholder-glow 2s ease-in-out infinite; - animation: placeholder-glow 2s ease-in-out infinite; -} - -@-webkit-keyframes placeholder-glow { - 50% { - opacity: 0.2; - } -} - -@keyframes placeholder-glow { - 50% { - opacity: 0.2; - } -} -.placeholder-wave { - -webkit-mask-image: linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%); - mask-image: linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%); - -webkit-mask-size: 200% 100%; - mask-size: 200% 100%; - -webkit-animation: placeholder-wave 2s linear infinite; - animation: placeholder-wave 2s linear infinite; -} - -@-webkit-keyframes placeholder-wave { - 100% { - -webkit-mask-position: -200% 0%; - mask-position: -200% 0%; - } -} - -@keyframes placeholder-wave { - 100% { - -webkit-mask-position: -200% 0%; - mask-position: -200% 0%; - } -} .clearfix::after { display: block; clear: both; @@ -6517,20 +6247,6 @@ textarea.form-control-lg { z-index: 1020; } } -.hstack { - display: flex; - flex-direction: row; - align-items: center; - align-self: stretch; -} - -.vstack { - display: flex; - flex: 1 1 auto; - flex-direction: column; - align-self: stretch; -} - .visually-hidden, .visually-hidden-focusable:not(:focus):not(:focus-within) { position: absolute !important; @@ -6560,15 +6276,6 @@ textarea.form-control-lg { white-space: nowrap; } -.vr { - display: inline-block; - align-self: stretch; - width: 1px; - min-height: 1em; - background-color: currentColor; - opacity: 0.25; -} - .align-baseline { vertical-align: baseline !important; } @@ -6605,26 +6312,6 @@ textarea.form-control-lg { float: none !important; } -.opacity-0 { - opacity: 0 !important; -} - -.opacity-25 { - opacity: 0.25 !important; -} - -.opacity-50 { - opacity: 0.5 !important; -} - -.opacity-75 { - opacity: 0.75 !important; -} - -.opacity-100 { - opacity: 1 !important; -} - .overflow-auto { overflow: auto !important; } @@ -7648,176 +7335,105 @@ textarea.form-control-lg { /* rtl:end:remove */ .text-primary { - --bs-text-opacity: 1; - color: rgba(var(--bs-primary-rgb), var(--bs-text-opacity)) !important; + color: #0d6efd !important; } .text-secondary { - --bs-text-opacity: 1; - color: rgba(var(--bs-secondary-rgb), var(--bs-text-opacity)) !important; + color: #6c757d !important; } .text-success { - --bs-text-opacity: 1; - color: rgba(var(--bs-success-rgb), var(--bs-text-opacity)) !important; + color: #198754 !important; } .text-info { - --bs-text-opacity: 1; - color: rgba(var(--bs-info-rgb), var(--bs-text-opacity)) !important; + color: #0dcaf0 !important; } .text-warning { - --bs-text-opacity: 1; - color: rgba(var(--bs-warning-rgb), var(--bs-text-opacity)) !important; + color: #ffc107 !important; } .text-danger { - --bs-text-opacity: 1; - color: rgba(var(--bs-danger-rgb), var(--bs-text-opacity)) !important; + color: #dc3545 !important; } .text-light { - --bs-text-opacity: 1; - color: rgba(var(--bs-light-rgb), var(--bs-text-opacity)) !important; + color: #f8f9fa !important; } .text-dark { - --bs-text-opacity: 1; - color: rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important; -} - -.text-black { - --bs-text-opacity: 1; - color: rgba(var(--bs-black-rgb), var(--bs-text-opacity)) !important; + color: #212529 !important; } .text-white { - --bs-text-opacity: 1; - color: rgba(var(--bs-white-rgb), var(--bs-text-opacity)) !important; + color: #fff !important; } .text-body { - --bs-text-opacity: 1; - color: rgba(var(--bs-body-rgb), var(--bs-text-opacity)) !important; + color: #212529 !important; } .text-muted { - --bs-text-opacity: 1; color: #6c757d !important; } .text-black-50 { - --bs-text-opacity: 1; color: rgba(0, 0, 0, 0.5) !important; } .text-white-50 { - --bs-text-opacity: 1; color: rgba(255, 255, 255, 0.5) !important; } .text-reset { - --bs-text-opacity: 1; color: inherit !important; } -.text-opacity-25 { - --bs-text-opacity: 0.25; -} - -.text-opacity-50 { - --bs-text-opacity: 0.5; -} - -.text-opacity-75 { - --bs-text-opacity: 0.75; -} - -.text-opacity-100 { - --bs-text-opacity: 1; -} - .bg-primary { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important; + background-color: #0d6efd !important; } .bg-secondary { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity)) !important; + background-color: #6c757d !important; } .bg-success { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important; + background-color: #198754 !important; } .bg-info { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-info-rgb), var(--bs-bg-opacity)) !important; + background-color: #0dcaf0 !important; } .bg-warning { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-warning-rgb), var(--bs-bg-opacity)) !important; + background-color: #ffc107 !important; } .bg-danger { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-danger-rgb), var(--bs-bg-opacity)) !important; + background-color: #dc3545 !important; } .bg-light { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-light-rgb), var(--bs-bg-opacity)) !important; + background-color: #f8f9fa !important; } .bg-dark { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-dark-rgb), var(--bs-bg-opacity)) !important; + background-color: #212529 !important; } -.bg-black { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-black-rgb), var(--bs-bg-opacity)) !important; +.bg-body { + background-color: #fff !important; } .bg-white { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-white-rgb), var(--bs-bg-opacity)) !important; -} - -.bg-body { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-body-rgb), var(--bs-bg-opacity)) !important; + background-color: #fff !important; } .bg-transparent { - --bs-bg-opacity: 1; background-color: transparent !important; } -.bg-opacity-10 { - --bs-bg-opacity: 0.1; -} - -.bg-opacity-25 { - --bs-bg-opacity: 0.25; -} - -.bg-opacity-50 { - --bs-bg-opacity: 0.5; -} - -.bg-opacity-75 { - --bs-bg-opacity: 0.75; -} - -.bg-opacity-100 { - --bs-bg-opacity: 1; -} - .bg-gradient { background-image: var(--bs-gradient) !important; } @@ -11218,4 +10834,4 @@ textarea.form-control-lg { } } -/*# sourceMappingURL=bootstrap.css.map */ +/*# sourceMappingURL=bootstrap.css.map */ \ No newline at end of file diff --git a/src/static/scripts/datatables.css b/src/static/scripts/datatables.css index db60b110..585f9390 100644 --- a/src/static/scripts/datatables.css +++ b/src/static/scripts/datatables.css @@ -4,13 +4,94 @@ * * To rebuild or modify this file with the latest versions of the included * software please visit: - * https://datatables.net/download/#bs5/dt-1.10.25 + * https://datatables.net/download/#bs5/dt-1.11.2 * * Included libraries: - * DataTables 1.10.25 + * DataTables 1.11.2 */ @charset "UTF-8"; +td.dt-control { + background: url("https://www.datatables.net/examples/resources/details_open.png") no-repeat center center; + cursor: pointer; +} + +tr.dt-hasChild td.dt-control { + background: url("https://www.datatables.net/examples/resources/details_close.png") no-repeat center center; +} + +table.dataTable th.dt-left, +table.dataTable td.dt-left { + text-align: left; +} +table.dataTable th.dt-center, +table.dataTable td.dt-center, +table.dataTable td.dataTables_empty { + text-align: center; +} +table.dataTable th.dt-right, +table.dataTable td.dt-right { + text-align: right; +} +table.dataTable th.dt-justify, +table.dataTable td.dt-justify { + text-align: justify; +} +table.dataTable th.dt-nowrap, +table.dataTable td.dt-nowrap { + white-space: nowrap; +} +table.dataTable thead th.dt-head-left, +table.dataTable thead td.dt-head-left, +table.dataTable tfoot th.dt-head-left, +table.dataTable tfoot td.dt-head-left { + text-align: left; +} +table.dataTable thead th.dt-head-center, +table.dataTable thead td.dt-head-center, +table.dataTable tfoot th.dt-head-center, +table.dataTable tfoot td.dt-head-center { + text-align: center; +} +table.dataTable thead th.dt-head-right, +table.dataTable thead td.dt-head-right, +table.dataTable tfoot th.dt-head-right, +table.dataTable tfoot td.dt-head-right { + text-align: right; +} +table.dataTable thead th.dt-head-justify, +table.dataTable thead td.dt-head-justify, +table.dataTable tfoot th.dt-head-justify, +table.dataTable tfoot td.dt-head-justify { + text-align: justify; +} +table.dataTable thead th.dt-head-nowrap, +table.dataTable thead td.dt-head-nowrap, +table.dataTable tfoot th.dt-head-nowrap, +table.dataTable tfoot td.dt-head-nowrap { + white-space: nowrap; +} +table.dataTable tbody th.dt-body-left, +table.dataTable tbody td.dt-body-left { + text-align: left; +} +table.dataTable tbody th.dt-body-center, +table.dataTable tbody td.dt-body-center { + text-align: center; +} +table.dataTable tbody th.dt-body-right, +table.dataTable tbody td.dt-body-right { + text-align: right; +} +table.dataTable tbody th.dt-body-justify, +table.dataTable tbody td.dt-body-justify { + text-align: justify; +} +table.dataTable tbody th.dt-body-nowrap, +table.dataTable tbody td.dt-body-nowrap { + white-space: nowrap; +} + /*! Bootstrap 5 integration for DataTables * * ©2020 SpryMedia Ltd, all rights reserved. @@ -143,21 +224,21 @@ div.dataTables_scrollHead table.dataTable { margin-bottom: 0 !important; } -div.dataTables_scrollBody table { +div.dataTables_scrollBody > table { border-top: none; margin-top: 0 !important; margin-bottom: 0 !important; } -div.dataTables_scrollBody table thead .sorting:before, -div.dataTables_scrollBody table thead .sorting_asc:before, -div.dataTables_scrollBody table thead .sorting_desc:before, -div.dataTables_scrollBody table thead .sorting:after, -div.dataTables_scrollBody table thead .sorting_asc:after, -div.dataTables_scrollBody table thead .sorting_desc:after { +div.dataTables_scrollBody > table > thead .sorting:before, +div.dataTables_scrollBody > table > thead .sorting_asc:before, +div.dataTables_scrollBody > table > thead .sorting_desc:before, +div.dataTables_scrollBody > table > thead .sorting:after, +div.dataTables_scrollBody > table > thead .sorting_asc:after, +div.dataTables_scrollBody > table > thead .sorting_desc:after { display: none; } -div.dataTables_scrollBody table tbody tr:first-child th, -div.dataTables_scrollBody table tbody tr:first-child td { +div.dataTables_scrollBody > table > tbody tr:first-child th, +div.dataTables_scrollBody > table > tbody tr:first-child td { border-top: none; } @@ -235,4 +316,11 @@ div.table-responsive > div.dataTables_wrapper > div.row > div[class^=col-]:last- padding-right: 0; } +table.dataTable.table-striped > tbody > tr:nth-of-type(2n+1) { + --bs-table-accent-bg: transparent; +} +table.dataTable.table-striped > tbody > tr.odd { + --bs-table-accent-bg: var(--bs-table-striped-bg); +} + diff --git a/src/static/scripts/datatables.js b/src/static/scripts/datatables.js index f8f1f3d2..93bbe80b 100644 --- a/src/static/scripts/datatables.js +++ b/src/static/scripts/datatables.js @@ -4,20 +4,20 @@ * * To rebuild or modify this file with the latest versions of the included * software please visit: - * https://datatables.net/download/#bs5/dt-1.10.25 + * https://datatables.net/download/#bs5/dt-1.11.2 * * Included libraries: - * DataTables 1.10.25 + * DataTables 1.11.2 */ -/*! DataTables 1.10.25 +/*! DataTables 1.11.2 * ©2008-2021 SpryMedia Ltd - datatables.net/license */ /** * @summary DataTables * @description Paginate, search and order HTML tables - * @version 1.10.25 + * @version 1.11.2 * @file jquery.dataTables.js * @author SpryMedia Ltd * @contact www.datatables.net @@ -65,7 +65,7 @@ } else { // Browser - factory( jQuery, window, document ); + window.DataTable = factory( jQuery, window, document ); } } (function( $, window, document, undefined ) { @@ -103,8 +103,17 @@ * } ); * } ); */ - var DataTable = function ( options ) + var DataTable = function ( selector, options ) { + // When creating with `new`, create a new DataTable, returning the API instance + if (this instanceof DataTable) { + return $(selector).DataTable(options); + } + else { + // Argument switching + options = selector; + } + /** * Perform a jQuery selector action on the table's TR elements (from the tbody) and * return the resulting jQuery object. @@ -1097,8 +1106,8 @@ dataType: 'json', url: oLanguage.sUrl, success: function ( json ) { - _fnLanguageCompat( json ); _fnCamelToHungarian( defaults.oLanguage, json ); + _fnLanguageCompat( json ); $.extend( true, oLanguage, json ); _fnCallbackFire( oSettings, null, 'i18n', [oSettings]); @@ -1313,10 +1322,11 @@ }; /* Must be done after everything which can be overridden by the state saving! */ + _fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' ); + if ( oInit.bStateSave ) { features.bStateSave = true; - _fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' ); _fnLoadState( oSettings, oInit, loadedInit ); } else { @@ -1687,6 +1697,227 @@ */ escapeRegex: function ( val ) { return val.replace( _re_escape_regex, '\\$1' ); + }, + + /** + * Create a function that will write to a nested object or array + * @param {*} source JSON notation string + * @returns Write function + */ + set: function ( source ) { + if ( $.isPlainObject( source ) ) { + /* Unlike get, only the underscore (global) option is used for for + * setting data since we don't know the type here. This is why an object + * option is not documented for `mData` (which is read/write), but it is + * for `mRender` which is read only. + */ + return DataTable.util.set( source._ ); + } + else if ( source === null ) { + // Nothing to do when the data source is null + return function () {}; + } + else if ( typeof source === 'function' ) { + return function (data, val, meta) { + source( data, 'set', val, meta ); + }; + } + else if ( typeof source === 'string' && (source.indexOf('.') !== -1 || + source.indexOf('[') !== -1 || source.indexOf('(') !== -1) ) + { + // Like the get, we need to get data from a nested object + var setData = function (data, val, src) { + var a = _fnSplitObjNotation( src ), b; + var aLast = a[a.length-1]; + var arrayNotation, funcNotation, o, innerSrc; + + for ( var i=0, iLen=a.length-1 ; i