diff --git a/.env.template b/.env.template index 6e164152b40..98bed0b7918 100644 --- a/.env.template +++ b/.env.template @@ -30,6 +30,10 @@ ## Define the size of the connection pool used for connecting to the database. # DATABASE_MAX_CONNS=10 +## Database timeout +## Timeout when acquiring database connection +# DATABASE_TIMEOUT=30 + ## Database connection initialization ## Allows SQL statements to be run whenever a new database connection is created. ## This is mainly useful for connection-scoped pragmas. @@ -77,7 +81,7 @@ # PUSH_INSTALLATION_ID=CHANGEME # PUSH_INSTALLATION_KEY=CHANGEME ## Don't change this unless you know what you're doing. -# PUSH_RELAY_BASE_URI=https://push.bitwarden.com +# PUSH_RELAY_URI=https://push.bitwarden.com ## Controls whether users are allowed to create Bitwarden Sends. ## This setting applies globally to all users. diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 99ac8108109..312ef5ca275 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,7 +24,7 @@ on: jobs: build: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 timeout-minutes: 120 # Make warnings errors, this is to prevent warnings slipping through. # This is done globally to prevent rebuilds when the RUSTFLAGS env variable changes. @@ -49,7 +49,7 @@ jobs: # Install dependencies - name: "Install dependencies Ubuntu" - run: sudo apt-get update && sudo apt-get install -y --no-install-recommends openssl sqlite build-essential libmariadb-dev-compat libpq-dev libssl-dev pkg-config + run: sudo apt-get update && sudo apt-get install -y --no-install-recommends openssl build-essential libmariadb-dev-compat libpq-dev libssl-dev pkg-config # End Install dependencies @@ -89,7 +89,12 @@ jobs: # Enable Rust Caching - - uses: Swatinem/rust-cache@2656b87321093db1cb55fbd73183d195214fdfd1 # v2.5.0 + - uses: Swatinem/rust-cache@dd05243424bd5c0e585e4b55eb2d7615cdd32f1f # v2.5.1 + with: + # Use a custom prefix-key to force a fresh start. This is sometimes needed with bigger changes. + # Like changing the build host from Ubuntu 20.04 to 22.04 for example. + # Only update when really needed! Use a .[.] format. + prefix-key: "v2023.07-rust" # End Enable Rust Caching diff --git a/.github/workflows/hadolint.yml b/.github/workflows/hadolint.yml index 2cae8ee0e08..f7c00fa7bfa 100644 --- a/.github/workflows/hadolint.yml +++ b/.github/workflows/hadolint.yml @@ -8,7 +8,7 @@ on: [ jobs: hadolint: name: Validate Dockerfile syntax - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 timeout-minutes: 30 steps: # Checkout the repo diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c562e24a077..62de863d0e0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,7 +24,7 @@ jobs: # 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-20.04 + runs-on: ubuntu-22.04 if: ${{ github.repository == 'dani-garcia/vaultwarden' }} outputs: should_skip: ${{ steps.skip_check.outputs.should_skip }} @@ -38,7 +38,7 @@ jobs: if: ${{ startsWith(github.ref, 'refs/heads/') }} docker-build: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 timeout-minutes: 120 needs: skip_check # Start a local docker registry to be used to generate multi-arch images. diff --git a/Cargo.lock b/Cargo.lock index cf215aa07ad..cf74b7f8864 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aho-corasick" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +checksum = "86b8f9420f797f2d9e935edf629310eb938a0d839f984e25327f3c7eed22300c" dependencies = [ "memchr", ] @@ -58,20 +58,21 @@ dependencies = [ [[package]] name = "argon2" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95c2fcf79ad1932ac6269a738109997a83c227c09b75842ae564dc8ede6a861c" +checksum = "b2e554a8638bdc1e4eae9984845306cc95f8a9208ba8d49c3859fd958b46774d" dependencies = [ "base64ct", "blake2", + "cpufeatures", "password-hash", ] [[package]] name = "async-channel" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" dependencies = [ "concurrent-queue", "event-listener", @@ -80,9 +81,9 @@ dependencies = [ [[package]] name = "async-compression" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0122885821398cc923ece939e24d1056a2384ee719432397fa9db87230ff11" +checksum = "62b74f44609f0f91493e3082d3734d98497e094777144380ea4db9f9905dd5b6" dependencies = [ "brotli", "flate2", @@ -101,7 +102,7 @@ dependencies = [ "async-lock", "async-task", "concurrent-queue", - "fastrand", + "fastrand 1.9.0", "futures-lite", "slab", ] @@ -135,7 +136,7 @@ dependencies = [ "log", "parking", "polling", - "rustix 0.37.22", + "rustix 0.37.23", "slab", "socket2 0.4.9", "waker-fn", @@ -143,9 +144,9 @@ dependencies = [ [[package]] name = "async-lock" -version = "2.7.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa24f727524730b077666307f2734b4a1a1c57acb79193127dcc8914d5242dd7" +checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" dependencies = [ "event-listener", ] @@ -163,7 +164,7 @@ dependencies = [ "cfg-if", "event-listener", "futures-lite", - "rustix 0.37.22", + "rustix 0.37.23", "signal-hook", "windows-sys", ] @@ -214,7 +215,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.28", ] [[package]] @@ -225,13 +226,13 @@ checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae" [[package]] name = "async-trait" -version = "0.1.70" +version = "0.1.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79fa67157abdfd688a259b6648808757db9347af834624f27ec646da976aee5d" +checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.28", ] [[package]] @@ -299,9 +300,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.3.3" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" [[package]] name = "blake2" @@ -331,7 +332,7 @@ dependencies = [ "async-lock", "async-task", "atomic-waker", - "fastrand", + "fastrand 1.9.0", "futures-lite", "log", ] @@ -413,9 +414,12 @@ checksum = "3a4f925191b4367301851c6d99b09890311d74b0d43f274c0b34c86d308a3663" [[package]] name = "cc" -version = "1.0.79" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "305fe645edc1442a0fa8b6726ba61d422798d37a52e12eaecf4b022ebbb88f01" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -541,9 +545,9 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cpufeatures" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" dependencies = [ "libc", ] @@ -624,12 +628,12 @@ dependencies = [ [[package]] name = "dashmap" -version = "5.4.0" +version = "5.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc" +checksum = "6943ae99c34386c84a470c499d3414f66502a41340aa895406e0d2e4a207b91d" dependencies = [ "cfg-if", - "hashbrown 0.12.3", + "hashbrown 0.14.0", "lock_api", "once_cell", "parking_lot_core", @@ -647,6 +651,12 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41b319d1b62ffbd002e057f36bebd1f42b9f97927c9577461d855f3513c4289f" +[[package]] +name = "deranged" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7684a49fb1af197853ef7b2ee694bc1f5b4179556f1e5710e1760c5db6f5e929" + [[package]] name = "devise" version = "0.4.1" @@ -673,11 +683,11 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35b50dba0afdca80b187392b24f2499a88c336d5a8493e4b4ccfb608708be56a" dependencies = [ - "bitflags 2.3.3", + "bitflags 2.4.0", "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.23", + "syn 2.0.28", ] [[package]] @@ -686,7 +696,7 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7a532c1f99a0f596f6960a60d1e119e91582b24b39e2d83a190e61262c3ef0c" dependencies = [ - "bitflags 2.3.3", + "bitflags 2.4.0", "byteorder", "chrono", "diesel_derives", @@ -709,7 +719,7 @@ dependencies = [ "diesel_table_macro_syntax", "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.28", ] [[package]] @@ -739,7 +749,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc5557efc453706fed5e4fa85006fe9817c224c3f480a34c7e5959fd700921c5" dependencies = [ - "syn 2.0.23", + "syn 2.0.28", ] [[package]] @@ -761,9 +771,9 @@ checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" [[package]] name = "either" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "email-encoding" @@ -807,15 +817,15 @@ dependencies = [ [[package]] name = "equivalent" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" dependencies = [ "errno-dragonfly", "libc", @@ -856,6 +866,12 @@ dependencies = [ "instant", ] +[[package]] +name = "fastrand" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" + [[package]] name = "fern" version = "0.6.2" @@ -974,7 +990,7 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" dependencies = [ - "fastrand", + "fastrand 1.9.0", "futures-core", "futures-io", "memchr", @@ -991,7 +1007,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.28", ] [[package]] @@ -1061,7 +1077,7 @@ checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", ] [[package]] @@ -1090,9 +1106,9 @@ dependencies = [ [[package]] name = "governor" -version = "0.5.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c390a940a5d157878dd057c78680a33ce3415bcd05b4799509ea44210914b4d5" +checksum = "821239e5672ff23e2a7060901fa622950bbd80b649cdaadd78d1c1767ed14eb4" dependencies = [ "cfg-if", "dashmap", @@ -1198,9 +1214,9 @@ dependencies = [ [[package]] name = "html5gum" -version = "0.5.3" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b4d5b6f92743baff720caafecfa172651b233609b0e2c80617cdb043dac73d" +checksum = "4c4e556171a058ba117bbe88b059fb37b6289023e007d2903ea6dca3a3cbff14" dependencies = [ "jetscii", ] @@ -1235,9 +1251,9 @@ checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" @@ -1403,20 +1419,20 @@ checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" [[package]] name = "is-terminal" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24fddda5af7e54bf7da53067d6e802dbcc381d0a8eef629df528e3ebf68755cb" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", - "rustix 0.38.2", + "rustix 0.38.8", "windows-sys", ] [[package]] name = "itoa" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "jetscii" @@ -1484,7 +1500,7 @@ dependencies = [ "base64 0.21.2", "email-encoding", "email_address", - "fastrand", + "fastrand 1.9.0", "futures-io", "futures-util", "hostname", @@ -1543,9 +1559,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" +checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" [[package]] name = "lock_api" @@ -1559,9 +1575,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.19" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" dependencies = [ "value-bag", ] @@ -1591,10 +1607,10 @@ dependencies = [ ] [[package]] -name = "mach" -version = "0.3.2" +name = "mach2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" +checksum = "6d0d1830bcd151a6fc4aea1369af235b36c1528fe976b8ff678683c9995eade8" dependencies = [ "libc", ] @@ -1611,7 +1627,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" dependencies = [ - "regex-automata", + "regex-automata 0.1.10", ] [[package]] @@ -1684,7 +1700,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "windows-sys", ] @@ -1787,7 +1803,7 @@ checksum = "9e6a0fd4f737c707bd9086cc16c925f294943eb62eb71499e9fd4cf71f8b9f4e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.28", ] [[package]] @@ -1802,9 +1818,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", ] @@ -1845,9 +1861,9 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "openssl" -version = "0.10.55" +version = "0.10.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d" +checksum = "729b745ad4a5575dd06a3e1af1414bd330ee561c01b3899eb584baeaa8def17e" dependencies = [ "bitflags 1.3.2", "cfg-if", @@ -1866,7 +1882,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.28", ] [[package]] @@ -1877,18 +1893,18 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "111.26.0+1.1.1u" +version = "111.27.0+1.1.1v" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efc62c9f12b22b8f5208c23a7200a442b2e5999f8bdf80233852122b5a4f6f37" +checksum = "06e8f197c82d7511c5b014030c9b1efeda40d7d5f99d23b4ceed3524a5e63f02" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.90" +version = "0.9.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6" +checksum = "866b5f16f90776b9bb8dc1e1802ac6f0513de3a7a7465867bfbc563dc737faac" dependencies = [ "cc", "libc", @@ -1954,31 +1970,31 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4b27ab7be369122c218afc2079489cdcb4b517c0a3fc386ff11e1fedfcc2b35" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] name = "pear" -version = "0.2.4" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ec95680a7087503575284e5063e14b694b7a9c0b065e5dceec661e0497127e8" +checksum = "61a386cd715229d399604b50d1361683fe687066f42d56f54be995bc6868f71c" dependencies = [ "inlinable_string", "pear_codegen", - "yansi", + "yansi 1.0.0-rc.1", ] [[package]] name = "pear_codegen" -version = "0.2.4" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9661a3a53f93f09f2ea882018e4d7c88f6ff2956d809a276060476fd8c879d3c" +checksum = "da9f0f13dac8069c139e8300a6510e3f4143ecf5259c60b116a9b271b4ca0d54" dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.23", + "syn 2.0.28", ] [[package]] @@ -1998,9 +2014,9 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pest" -version = "2.7.0" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73935e4d55e2abf7f130186537b19e7a4abc886a0252380b59248af473a3fc9" +checksum = "1acb4a4365a13f749a93f1a094a7805e5cfa0955373a9de860d962eaa3a5fe5a" dependencies = [ "thiserror", "ucd-trie", @@ -2008,9 +2024,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.0" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aef623c9bbfa0eedf5a0efba11a5ee83209c326653ca31ff019bec3a95bfff2b" +checksum = "666d00490d4ac815001da55838c500eafb0320019bbaa44444137c48b443a853" dependencies = [ "pest", "pest_generator", @@ -2018,22 +2034,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.0" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3e8cba4ec22bada7fc55ffe51e2deb6a0e0db2d0b7ab0b103acc80d2510c190" +checksum = "68ca01446f50dbda87c1786af8770d535423fa8a53aec03b8f4e3d7eb10e0929" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.28", ] [[package]] name = "pest_meta" -version = "2.7.0" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a01f71cb40bd8bb94232df14b946909e14660e33fc05db3e50ae2a82d7ea0ca0" +checksum = "56af0a30af74d0445c0bf6d9d051c979b516a1a5af790d251daee76005420a48" dependencies = [ "once_cell", "pest", @@ -2086,9 +2102,9 @@ checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" [[package]] name = "pin-project-lite" -version = "0.2.10" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" +checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05" [[package]] name = "pin-utils" @@ -2135,24 +2151,24 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.63" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] [[package]] name = "proc-macro2-diagnostics" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "606c4ba35817e2922a308af55ad51bab3645b59eae5c570d4a6cf07e36bd493b" +checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.28", "version_check", - "yansi", + "yansi 1.0.0-rc.1", ] [[package]] @@ -2173,16 +2189,16 @@ dependencies = [ [[package]] name = "quanta" -version = "0.9.3" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20afe714292d5e879d8b12740aa223c6a88f118af41870e8b6196e39a02238a8" +checksum = "a17e662a7a8291a865152364c20c7abc5e60486ab2001e8ec10b24862de0b9ab" dependencies = [ "crossbeam-utils", "libc", - "mach", + "mach2", "once_cell", "raw-cpuid", - "wasi 0.10.2+wasi-snapshot-preview1", + "wasi", "web-sys", "winapi", ] @@ -2195,9 +2211,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.29" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" dependencies = [ "proc-macro2", ] @@ -2269,33 +2285,34 @@ dependencies = [ [[package]] name = "ref-cast" -version = "1.0.17" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85d07b1a5f16b5548f4255a978c94259971aff73f39e8d67e8250e8b2f6667c3" +checksum = "61ef7e18e8841942ddb1cf845054f8008410030a3997875d9e49b7a363063df1" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.17" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a930b010d9effee5834317bb7ff406b76af7724348fd572b38705b4bd099fa92" +checksum = "2dfaf0c85b766276c797f3791f5bc6d5bd116b41d53049af2789666b0c0bc9fa" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.28", ] [[package]] name = "regex" -version = "1.8.4" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" +checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.7.2", + "regex-automata 0.3.6", + "regex-syntax 0.7.4", ] [[package]] @@ -2307,6 +2324,17 @@ dependencies = [ "regex-syntax 0.6.29", ] +[[package]] +name = "regex-automata" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.7.4", +] + [[package]] name = "regex-syntax" version = "0.6.29" @@ -2315,9 +2343,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" +checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" [[package]] name = "reqwest" @@ -2390,9 +2418,9 @@ dependencies = [ [[package]] name = "rmp" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44519172358fd6d58656c86ab8e7fbc9e1490c3e8f14d35ed78ca0dd07403c9f" +checksum = "7f9860a6cc38ed1da53456442089b4dfa35e7cedaa326df63017af88385e6b20" dependencies = [ "byteorder", "num-traits", @@ -2401,9 +2429,9 @@ dependencies = [ [[package]] name = "rmpv" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de8813b3a2f95c5138fe5925bfb8784175d88d6bff059ba8ce090aa891319754" +checksum = "2e0e0214a4a2b444ecce41a4025792fc31f77c7bb89c46d253953ea8c65701ec" dependencies = [ "num-traits", "rmp", @@ -2444,7 +2472,7 @@ dependencies = [ "tokio-util", "ubyte", "version_check", - "yansi", + "yansi 0.5.1", ] [[package]] @@ -2458,7 +2486,7 @@ dependencies = [ "proc-macro2", "quote", "rocket_http", - "syn 2.0.23", + "syn 2.0.28", "unicode-xid", ] @@ -2529,9 +2557,9 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustix" -version = "0.37.22" +version = "0.37.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8818fa822adcc98b18fedbb3632a6a33213c070556b5aa7c4c8cc21cff565c4c" +checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" dependencies = [ "bitflags 1.3.2", "errno", @@ -2543,22 +2571,22 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.2" +version = "0.38.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aabcb0461ebd01d6b79945797c27f8529082226cb630a9865a71870ff63532a4" +checksum = "19ed4fa021d81c8392ce04db050a3da9a60299050b7ae1cf482d862b54a7218f" dependencies = [ - "bitflags 2.3.3", + "bitflags 2.4.0", "errno", "libc", - "linux-raw-sys 0.4.3", + "linux-raw-sys 0.4.5", "windows-sys", ] [[package]] name = "rustls" -version = "0.21.2" +version = "0.21.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e32ca28af694bc1bbf399c33a516dbdf1c90090b8ab23c2bc24f834aa2247f5f" +checksum = "1d1feddffcfcc0b33f5c6ce9a29e341e4cd59c3f78e7ee45f4a40c038b1d6cbb" dependencies = [ "log", "ring", @@ -2577,9 +2605,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.100.1" +version = "0.101.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b" +checksum = "261e9e0888cba427c3316e6322805653c9425240b6fd96cee7cb671ab70ab8d0" dependencies = [ "ring", "untrusted", @@ -2587,15 +2615,15 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc31bd9b61a32c31f9650d18add92aa83a49ba979c143eefd27fe7177b05bd5f" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "ryu" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "same-file" @@ -2632,9 +2660,9 @@ checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sct" @@ -2648,9 +2676,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.1" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -2661,9 +2689,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" dependencies = [ "core-foundation-sys", "libc", @@ -2671,15 +2699,15 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" +checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" [[package]] name = "serde" -version = "1.0.166" +version = "1.0.183" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d01b7404f9d441d3ad40e6a636a7782c377d2abdbe4fa2440e2edcc2f4f10db8" +checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c" dependencies = [ "serde_derive", ] @@ -2696,20 +2724,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.166" +version = "1.0.183" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd83d6dde2b6b2d466e14d9d1acce8816dedee94f735eac6395808b3483c6d6" +checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.28", ] [[package]] name = "serde_json" -version = "1.0.99" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3" +checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" dependencies = [ "itoa", "ryu", @@ -2781,9 +2809,9 @@ dependencies = [ [[package]] name = "signal-hook" -version = "0.3.15" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" dependencies = [ "libc", "signal-hook-registry", @@ -2827,9 +2855,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" [[package]] name = "socket2" @@ -2906,9 +2934,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.23" +version = "2.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737" +checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" dependencies = [ "proc-macro2", "quote", @@ -2930,36 +2958,35 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.6.0" +version = "3.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" +checksum = "dc02fddf48964c42031a0b3fe0428320ecf3a73c401040fc0096f97794310651" dependencies = [ - "autocfg", "cfg-if", - "fastrand", + "fastrand 2.0.0", "redox_syscall", - "rustix 0.37.22", + "rustix 0.38.8", "windows-sys", ] [[package]] name = "thiserror" -version = "1.0.40" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.40" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.28", ] [[package]] @@ -2983,10 +3010,11 @@ dependencies = [ [[package]] name = "time" -version = "0.3.22" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" +checksum = "b0fdd63d58b18d663fbdf70e049f00a22c8e42be082203be7f26589213cd75ea" dependencies = [ + "deranged", "itoa", "libc", "num_threads", @@ -3003,9 +3031,9 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" +checksum = "eb71511c991639bb078fd5bf97757e03914361c48100d52878b8e52b46fb92cd" dependencies = [ "time-core", ] @@ -3027,11 +3055,10 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.29.1" +version = "1.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" +checksum = "40de3a2ba249dcb097e01be5e67a5ff53cf250397715a071a81543e8a832a920" dependencies = [ - "autocfg", "backtrace", "bytes", "libc", @@ -3040,7 +3067,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.4.9", + "socket2 0.5.3", "tokio-macros", "windows-sys", ] @@ -3053,7 +3080,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.28", ] [[package]] @@ -3127,9 +3154,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ebafdf5ad1220cb59e7d17cf4d2c72015297b75b19a10472f99b89225089240" +checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" dependencies = [ "serde", "serde_spanned", @@ -3148,9 +3175,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.19.11" +version = "0.19.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266f016b7f039eec8a1a80dfe6156b633d208b9fccca5e4db1d6775b0c4e34a7" +checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" dependencies = [ "indexmap 2.0.0", "serde", @@ -3198,7 +3225,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.28", ] [[package]] @@ -3327,9 +3354,9 @@ dependencies = [ [[package]] name = "ucd-trie" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" [[package]] name = "uncased" @@ -3349,9 +3376,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" [[package]] name = "unicode-normalization" @@ -3394,9 +3421,9 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "uuid" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d023da39d1fde5a8a3fe1f3e01ca9632ada0a63e9797de55a879d6e2236277be" +checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" dependencies = [ "getrandom", ] @@ -3511,12 +3538,6 @@ dependencies = [ "try-lock", ] -[[package]] -name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -3544,7 +3565,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.28", "wasm-bindgen-shared", ] @@ -3578,7 +3599,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.28", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3756,9 +3777,9 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "winnow" -version = "0.4.7" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca0ace3845f0d96209f0375e6d367e3eb87eb65d27d445bdc9f1843a26f39448" +checksum = "5504cc7644f4b593cbc05c4a55bf9bd4e94b867c3c0bd440934174d50482427d" dependencies = [ "memchr", ] @@ -3788,6 +3809,12 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" +[[package]] +name = "yansi" +version = "1.0.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1367295b8f788d371ce2dbc842c7b709c73ee1364d30351dd300ec2203b12377" + [[package]] name = "yubico" version = "0.11.0" diff --git a/Cargo.toml b/Cargo.toml index 8231c354ab7..6875db8ab99 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ name = "vaultwarden" version = "1.0.0" authors = ["Daniel GarcĂ­a "] edition = "2021" -rust-version = "1.68.2" +rust-version = "1.69.0" resolver = "2" repository = "https://github.com/dani-garcia/vaultwarden" @@ -51,7 +51,7 @@ dotenvy = { version = "0.15.7", default-features = false } once_cell = "1.18.0" # Numerical libraries -num-traits = "0.2.15" +num-traits = "0.2.16" num-derive = "0.4.0" # Web framework @@ -61,18 +61,18 @@ rocket_ws = { git = 'https://github.com/SergioBenitez/Rocket', rev = "ce441b5f46 # WebSockets libraries tokio-tungstenite = "0.19.0" -rmpv = "1.0.0" # MessagePack library +rmpv = "1.0.1" # MessagePack library # Concurrent HashMap used for WebSocket messaging and favicons -dashmap = "5.4.0" +dashmap = "5.5.0" # Async futures futures = "0.3.28" -tokio = { version = "1.29.1", features = ["rt-multi-thread", "fs", "io-util", "parking_lot", "time", "signal"] } +tokio = { version = "1.30.0", features = ["rt-multi-thread", "fs", "io-util", "parking_lot", "time", "signal"] } # A generic serialization/deserialization framework -serde = { version = "1.0.166", features = ["derive"] } -serde_json = "1.0.99" +serde = { version = "1.0.183", features = ["derive"] } +serde_json = "1.0.104" # A safe, extensible ORM and Query builder diesel = { version = "2.1.0", features = ["chrono", "r2d2"] } @@ -87,12 +87,12 @@ rand = { version = "0.8.5", features = ["small_rng"] } ring = "0.16.20" # UUID generation -uuid = { version = "1.4.0", features = ["v4"] } +uuid = { version = "1.4.1", features = ["v4"] } # Date and time libraries chrono = { version = "0.4.26", features = ["clock", "serde"], default-features = false } chrono-tz = "0.8.3" -time = "0.3.22" +time = "0.3.25" # Job scheduler job_scheduler_ng = "2.0.4" @@ -124,11 +124,11 @@ email_address = "0.2.4" handlebars = { version = "4.3.7", features = ["dir_source"] } # HTTP client (Used for favicons, version check, DUO and HIBP API) -reqwest = { version = "0.11.18", features = ["stream", "json", "gzip", "brotli", "socks", "cookies", "trust-dns"] } +reqwest = { version = "0.11.18", features = ["stream", "json", "deflate", "gzip", "brotli", "socks", "cookies", "trust-dns", "native-tls-alpn"] } # Favicon extraction libraries -html5gum = "0.5.3" -regex = { version = "1.8.4", features = ["std", "perf", "unicode-perl"], default-features = false } +html5gum = "0.5.7" +regex = { version = "1.9.3", features = ["std", "perf", "unicode-perl"], default-features = false } data-url = "0.3.0" bytes = "1.4.0" @@ -140,17 +140,17 @@ cookie = "0.16.2" cookie_store = "0.19.1" # Used by U2F, JWT and PostgreSQL -openssl = "0.10.55" +openssl = "0.10.56" # CLI argument parsing pico-args = "0.5.0" # Macro ident concatenation -paste = "1.0.13" -governor = "0.5.1" +paste = "1.0.14" +governor = "0.6.0" # Check client versions for specific features. -semver = "1.0.17" +semver = "1.0.18" # Allow overriding the default memory allocator # Mainly used for the musl builds, since the default musl malloc is very slow @@ -158,7 +158,7 @@ mimalloc = { version = "0.1.37", features = ["secure"], default-features = false which = "4.4.0" # Argon2 library with support for the PHC format -argon2 = "0.5.0" +argon2 = "0.5.1" # Reading a password from the cli for generating the Argon2id ADMIN_TOKEN rpassword = "7.2.0" diff --git a/docker/Dockerfile.j2 b/docker/Dockerfile.j2 index 04020d9042f..e1eb2d08c7e 100644 --- a/docker/Dockerfile.j2 +++ b/docker/Dockerfile.j2 @@ -2,25 +2,25 @@ # This file was generated using a Jinja2 template. # Please make your changes in `Dockerfile.j2` and then `make` the individual Dockerfiles. -{% set rust_version = "1.70.0" %} -{% set debian_version = "bullseye" %} +{% set rust_version = "1.71.1" %} +{% set debian_version = "bookworm" %} {% set alpine_version = "3.17" %} {% set build_stage_base_image = "docker.io/library/rust:%s-%s" % (rust_version, debian_version) %} {% if "alpine" in target_file %} {% if "amd64" in target_file %} -{% set build_stage_base_image = "docker.io/blackdex/rust-musl:x86_64-musl-stable-%s" % rust_version %} +{% set build_stage_base_image = "docker.io/blackdex/rust-musl:x86_64-musl-stable-%s-openssl3" % rust_version %} {% set runtime_stage_base_image = "docker.io/library/alpine:%s" % alpine_version %} {% set package_arch_target = "x86_64-unknown-linux-musl" %} {% elif "armv7" in target_file %} -{% set build_stage_base_image = "docker.io/blackdex/rust-musl:armv7-musleabihf-stable-%s" % rust_version %} +{% set build_stage_base_image = "docker.io/blackdex/rust-musl:armv7-musleabihf-stable-%s-openssl3" % rust_version %} {% set runtime_stage_base_image = "docker.io/balenalib/armv7hf-alpine:%s" % alpine_version %} {% set package_arch_target = "armv7-unknown-linux-musleabihf" %} {% elif "armv6" in target_file %} -{% set build_stage_base_image = "docker.io/blackdex/rust-musl:arm-musleabi-stable-%s" % rust_version %} +{% set build_stage_base_image = "docker.io/blackdex/rust-musl:arm-musleabi-stable-%s-openssl3" % rust_version %} {% set runtime_stage_base_image = "docker.io/balenalib/rpi-alpine:%s" % alpine_version %} {% set package_arch_target = "arm-unknown-linux-musleabi" %} {% elif "arm64" in target_file %} -{% set build_stage_base_image = "docker.io/blackdex/rust-musl:aarch64-musl-stable-%s" % rust_version %} +{% set build_stage_base_image = "docker.io/blackdex/rust-musl:aarch64-musl-stable-%s-openssl3" % rust_version %} {% set runtime_stage_base_image = "docker.io/balenalib/aarch64-alpine:%s" % alpine_version %} {% set package_arch_target = "aarch64-unknown-linux-musl" %} {% endif %} @@ -61,8 +61,8 @@ # https://docs.docker.com/develop/develop-images/multistage-build/ # https://whitfin.io/speeding-up-rust-docker-builds/ ####################### VAULT BUILD IMAGE ####################### -{% set vault_version = "v2023.5.0" %} -{% set vault_image_digest = "sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085" %} +{% set vault_version = "v2023.7.1" %} +{% set vault_image_digest = "sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f" %} # 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 @@ -91,6 +91,7 @@ ENV DEBIAN_FRONTEND=noninteractive \ TZ=UTC \ TERM=xterm-256color \ CARGO_HOME="/root/.cargo" \ + REGISTRIES_CRATES_IO_PROTOCOL=sparse \ USER="root" # Create CARGO_HOME folder and don't download rust docs @@ -98,13 +99,16 @@ RUN {{ mount_rust_cache -}} mkdir -pv "${CARGO_HOME}" \ && rustup set profile minimal {% if "alpine" in target_file %} +# Use PostgreSQL v15 during Alpine/MUSL builds instead of the default v11 +# Debian Bookworm already contains libpq v15 +ENV PQ_LIB_DIR="/usr/local/musl/pq15/lib" {% if "armv6" in target_file %} -# To be able to build the armv6 image with mimalloc we need to specifically specify the libatomic.a file location -ENV RUSTFLAGS='-Clink-arg=/usr/local/musl/{{ package_arch_target }}/lib/libatomic.a' +# To be able to build the armv6 image with mimalloc we need to tell the linker to also look for libatomic +ENV RUSTFLAGS='-Clink-arg=-latomic' {% endif %} {% elif "arm" in target_file %} # Install build dependencies for the {{ package_arch_name }} architecture -RUN dpkg --add-architecture {{ package_arch_name }} \ +RUN {{ mount_rust_cache -}} dpkg --add-architecture {{ package_arch_name }} \ && apt-get update \ && apt-get install -y \ --no-install-recommends \ @@ -211,13 +215,6 @@ RUN mkdir /data \ && rm -rf /var/lib/apt/lists/* {% endif %} -{% if "armv6" in target_file and "alpine" not in target_file %} -# In the Balena Bullseye images for armv6/rpi-debian there is a missing symlink. -# This symlink was there in the buster images, and for some reason this is needed. -RUN ln -v -s /lib/ld-linux-armhf.so.3 /lib/ld-linux.so.3 - -{% endif -%} - {% if "amd64" not in target_file %} RUN [ "cross-build-end" ] {% endif %} diff --git a/docker/amd64/Dockerfile b/docker/amd64/Dockerfile index de386381b66..ccaabe4713d 100644 --- a/docker/amd64/Dockerfile +++ b/docker/amd64/Dockerfile @@ -15,18 +15,18 @@ # - 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 docker.io/vaultwarden/web-vault:v2023.5.0 -# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2023.5.0 -# [docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085] +# $ docker pull docker.io/vaultwarden/web-vault:v2023.7.1 +# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2023.7.1 +# [docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f] # # - Conversely, to get the tag name from the digest: -# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085 -# [docker.io/vaultwarden/web-vault:v2023.5.0] +# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f +# [docker.io/vaultwarden/web-vault:v2023.7.1] # -FROM docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085 as vault +FROM docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f as vault ########################## BUILD IMAGE ########################## -FROM docker.io/library/rust:1.70.0-bullseye as build +FROM docker.io/library/rust:1.71.1-bookworm as build # Build time options to avoid dpkg warnings and help with reproducible builds. ENV DEBIAN_FRONTEND=noninteractive \ @@ -34,6 +34,7 @@ ENV DEBIAN_FRONTEND=noninteractive \ TZ=UTC \ TERM=xterm-256color \ CARGO_HOME="/root/.cargo" \ + REGISTRIES_CRATES_IO_PROTOCOL=sparse \ USER="root" # Create CARGO_HOME folder and don't download rust docs @@ -80,7 +81,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 docker.io/library/debian:bullseye-slim +FROM docker.io/library/debian:bookworm-slim ENV ROCKET_PROFILE="release" \ ROCKET_ADDRESS=0.0.0.0 \ diff --git a/docker/amd64/Dockerfile.alpine b/docker/amd64/Dockerfile.alpine index fd565f2d0e1..1b068ee54c2 100644 --- a/docker/amd64/Dockerfile.alpine +++ b/docker/amd64/Dockerfile.alpine @@ -15,18 +15,18 @@ # - 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 docker.io/vaultwarden/web-vault:v2023.5.0 -# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2023.5.0 -# [docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085] +# $ docker pull docker.io/vaultwarden/web-vault:v2023.7.1 +# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2023.7.1 +# [docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f] # # - Conversely, to get the tag name from the digest: -# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085 -# [docker.io/vaultwarden/web-vault:v2023.5.0] +# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f +# [docker.io/vaultwarden/web-vault:v2023.7.1] # -FROM docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085 as vault +FROM docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f as vault ########################## BUILD IMAGE ########################## -FROM docker.io/blackdex/rust-musl:x86_64-musl-stable-1.70.0 as build +FROM docker.io/blackdex/rust-musl:x86_64-musl-stable-1.71.1-openssl3 as build # Build time options to avoid dpkg warnings and help with reproducible builds. ENV DEBIAN_FRONTEND=noninteractive \ @@ -34,12 +34,16 @@ ENV DEBIAN_FRONTEND=noninteractive \ TZ=UTC \ TERM=xterm-256color \ CARGO_HOME="/root/.cargo" \ + REGISTRIES_CRATES_IO_PROTOCOL=sparse \ USER="root" # Create CARGO_HOME folder and don't download rust docs RUN mkdir -pv "${CARGO_HOME}" \ && rustup set profile minimal +# Use PostgreSQL v15 during Alpine/MUSL builds instead of the default v11 +# Debian Bookworm already contains libpq v15 +ENV PQ_LIB_DIR="/usr/local/musl/pq15/lib" # Creates a dummy project used to grab dependencies RUN USER=root cargo new --bin /app diff --git a/docker/amd64/Dockerfile.buildkit b/docker/amd64/Dockerfile.buildkit index 1bdaae0ff27..e5979dd2169 100644 --- a/docker/amd64/Dockerfile.buildkit +++ b/docker/amd64/Dockerfile.buildkit @@ -15,18 +15,18 @@ # - 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 docker.io/vaultwarden/web-vault:v2023.5.0 -# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2023.5.0 -# [docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085] +# $ docker pull docker.io/vaultwarden/web-vault:v2023.7.1 +# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2023.7.1 +# [docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f] # # - Conversely, to get the tag name from the digest: -# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085 -# [docker.io/vaultwarden/web-vault:v2023.5.0] +# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f +# [docker.io/vaultwarden/web-vault:v2023.7.1] # -FROM docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085 as vault +FROM docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f as vault ########################## BUILD IMAGE ########################## -FROM docker.io/library/rust:1.70.0-bullseye as build +FROM docker.io/library/rust:1.71.1-bookworm as build # Build time options to avoid dpkg warnings and help with reproducible builds. ENV DEBIAN_FRONTEND=noninteractive \ @@ -34,6 +34,7 @@ ENV DEBIAN_FRONTEND=noninteractive \ TZ=UTC \ TERM=xterm-256color \ CARGO_HOME="/root/.cargo" \ + REGISTRIES_CRATES_IO_PROTOCOL=sparse \ USER="root" # Create CARGO_HOME folder and don't download rust docs @@ -80,7 +81,7 @@ RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/. ######################## RUNTIME IMAGE ######################## # Create a new stage with a minimal image # because we already have a binary built -FROM docker.io/library/debian:bullseye-slim +FROM docker.io/library/debian:bookworm-slim ENV ROCKET_PROFILE="release" \ ROCKET_ADDRESS=0.0.0.0 \ diff --git a/docker/amd64/Dockerfile.buildkit.alpine b/docker/amd64/Dockerfile.buildkit.alpine index fc130f0e99a..60e5155c613 100644 --- a/docker/amd64/Dockerfile.buildkit.alpine +++ b/docker/amd64/Dockerfile.buildkit.alpine @@ -15,18 +15,18 @@ # - 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 docker.io/vaultwarden/web-vault:v2023.5.0 -# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2023.5.0 -# [docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085] +# $ docker pull docker.io/vaultwarden/web-vault:v2023.7.1 +# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2023.7.1 +# [docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f] # # - Conversely, to get the tag name from the digest: -# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085 -# [docker.io/vaultwarden/web-vault:v2023.5.0] +# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f +# [docker.io/vaultwarden/web-vault:v2023.7.1] # -FROM docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085 as vault +FROM docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f as vault ########################## BUILD IMAGE ########################## -FROM docker.io/blackdex/rust-musl:x86_64-musl-stable-1.70.0 as build +FROM docker.io/blackdex/rust-musl:x86_64-musl-stable-1.71.1-openssl3 as build # Build time options to avoid dpkg warnings and help with reproducible builds. ENV DEBIAN_FRONTEND=noninteractive \ @@ -34,12 +34,16 @@ ENV DEBIAN_FRONTEND=noninteractive \ TZ=UTC \ TERM=xterm-256color \ CARGO_HOME="/root/.cargo" \ + REGISTRIES_CRATES_IO_PROTOCOL=sparse \ 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 +# Use PostgreSQL v15 during Alpine/MUSL builds instead of the default v11 +# Debian Bookworm already contains libpq v15 +ENV PQ_LIB_DIR="/usr/local/musl/pq15/lib" # Creates a dummy project used to grab dependencies RUN USER=root cargo new --bin /app diff --git a/docker/arm64/Dockerfile b/docker/arm64/Dockerfile index 85abdd9ae1d..5d802e88b01 100644 --- a/docker/arm64/Dockerfile +++ b/docker/arm64/Dockerfile @@ -15,18 +15,18 @@ # - 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 docker.io/vaultwarden/web-vault:v2023.5.0 -# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2023.5.0 -# [docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085] +# $ docker pull docker.io/vaultwarden/web-vault:v2023.7.1 +# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2023.7.1 +# [docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f] # # - Conversely, to get the tag name from the digest: -# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085 -# [docker.io/vaultwarden/web-vault:v2023.5.0] +# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f +# [docker.io/vaultwarden/web-vault:v2023.7.1] # -FROM docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085 as vault +FROM docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f as vault ########################## BUILD IMAGE ########################## -FROM docker.io/library/rust:1.70.0-bullseye as build +FROM docker.io/library/rust:1.71.1-bookworm as build # Build time options to avoid dpkg warnings and help with reproducible builds. ENV DEBIAN_FRONTEND=noninteractive \ @@ -34,6 +34,7 @@ ENV DEBIAN_FRONTEND=noninteractive \ TZ=UTC \ TERM=xterm-256color \ CARGO_HOME="/root/.cargo" \ + REGISTRIES_CRATES_IO_PROTOCOL=sparse \ USER="root" # Create CARGO_HOME folder and don't download rust docs @@ -99,7 +100,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 docker.io/balenalib/aarch64-debian:bullseye +FROM docker.io/balenalib/aarch64-debian:bookworm ENV ROCKET_PROFILE="release" \ ROCKET_ADDRESS=0.0.0.0 \ diff --git a/docker/arm64/Dockerfile.alpine b/docker/arm64/Dockerfile.alpine index dda1dd3d929..b43e833079c 100644 --- a/docker/arm64/Dockerfile.alpine +++ b/docker/arm64/Dockerfile.alpine @@ -15,18 +15,18 @@ # - 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 docker.io/vaultwarden/web-vault:v2023.5.0 -# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2023.5.0 -# [docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085] +# $ docker pull docker.io/vaultwarden/web-vault:v2023.7.1 +# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2023.7.1 +# [docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f] # # - Conversely, to get the tag name from the digest: -# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085 -# [docker.io/vaultwarden/web-vault:v2023.5.0] +# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f +# [docker.io/vaultwarden/web-vault:v2023.7.1] # -FROM docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085 as vault +FROM docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f as vault ########################## BUILD IMAGE ########################## -FROM docker.io/blackdex/rust-musl:aarch64-musl-stable-1.70.0 as build +FROM docker.io/blackdex/rust-musl:aarch64-musl-stable-1.71.1-openssl3 as build # Build time options to avoid dpkg warnings and help with reproducible builds. ENV DEBIAN_FRONTEND=noninteractive \ @@ -34,12 +34,16 @@ ENV DEBIAN_FRONTEND=noninteractive \ TZ=UTC \ TERM=xterm-256color \ CARGO_HOME="/root/.cargo" \ + REGISTRIES_CRATES_IO_PROTOCOL=sparse \ USER="root" # Create CARGO_HOME folder and don't download rust docs RUN mkdir -pv "${CARGO_HOME}" \ && rustup set profile minimal +# Use PostgreSQL v15 during Alpine/MUSL builds instead of the default v11 +# Debian Bookworm already contains libpq v15 +ENV PQ_LIB_DIR="/usr/local/musl/pq15/lib" # Creates a dummy project used to grab dependencies RUN USER=root cargo new --bin /app diff --git a/docker/arm64/Dockerfile.buildkit b/docker/arm64/Dockerfile.buildkit index 7c533055c44..9c838965302 100644 --- a/docker/arm64/Dockerfile.buildkit +++ b/docker/arm64/Dockerfile.buildkit @@ -15,18 +15,18 @@ # - 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 docker.io/vaultwarden/web-vault:v2023.5.0 -# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2023.5.0 -# [docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085] +# $ docker pull docker.io/vaultwarden/web-vault:v2023.7.1 +# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2023.7.1 +# [docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f] # # - Conversely, to get the tag name from the digest: -# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085 -# [docker.io/vaultwarden/web-vault:v2023.5.0] +# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f +# [docker.io/vaultwarden/web-vault:v2023.7.1] # -FROM docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085 as vault +FROM docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f as vault ########################## BUILD IMAGE ########################## -FROM docker.io/library/rust:1.70.0-bullseye as build +FROM docker.io/library/rust:1.71.1-bookworm as build # Build time options to avoid dpkg warnings and help with reproducible builds. ENV DEBIAN_FRONTEND=noninteractive \ @@ -34,6 +34,7 @@ ENV DEBIAN_FRONTEND=noninteractive \ TZ=UTC \ TERM=xterm-256color \ CARGO_HOME="/root/.cargo" \ + REGISTRIES_CRATES_IO_PROTOCOL=sparse \ USER="root" # Create CARGO_HOME folder and don't download rust docs @@ -41,7 +42,7 @@ RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/. && rustup set profile minimal # Install build dependencies for the arm64 architecture -RUN dpkg --add-architecture arm64 \ +RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry dpkg --add-architecture arm64 \ && apt-get update \ && apt-get install -y \ --no-install-recommends \ @@ -99,7 +100,7 @@ RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/. ######################## RUNTIME IMAGE ######################## # Create a new stage with a minimal image # because we already have a binary built -FROM docker.io/balenalib/aarch64-debian:bullseye +FROM docker.io/balenalib/aarch64-debian:bookworm ENV ROCKET_PROFILE="release" \ ROCKET_ADDRESS=0.0.0.0 \ diff --git a/docker/arm64/Dockerfile.buildkit.alpine b/docker/arm64/Dockerfile.buildkit.alpine index e202b9655e8..abd345e241a 100644 --- a/docker/arm64/Dockerfile.buildkit.alpine +++ b/docker/arm64/Dockerfile.buildkit.alpine @@ -15,18 +15,18 @@ # - 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 docker.io/vaultwarden/web-vault:v2023.5.0 -# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2023.5.0 -# [docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085] +# $ docker pull docker.io/vaultwarden/web-vault:v2023.7.1 +# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2023.7.1 +# [docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f] # # - Conversely, to get the tag name from the digest: -# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085 -# [docker.io/vaultwarden/web-vault:v2023.5.0] +# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f +# [docker.io/vaultwarden/web-vault:v2023.7.1] # -FROM docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085 as vault +FROM docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f as vault ########################## BUILD IMAGE ########################## -FROM docker.io/blackdex/rust-musl:aarch64-musl-stable-1.70.0 as build +FROM docker.io/blackdex/rust-musl:aarch64-musl-stable-1.71.1-openssl3 as build # Build time options to avoid dpkg warnings and help with reproducible builds. ENV DEBIAN_FRONTEND=noninteractive \ @@ -34,12 +34,16 @@ ENV DEBIAN_FRONTEND=noninteractive \ TZ=UTC \ TERM=xterm-256color \ CARGO_HOME="/root/.cargo" \ + REGISTRIES_CRATES_IO_PROTOCOL=sparse \ 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 +# Use PostgreSQL v15 during Alpine/MUSL builds instead of the default v11 +# Debian Bookworm already contains libpq v15 +ENV PQ_LIB_DIR="/usr/local/musl/pq15/lib" # Creates a dummy project used to grab dependencies RUN USER=root cargo new --bin /app diff --git a/docker/armv6/Dockerfile b/docker/armv6/Dockerfile index 5048876f3a4..80c8be4e383 100644 --- a/docker/armv6/Dockerfile +++ b/docker/armv6/Dockerfile @@ -15,18 +15,18 @@ # - 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 docker.io/vaultwarden/web-vault:v2023.5.0 -# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2023.5.0 -# [docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085] +# $ docker pull docker.io/vaultwarden/web-vault:v2023.7.1 +# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2023.7.1 +# [docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f] # # - Conversely, to get the tag name from the digest: -# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085 -# [docker.io/vaultwarden/web-vault:v2023.5.0] +# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f +# [docker.io/vaultwarden/web-vault:v2023.7.1] # -FROM docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085 as vault +FROM docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f as vault ########################## BUILD IMAGE ########################## -FROM docker.io/library/rust:1.70.0-bullseye as build +FROM docker.io/library/rust:1.71.1-bookworm as build # Build time options to avoid dpkg warnings and help with reproducible builds. ENV DEBIAN_FRONTEND=noninteractive \ @@ -34,6 +34,7 @@ ENV DEBIAN_FRONTEND=noninteractive \ TZ=UTC \ TERM=xterm-256color \ CARGO_HOME="/root/.cargo" \ + REGISTRIES_CRATES_IO_PROTOCOL=sparse \ USER="root" # Create CARGO_HOME folder and don't download rust docs @@ -99,7 +100,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 docker.io/balenalib/rpi-debian:bullseye +FROM docker.io/balenalib/rpi-debian:bookworm ENV ROCKET_PROFILE="release" \ ROCKET_ADDRESS=0.0.0.0 \ @@ -119,10 +120,6 @@ RUN mkdir /data \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* -# In the Balena Bullseye images for armv6/rpi-debian there is a missing symlink. -# This symlink was there in the buster images, and for some reason this is needed. -RUN ln -v -s /lib/ld-linux-armhf.so.3 /lib/ld-linux.so.3 - RUN [ "cross-build-end" ] VOLUME /data diff --git a/docker/armv6/Dockerfile.alpine b/docker/armv6/Dockerfile.alpine index 4d1b4651e7b..71529bfaa35 100644 --- a/docker/armv6/Dockerfile.alpine +++ b/docker/armv6/Dockerfile.alpine @@ -15,18 +15,18 @@ # - 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 docker.io/vaultwarden/web-vault:v2023.5.0 -# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2023.5.0 -# [docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085] +# $ docker pull docker.io/vaultwarden/web-vault:v2023.7.1 +# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2023.7.1 +# [docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f] # # - Conversely, to get the tag name from the digest: -# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085 -# [docker.io/vaultwarden/web-vault:v2023.5.0] +# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f +# [docker.io/vaultwarden/web-vault:v2023.7.1] # -FROM docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085 as vault +FROM docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f as vault ########################## BUILD IMAGE ########################## -FROM docker.io/blackdex/rust-musl:arm-musleabi-stable-1.70.0 as build +FROM docker.io/blackdex/rust-musl:arm-musleabi-stable-1.71.1-openssl3 as build # Build time options to avoid dpkg warnings and help with reproducible builds. ENV DEBIAN_FRONTEND=noninteractive \ @@ -34,14 +34,18 @@ ENV DEBIAN_FRONTEND=noninteractive \ TZ=UTC \ TERM=xterm-256color \ CARGO_HOME="/root/.cargo" \ + REGISTRIES_CRATES_IO_PROTOCOL=sparse \ USER="root" # Create CARGO_HOME folder and don't download rust docs RUN mkdir -pv "${CARGO_HOME}" \ && rustup set profile minimal -# To be able to build the armv6 image with mimalloc we need to specifically specify the libatomic.a file location -ENV RUSTFLAGS='-Clink-arg=/usr/local/musl/arm-unknown-linux-musleabi/lib/libatomic.a' +# Use PostgreSQL v15 during Alpine/MUSL builds instead of the default v11 +# Debian Bookworm already contains libpq v15 +ENV PQ_LIB_DIR="/usr/local/musl/pq15/lib" +# To be able to build the armv6 image with mimalloc we need to tell the linker to also look for libatomic +ENV RUSTFLAGS='-Clink-arg=-latomic' # Creates a dummy project used to grab dependencies RUN USER=root cargo new --bin /app diff --git a/docker/armv6/Dockerfile.buildkit b/docker/armv6/Dockerfile.buildkit index 3d516d1073f..7a267c926a5 100644 --- a/docker/armv6/Dockerfile.buildkit +++ b/docker/armv6/Dockerfile.buildkit @@ -15,18 +15,18 @@ # - 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 docker.io/vaultwarden/web-vault:v2023.5.0 -# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2023.5.0 -# [docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085] +# $ docker pull docker.io/vaultwarden/web-vault:v2023.7.1 +# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2023.7.1 +# [docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f] # # - Conversely, to get the tag name from the digest: -# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085 -# [docker.io/vaultwarden/web-vault:v2023.5.0] +# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f +# [docker.io/vaultwarden/web-vault:v2023.7.1] # -FROM docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085 as vault +FROM docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f as vault ########################## BUILD IMAGE ########################## -FROM docker.io/library/rust:1.70.0-bullseye as build +FROM docker.io/library/rust:1.71.1-bookworm as build # Build time options to avoid dpkg warnings and help with reproducible builds. ENV DEBIAN_FRONTEND=noninteractive \ @@ -34,6 +34,7 @@ ENV DEBIAN_FRONTEND=noninteractive \ TZ=UTC \ TERM=xterm-256color \ CARGO_HOME="/root/.cargo" \ + REGISTRIES_CRATES_IO_PROTOCOL=sparse \ USER="root" # Create CARGO_HOME folder and don't download rust docs @@ -41,7 +42,7 @@ RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/. && rustup set profile minimal # Install build dependencies for the armel architecture -RUN dpkg --add-architecture armel \ +RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry dpkg --add-architecture armel \ && apt-get update \ && apt-get install -y \ --no-install-recommends \ @@ -99,7 +100,7 @@ RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/. ######################## RUNTIME IMAGE ######################## # Create a new stage with a minimal image # because we already have a binary built -FROM docker.io/balenalib/rpi-debian:bullseye +FROM docker.io/balenalib/rpi-debian:bookworm ENV ROCKET_PROFILE="release" \ ROCKET_ADDRESS=0.0.0.0 \ @@ -119,10 +120,6 @@ RUN mkdir /data \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* -# In the Balena Bullseye images for armv6/rpi-debian there is a missing symlink. -# This symlink was there in the buster images, and for some reason this is needed. -RUN ln -v -s /lib/ld-linux-armhf.so.3 /lib/ld-linux.so.3 - RUN [ "cross-build-end" ] VOLUME /data diff --git a/docker/armv6/Dockerfile.buildkit.alpine b/docker/armv6/Dockerfile.buildkit.alpine index 392512c60e3..9cb5e65c59d 100644 --- a/docker/armv6/Dockerfile.buildkit.alpine +++ b/docker/armv6/Dockerfile.buildkit.alpine @@ -15,18 +15,18 @@ # - 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 docker.io/vaultwarden/web-vault:v2023.5.0 -# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2023.5.0 -# [docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085] +# $ docker pull docker.io/vaultwarden/web-vault:v2023.7.1 +# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2023.7.1 +# [docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f] # # - Conversely, to get the tag name from the digest: -# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085 -# [docker.io/vaultwarden/web-vault:v2023.5.0] +# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f +# [docker.io/vaultwarden/web-vault:v2023.7.1] # -FROM docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085 as vault +FROM docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f as vault ########################## BUILD IMAGE ########################## -FROM docker.io/blackdex/rust-musl:arm-musleabi-stable-1.70.0 as build +FROM docker.io/blackdex/rust-musl:arm-musleabi-stable-1.71.1-openssl3 as build # Build time options to avoid dpkg warnings and help with reproducible builds. ENV DEBIAN_FRONTEND=noninteractive \ @@ -34,14 +34,18 @@ ENV DEBIAN_FRONTEND=noninteractive \ TZ=UTC \ TERM=xterm-256color \ CARGO_HOME="/root/.cargo" \ + REGISTRIES_CRATES_IO_PROTOCOL=sparse \ 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 -# To be able to build the armv6 image with mimalloc we need to specifically specify the libatomic.a file location -ENV RUSTFLAGS='-Clink-arg=/usr/local/musl/arm-unknown-linux-musleabi/lib/libatomic.a' +# Use PostgreSQL v15 during Alpine/MUSL builds instead of the default v11 +# Debian Bookworm already contains libpq v15 +ENV PQ_LIB_DIR="/usr/local/musl/pq15/lib" +# To be able to build the armv6 image with mimalloc we need to tell the linker to also look for libatomic +ENV RUSTFLAGS='-Clink-arg=-latomic' # Creates a dummy project used to grab dependencies RUN USER=root cargo new --bin /app diff --git a/docker/armv7/Dockerfile b/docker/armv7/Dockerfile index 025a7e6e651..3202bf7eed8 100644 --- a/docker/armv7/Dockerfile +++ b/docker/armv7/Dockerfile @@ -15,18 +15,18 @@ # - 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 docker.io/vaultwarden/web-vault:v2023.5.0 -# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2023.5.0 -# [docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085] +# $ docker pull docker.io/vaultwarden/web-vault:v2023.7.1 +# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2023.7.1 +# [docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f] # # - Conversely, to get the tag name from the digest: -# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085 -# [docker.io/vaultwarden/web-vault:v2023.5.0] +# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f +# [docker.io/vaultwarden/web-vault:v2023.7.1] # -FROM docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085 as vault +FROM docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f as vault ########################## BUILD IMAGE ########################## -FROM docker.io/library/rust:1.70.0-bullseye as build +FROM docker.io/library/rust:1.71.1-bookworm as build # Build time options to avoid dpkg warnings and help with reproducible builds. ENV DEBIAN_FRONTEND=noninteractive \ @@ -34,6 +34,7 @@ ENV DEBIAN_FRONTEND=noninteractive \ TZ=UTC \ TERM=xterm-256color \ CARGO_HOME="/root/.cargo" \ + REGISTRIES_CRATES_IO_PROTOCOL=sparse \ USER="root" # Create CARGO_HOME folder and don't download rust docs @@ -99,7 +100,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 docker.io/balenalib/armv7hf-debian:bullseye +FROM docker.io/balenalib/armv7hf-debian:bookworm ENV ROCKET_PROFILE="release" \ ROCKET_ADDRESS=0.0.0.0 \ diff --git a/docker/armv7/Dockerfile.alpine b/docker/armv7/Dockerfile.alpine index 490e184e0e7..2541e7b4341 100644 --- a/docker/armv7/Dockerfile.alpine +++ b/docker/armv7/Dockerfile.alpine @@ -15,18 +15,18 @@ # - 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 docker.io/vaultwarden/web-vault:v2023.5.0 -# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2023.5.0 -# [docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085] +# $ docker pull docker.io/vaultwarden/web-vault:v2023.7.1 +# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2023.7.1 +# [docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f] # # - Conversely, to get the tag name from the digest: -# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085 -# [docker.io/vaultwarden/web-vault:v2023.5.0] +# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f +# [docker.io/vaultwarden/web-vault:v2023.7.1] # -FROM docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085 as vault +FROM docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f as vault ########################## BUILD IMAGE ########################## -FROM docker.io/blackdex/rust-musl:armv7-musleabihf-stable-1.70.0 as build +FROM docker.io/blackdex/rust-musl:armv7-musleabihf-stable-1.71.1-openssl3 as build # Build time options to avoid dpkg warnings and help with reproducible builds. ENV DEBIAN_FRONTEND=noninteractive \ @@ -34,12 +34,16 @@ ENV DEBIAN_FRONTEND=noninteractive \ TZ=UTC \ TERM=xterm-256color \ CARGO_HOME="/root/.cargo" \ + REGISTRIES_CRATES_IO_PROTOCOL=sparse \ USER="root" # Create CARGO_HOME folder and don't download rust docs RUN mkdir -pv "${CARGO_HOME}" \ && rustup set profile minimal +# Use PostgreSQL v15 during Alpine/MUSL builds instead of the default v11 +# Debian Bookworm already contains libpq v15 +ENV PQ_LIB_DIR="/usr/local/musl/pq15/lib" # Creates a dummy project used to grab dependencies RUN USER=root cargo new --bin /app diff --git a/docker/armv7/Dockerfile.buildkit b/docker/armv7/Dockerfile.buildkit index f977322d23b..b19770fc8ff 100644 --- a/docker/armv7/Dockerfile.buildkit +++ b/docker/armv7/Dockerfile.buildkit @@ -15,18 +15,18 @@ # - 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 docker.io/vaultwarden/web-vault:v2023.5.0 -# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2023.5.0 -# [docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085] +# $ docker pull docker.io/vaultwarden/web-vault:v2023.7.1 +# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2023.7.1 +# [docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f] # # - Conversely, to get the tag name from the digest: -# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085 -# [docker.io/vaultwarden/web-vault:v2023.5.0] +# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f +# [docker.io/vaultwarden/web-vault:v2023.7.1] # -FROM docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085 as vault +FROM docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f as vault ########################## BUILD IMAGE ########################## -FROM docker.io/library/rust:1.70.0-bullseye as build +FROM docker.io/library/rust:1.71.1-bookworm as build # Build time options to avoid dpkg warnings and help with reproducible builds. ENV DEBIAN_FRONTEND=noninteractive \ @@ -34,6 +34,7 @@ ENV DEBIAN_FRONTEND=noninteractive \ TZ=UTC \ TERM=xterm-256color \ CARGO_HOME="/root/.cargo" \ + REGISTRIES_CRATES_IO_PROTOCOL=sparse \ USER="root" # Create CARGO_HOME folder and don't download rust docs @@ -41,7 +42,7 @@ RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/. && rustup set profile minimal # Install build dependencies for the armhf architecture -RUN dpkg --add-architecture armhf \ +RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry dpkg --add-architecture armhf \ && apt-get update \ && apt-get install -y \ --no-install-recommends \ @@ -99,7 +100,7 @@ RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/. ######################## RUNTIME IMAGE ######################## # Create a new stage with a minimal image # because we already have a binary built -FROM docker.io/balenalib/armv7hf-debian:bullseye +FROM docker.io/balenalib/armv7hf-debian:bookworm ENV ROCKET_PROFILE="release" \ ROCKET_ADDRESS=0.0.0.0 \ diff --git a/docker/armv7/Dockerfile.buildkit.alpine b/docker/armv7/Dockerfile.buildkit.alpine index d882213b2ff..7fd655b07e3 100644 --- a/docker/armv7/Dockerfile.buildkit.alpine +++ b/docker/armv7/Dockerfile.buildkit.alpine @@ -15,18 +15,18 @@ # - 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 docker.io/vaultwarden/web-vault:v2023.5.0 -# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2023.5.0 -# [docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085] +# $ docker pull docker.io/vaultwarden/web-vault:v2023.7.1 +# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2023.7.1 +# [docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f] # # - Conversely, to get the tag name from the digest: -# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085 -# [docker.io/vaultwarden/web-vault:v2023.5.0] +# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f +# [docker.io/vaultwarden/web-vault:v2023.7.1] # -FROM docker.io/vaultwarden/web-vault@sha256:e5b5e99d132d50dc73176afb65f41cf3b834fb06bfa1d621ac16c705c3f10085 as vault +FROM docker.io/vaultwarden/web-vault@sha256:b306f38fe0d54fa3d79059a737f8e1803da44ddc5f273c2aecdd6a4886211b0f as vault ########################## BUILD IMAGE ########################## -FROM docker.io/blackdex/rust-musl:armv7-musleabihf-stable-1.70.0 as build +FROM docker.io/blackdex/rust-musl:armv7-musleabihf-stable-1.71.1-openssl3 as build # Build time options to avoid dpkg warnings and help with reproducible builds. ENV DEBIAN_FRONTEND=noninteractive \ @@ -34,12 +34,16 @@ ENV DEBIAN_FRONTEND=noninteractive \ TZ=UTC \ TERM=xterm-256color \ CARGO_HOME="/root/.cargo" \ + REGISTRIES_CRATES_IO_PROTOCOL=sparse \ 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 +# Use PostgreSQL v15 during Alpine/MUSL builds instead of the default v11 +# Debian Bookworm already contains libpq v15 +ENV PQ_LIB_DIR="/usr/local/musl/pq15/lib" # Creates a dummy project used to grab dependencies RUN USER=root cargo new --bin /app diff --git a/migrations/mysql/2023-06-17-200424_create_auth_requests_table/down.sql b/migrations/mysql/2023-06-17-200424_create_auth_requests_table/down.sql new file mode 100644 index 00000000000..e69de29bb2d diff --git a/migrations/mysql/2023-06-17-200424_create_auth_requests_table/up.sql b/migrations/mysql/2023-06-17-200424_create_auth_requests_table/up.sql new file mode 100644 index 00000000000..2366c3b99a3 --- /dev/null +++ b/migrations/mysql/2023-06-17-200424_create_auth_requests_table/up.sql @@ -0,0 +1,19 @@ +CREATE TABLE auth_requests ( + uuid CHAR(36) NOT NULL PRIMARY KEY, + user_uuid CHAR(36) NOT NULL, + organization_uuid CHAR(36), + request_device_identifier CHAR(36) NOT NULL, + device_type INTEGER NOT NULL, + request_ip TEXT NOT NULL, + response_device_id CHAR(36), + access_code TEXT NOT NULL, + public_key TEXT NOT NULL, + enc_key TEXT NOT NULL, + master_password_hash TEXT NOT NULL, + approved BOOLEAN, + creation_date DATETIME NOT NULL, + response_date DATETIME, + authentication_date DATETIME, + FOREIGN KEY(user_uuid) REFERENCES users(uuid), + FOREIGN KEY(organization_uuid) REFERENCES organizations(uuid) +); \ No newline at end of file diff --git a/migrations/postgresql/2023-06-17-200424_create_auth_requests_table/down.sql b/migrations/postgresql/2023-06-17-200424_create_auth_requests_table/down.sql new file mode 100644 index 00000000000..e69de29bb2d diff --git a/migrations/postgresql/2023-06-17-200424_create_auth_requests_table/up.sql b/migrations/postgresql/2023-06-17-200424_create_auth_requests_table/up.sql new file mode 100644 index 00000000000..8d495e72d24 --- /dev/null +++ b/migrations/postgresql/2023-06-17-200424_create_auth_requests_table/up.sql @@ -0,0 +1,19 @@ +CREATE TABLE auth_requests ( + uuid CHAR(36) NOT NULL PRIMARY KEY, + user_uuid CHAR(36) NOT NULL, + organization_uuid CHAR(36), + request_device_identifier CHAR(36) NOT NULL, + device_type INTEGER NOT NULL, + request_ip TEXT NOT NULL, + response_device_id CHAR(36), + access_code TEXT NOT NULL, + public_key TEXT NOT NULL, + enc_key TEXT NOT NULL, + master_password_hash TEXT NOT NULL, + approved BOOLEAN, + creation_date TIMESTAMP NOT NULL, + response_date TIMESTAMP, + authentication_date TIMESTAMP, + FOREIGN KEY(user_uuid) REFERENCES users(uuid), + FOREIGN KEY(organization_uuid) REFERENCES organizations(uuid) +); \ No newline at end of file diff --git a/migrations/sqlite/2023-06-17-200424_create_auth_requests_table/down.sql b/migrations/sqlite/2023-06-17-200424_create_auth_requests_table/down.sql new file mode 100644 index 00000000000..e69de29bb2d diff --git a/migrations/sqlite/2023-06-17-200424_create_auth_requests_table/up.sql b/migrations/sqlite/2023-06-17-200424_create_auth_requests_table/up.sql new file mode 100644 index 00000000000..f16922ec644 --- /dev/null +++ b/migrations/sqlite/2023-06-17-200424_create_auth_requests_table/up.sql @@ -0,0 +1,19 @@ +CREATE TABLE auth_requests ( + uuid TEXT NOT NULL PRIMARY KEY, + user_uuid TEXT NOT NULL, + organization_uuid TEXT, + request_device_identifier TEXT NOT NULL, + device_type INTEGER NOT NULL, + request_ip TEXT NOT NULL, + response_device_id TEXT, + access_code TEXT NOT NULL, + public_key TEXT NOT NULL, + enc_key TEXT NOT NULL, + master_password_hash TEXT NOT NULL, + approved BOOLEAN, + creation_date DATETIME NOT NULL, + response_date DATETIME, + authentication_date DATETIME, + FOREIGN KEY(user_uuid) REFERENCES users(uuid), + FOREIGN KEY(organization_uuid) REFERENCES organizations(uuid) +); \ No newline at end of file diff --git a/rust-toolchain b/rust-toolchain index 832e9afb6c1..68bc7ff2a8e 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -1.70.0 +1.71.1 diff --git a/src/api/core/accounts.rs b/src/api/core/accounts.rs index 6c7d8ed594a..3feccd801ff 100644 --- a/src/api/core/accounts.rs +++ b/src/api/core/accounts.rs @@ -1,13 +1,14 @@ +use crate::db::DbPool; use chrono::Utc; use rocket::serde::json::Json; use serde_json::Value; use crate::{ api::{ - core::log_user_event, register_push_device, unregister_push_device, EmptyResult, JsonResult, JsonUpcase, - Notify, NumberOrString, PasswordData, UpdateType, + core::log_user_event, register_push_device, unregister_push_device, AnonymousNotify, EmptyResult, JsonResult, + JsonUpcase, Notify, NumberOrString, PasswordData, UpdateType, }, - auth::{decode_delete, decode_invite, decode_verify_email, Headers}, + auth::{decode_delete, decode_invite, decode_verify_email, ClientHeaders, Headers}, crypto, db::{models::*, DbConn}, mail, CONFIG, @@ -51,6 +52,11 @@ pub fn routes() -> Vec { put_device_token, put_clear_device_token, post_clear_device_token, + post_auth_request, + get_auth_request, + put_auth_request, + get_auth_request_response, + get_auth_requests, ] } @@ -996,3 +1002,211 @@ async fn put_clear_device_token(uuid: &str, mut conn: DbConn) -> EmptyResult { async fn post_clear_device_token(uuid: &str, conn: DbConn) -> EmptyResult { put_clear_device_token(uuid, conn).await } + +#[derive(Debug, Deserialize)] +#[allow(non_snake_case)] +struct AuthRequestRequest { + accessCode: String, + deviceIdentifier: String, + email: String, + publicKey: String, + #[serde(alias = "type")] + _type: i32, +} + +#[post("/auth-requests", data = "")] +async fn post_auth_request( + data: Json, + headers: ClientHeaders, + mut conn: DbConn, + nt: Notify<'_>, +) -> JsonResult { + let data = data.into_inner(); + + let user = match User::find_by_mail(&data.email, &mut conn).await { + Some(user) => user, + None => { + err!("AuthRequest doesn't exist") + } + }; + + let mut auth_request = AuthRequest::new( + user.uuid.clone(), + data.deviceIdentifier.clone(), + headers.device_type, + headers.ip.ip.to_string(), + data.accessCode, + data.publicKey, + ); + auth_request.save(&mut conn).await?; + + nt.send_auth_request(&user.uuid, &auth_request.uuid, &data.deviceIdentifier, &mut conn).await; + + Ok(Json(json!({ + "id": auth_request.uuid, + "publicKey": auth_request.public_key, + "requestDeviceType": DeviceType::from_i32(auth_request.device_type).to_string(), + "requestIpAddress": auth_request.request_ip, + "key": null, + "masterPasswordHash": null, + "creationDate": auth_request.creation_date.and_utc(), + "responseDate": null, + "requestApproved": false, + "origin": CONFIG.domain_origin(), + "object": "auth-request" + }))) +} + +#[get("/auth-requests/")] +async fn get_auth_request(uuid: &str, mut conn: DbConn) -> JsonResult { + let auth_request = match AuthRequest::find_by_uuid(uuid, &mut conn).await { + Some(auth_request) => auth_request, + None => { + err!("AuthRequest doesn't exist") + } + }; + + let response_date_utc = auth_request.response_date.map(|response_date| response_date.and_utc()); + + Ok(Json(json!( + { + "id": uuid, + "publicKey": auth_request.public_key, + "requestDeviceType": DeviceType::from_i32(auth_request.device_type).to_string(), + "requestIpAddress": auth_request.request_ip, + "key": auth_request.enc_key, + "masterPasswordHash": auth_request.master_password_hash, + "creationDate": auth_request.creation_date.and_utc(), + "responseDate": response_date_utc, + "requestApproved": auth_request.approved, + "origin": CONFIG.domain_origin(), + "object":"auth-request" + } + ))) +} + +#[derive(Debug, Deserialize)] +#[allow(non_snake_case)] +struct AuthResponseRequest { + deviceIdentifier: String, + key: String, + masterPasswordHash: String, + requestApproved: bool, +} + +#[put("/auth-requests/", data = "")] +async fn put_auth_request( + uuid: &str, + data: Json, + mut conn: DbConn, + ant: AnonymousNotify<'_>, + nt: Notify<'_>, +) -> JsonResult { + let data = data.into_inner(); + let mut auth_request: AuthRequest = match AuthRequest::find_by_uuid(uuid, &mut conn).await { + Some(auth_request) => auth_request, + None => { + err!("AuthRequest doesn't exist") + } + }; + + auth_request.approved = Some(data.requestApproved); + auth_request.enc_key = data.key; + auth_request.master_password_hash = data.masterPasswordHash; + auth_request.response_device_id = Some(data.deviceIdentifier.clone()); + auth_request.save(&mut conn).await?; + + if auth_request.approved.unwrap_or(false) { + ant.send_auth_response(&auth_request.user_uuid, &auth_request.uuid).await; + nt.send_auth_response(&auth_request.user_uuid, &auth_request.uuid, data.deviceIdentifier, &mut conn).await; + } + + let response_date_utc = auth_request.response_date.map(|response_date| response_date.and_utc()); + + Ok(Json(json!( + { + "id": uuid, + "publicKey": auth_request.public_key, + "requestDeviceType": DeviceType::from_i32(auth_request.device_type).to_string(), + "requestIpAddress": auth_request.request_ip, + "key": auth_request.enc_key, + "masterPasswordHash": auth_request.master_password_hash, + "creationDate": auth_request.creation_date.and_utc(), + "responseDate": response_date_utc, + "requestApproved": auth_request.approved, + "origin": CONFIG.domain_origin(), + "object":"auth-request" + } + ))) +} + +#[get("/auth-requests//response?")] +async fn get_auth_request_response(uuid: &str, code: &str, mut conn: DbConn) -> JsonResult { + let auth_request = match AuthRequest::find_by_uuid(uuid, &mut conn).await { + Some(auth_request) => auth_request, + None => { + err!("AuthRequest doesn't exist") + } + }; + + if !auth_request.check_access_code(code) { + err!("Access code invalid doesn't exist") + } + + let response_date_utc = auth_request.response_date.map(|response_date| response_date.and_utc()); + + Ok(Json(json!( + { + "id": uuid, + "publicKey": auth_request.public_key, + "requestDeviceType": DeviceType::from_i32(auth_request.device_type).to_string(), + "requestIpAddress": auth_request.request_ip, + "key": auth_request.enc_key, + "masterPasswordHash": auth_request.master_password_hash, + "creationDate": auth_request.creation_date.and_utc(), + "responseDate": response_date_utc, + "requestApproved": auth_request.approved, + "origin": CONFIG.domain_origin(), + "object":"auth-request" + } + ))) +} + +#[get("/auth-requests")] +async fn get_auth_requests(headers: Headers, mut conn: DbConn) -> JsonResult { + let auth_requests = AuthRequest::find_by_user(&headers.user.uuid, &mut conn).await; + + Ok(Json(json!({ + "data": auth_requests + .iter() + .filter(|request| request.approved.is_none()) + .map(|request| { + let response_date_utc = request.response_date.map(|response_date| response_date.and_utc()); + + json!({ + "id": request.uuid, + "publicKey": request.public_key, + "requestDeviceType": DeviceType::from_i32(request.device_type).to_string(), + "requestIpAddress": request.request_ip, + "key": request.enc_key, + "masterPasswordHash": request.master_password_hash, + "creationDate": request.creation_date.and_utc(), + "responseDate": response_date_utc, + "requestApproved": request.approved, + "origin": CONFIG.domain_origin(), + "object":"auth-request" + }) + }).collect::>(), + "continuationToken": null, + "object": "list" + }))) +} + +pub async fn purge_auth_requests(pool: DbPool) { + debug!("Purging auth requests"); + if let Ok(mut conn) = pool.get().await { + AuthRequest::purge_expired_auth_requests(&mut conn).await; + } else { + error!("Failed to get DB connection while purging trashed ciphers") + } +} diff --git a/src/api/core/mod.rs b/src/api/core/mod.rs index f7e912cf8ac..f1424688ae2 100644 --- a/src/api/core/mod.rs +++ b/src/api/core/mod.rs @@ -8,6 +8,7 @@ mod public; mod sends; pub mod two_factor; +pub use accounts::purge_auth_requests; pub use ciphers::{purge_trashed_ciphers, CipherData, CipherSyncData, CipherSyncType}; pub use emergency_access::{emergency_notification_reminder_job, emergency_request_timeout_job}; pub use events::{event_cleanup_job, log_event, log_user_event}; diff --git a/src/api/core/public.rs b/src/api/core/public.rs index b294591818c..ab30635c7f2 100644 --- a/src/api/core/public.rs +++ b/src/api/core/public.rs @@ -85,7 +85,7 @@ async fn ldap_import(data: JsonUpcase, token: PublicToken, mut co new_user } }; - let user_org_status = if CONFIG.mail_enabled() { + let user_org_status = if CONFIG.mail_enabled() || user.password_hash.is_empty() { UserOrgStatus::Invited as i32 } else { UserOrgStatus::Accepted as i32 // Automatically mark user as accepted if no email invites diff --git a/src/api/icons.rs b/src/api/icons.rs index dcf985f7ce5..124f3a8f783 100644 --- a/src/api/icons.rs +++ b/src/api/icons.rs @@ -19,7 +19,7 @@ use tokio::{ net::lookup_host, }; -use html5gum::{Emitter, EndTag, HtmlString, InfallibleTokenizer, Readable, StartTag, StringReader, Tokenizer}; +use html5gum::{Emitter, HtmlString, InfallibleTokenizer, Readable, StringReader, Tokenizer}; use crate::{ error::Error, @@ -46,10 +46,15 @@ static CLIENT: Lazy = Lazy::new(|| { // Generate the cookie store let cookie_store = Arc::new(Jar::default()); + let icon_download_timeout = Duration::from_secs(CONFIG.icon_download_timeout()); + let pool_idle_timeout = Duration::from_secs(10); // Reuse the client between requests let client = get_reqwest_client_builder() .cookie_provider(Arc::clone(&cookie_store)) - .timeout(Duration::from_secs(CONFIG.icon_download_timeout())) + .timeout(icon_download_timeout) + .pool_max_idle_per_host(5) // Configure the Hyper Pool to only have max 5 idle connections + .pool_idle_timeout(pool_idle_timeout) // Configure the Hyper Pool to timeout after 10 seconds + .trust_dns(true) .default_headers(default_headers.clone()); match client.build() { @@ -58,9 +63,11 @@ static CLIENT: Lazy = Lazy::new(|| { error!("Possible trust-dns error, trying with trust-dns disabled: '{e}'"); get_reqwest_client_builder() .cookie_provider(cookie_store) - .timeout(Duration::from_secs(CONFIG.icon_download_timeout())) - .default_headers(default_headers) + .timeout(icon_download_timeout) + .pool_max_idle_per_host(5) // Configure the Hyper Pool to only have max 5 idle connections + .pool_idle_timeout(pool_idle_timeout) // Configure the Hyper Pool to timeout after 10 seconds .trust_dns(false) + .default_headers(default_headers) .build() .expect("Failed to build client") } @@ -258,7 +265,7 @@ mod tests { } } -#[derive(Debug, Clone)] +#[derive(Clone)] enum DomainBlacklistReason { Regex, IP, @@ -415,38 +422,34 @@ fn get_favicons_node( const TAG_LINK: &[u8] = b"link"; const TAG_BASE: &[u8] = b"base"; const TAG_HEAD: &[u8] = b"head"; - const ATTR_REL: &[u8] = b"rel"; const ATTR_HREF: &[u8] = b"href"; const ATTR_SIZES: &[u8] = b"sizes"; let mut base_url = url.clone(); - let mut icon_tags: Vec = Vec::new(); + let mut icon_tags: Vec = Vec::new(); for token in dom { - match token { - FaviconToken::StartTag(tag) => { - if *tag.name == TAG_LINK - && tag.attributes.contains_key(ATTR_REL) - && tag.attributes.contains_key(ATTR_HREF) - { - let rel_value = std::str::from_utf8(tag.attributes.get(ATTR_REL).unwrap()) - .unwrap_or_default() - .to_ascii_lowercase(); - if rel_value.contains("icon") && !rel_value.contains("mask-icon") { - icon_tags.push(tag); - } - } else if *tag.name == TAG_BASE && tag.attributes.contains_key(ATTR_HREF) { - let href = std::str::from_utf8(tag.attributes.get(ATTR_HREF).unwrap()).unwrap_or_default(); + let tag_name: &[u8] = &token.tag.name; + match tag_name { + TAG_LINK => { + icon_tags.push(token.tag); + } + TAG_BASE => { + base_url = if let Some(href) = token.tag.attributes.get(ATTR_HREF) { + let href = std::str::from_utf8(href).unwrap_or_default(); debug!("Found base href: {href}"); - base_url = match base_url.join(href) { + match base_url.join(href) { Ok(inner_url) => inner_url, - _ => url.clone(), - }; - } + _ => continue, + } + } else { + continue; + }; } - FaviconToken::EndTag(tag) => { - if *tag.name == TAG_HEAD { - break; - } + TAG_HEAD if token.closing => { + break; + } + _ => { + continue; } } } @@ -820,43 +823,64 @@ impl reqwest::cookie::CookieStore for Jar { } /// Custom FaviconEmitter for the html5gum parser. -/// The FaviconEmitter is using an almost 1:1 copy of the DefaultEmitter with some small changes. +/// The FaviconEmitter is using an optimized version of the DefaultEmitter. /// This prevents emitting tags like comments, doctype and also strings between the tags. +/// But it will also only emit the tags we need and only if they have the correct attributes /// Therefor parsing the HTML content is faster. -use std::collections::{BTreeSet, VecDeque}; +use std::collections::BTreeMap; + +#[derive(Default)] +pub struct Tag { + /// The tag's name, such as `"link"` or `"base"`. + pub name: HtmlString, -#[derive(Debug)] -enum FaviconToken { - StartTag(StartTag), - EndTag(EndTag), + /// A mapping for any HTML attributes this start tag may have. + /// + /// Duplicate attributes are ignored after the first one as per WHATWG spec. + pub attributes: BTreeMap, } -#[derive(Default, Debug)] +struct FaviconToken { + tag: Tag, + closing: bool, +} + +#[derive(Default)] struct FaviconEmitter { current_token: Option, last_start_tag: HtmlString, current_attribute: Option<(HtmlString, HtmlString)>, - seen_attributes: BTreeSet, - emitted_tokens: VecDeque, + emit_token: bool, } impl FaviconEmitter { - fn emit_token(&mut self, token: FaviconToken) { - self.emitted_tokens.push_front(token); - } + fn flush_current_attribute(&mut self, emit_current_tag: bool) { + const ATTR_HREF: &[u8] = b"href"; + const ATTR_REL: &[u8] = b"rel"; + const TAG_LINK: &[u8] = b"link"; + const TAG_BASE: &[u8] = b"base"; + const TAG_HEAD: &[u8] = b"head"; + + if let Some(ref mut token) = self.current_token { + let tag_name: &[u8] = &token.tag.name; + + if self.current_attribute.is_some() && (tag_name == TAG_BASE || tag_name == TAG_LINK) { + let (k, v) = self.current_attribute.take().unwrap(); + token.tag.attributes.entry(k).and_modify(|_| {}).or_insert(v); + } - fn flush_current_attribute(&mut self) { - if let Some((k, v)) = self.current_attribute.take() { - match self.current_token { - Some(FaviconToken::StartTag(ref mut tag)) => { - tag.attributes.entry(k).and_modify(|_| {}).or_insert(v); - } - Some(FaviconToken::EndTag(_)) => { - self.seen_attributes.insert(k); - } - _ => { - debug_assert!(false); + let tag_attr = &token.tag.attributes; + match tag_name { + TAG_HEAD if token.closing => self.emit_token = true, + TAG_BASE if tag_attr.contains_key(ATTR_HREF) => self.emit_token = true, + TAG_LINK if emit_current_tag && tag_attr.contains_key(ATTR_REL) && tag_attr.contains_key(ATTR_HREF) => { + let rel_value = + std::str::from_utf8(token.tag.attributes.get(ATTR_REL).unwrap()).unwrap_or_default(); + if rel_value.contains("icon") && !rel_value.contains("mask-icon") { + self.emit_token = true + } } + _ => (), } } } @@ -871,87 +895,71 @@ impl Emitter for FaviconEmitter { } fn pop_token(&mut self) -> Option { - self.emitted_tokens.pop_back() + if self.emit_token { + self.emit_token = false; + return self.current_token.take(); + } + None } fn init_start_tag(&mut self) { - self.current_token = Some(FaviconToken::StartTag(StartTag::default())); + self.current_token = Some(FaviconToken { + tag: Tag::default(), + closing: false, + }); } fn init_end_tag(&mut self) { - self.current_token = Some(FaviconToken::EndTag(EndTag::default())); - self.seen_attributes.clear(); + self.current_token = Some(FaviconToken { + tag: Tag::default(), + closing: true, + }); } fn emit_current_tag(&mut self) -> Option { - self.flush_current_attribute(); - let mut token = self.current_token.take().unwrap(); - let mut emit = false; - match token { - FaviconToken::EndTag(ref mut tag) => { - // Always clean seen attributes - self.seen_attributes.clear(); - self.set_last_start_tag(None); - - // Only trigger an emit for the tag. - // This is matched, and will break the for-loop. - if *tag.name == b"head" { - emit = true; - } - } - FaviconToken::StartTag(ref mut tag) => { - // Only trriger an emit for and tags. - // These are the only tags we want to parse. - if *tag.name == b"link" || *tag.name == b"base" { - self.set_last_start_tag(Some(&tag.name)); - emit = true; - } else { - self.set_last_start_tag(None); - } - } - } - - // Only emit the tags we want to parse. - if emit { - self.emit_token(token); + self.flush_current_attribute(true); + self.last_start_tag.clear(); + if self.current_token.is_some() && !self.current_token.as_ref().unwrap().closing { + self.last_start_tag.extend(&*self.current_token.as_ref().unwrap().tag.name); } - None + html5gum::naive_next_state(&self.last_start_tag) } fn push_tag_name(&mut self, s: &[u8]) { - match self.current_token { - Some( - FaviconToken::StartTag(StartTag { - ref mut name, - .. - }) - | FaviconToken::EndTag(EndTag { - ref mut name, - .. - }), - ) => { - name.extend(s); - } - _ => debug_assert!(false), + if let Some(ref mut token) = self.current_token { + token.tag.name.extend(s); } } fn init_attribute(&mut self) { - self.flush_current_attribute(); - self.current_attribute = Some(Default::default()); + self.flush_current_attribute(false); + self.current_attribute = match &self.current_token { + Some(token) => { + let tag_name: &[u8] = &token.tag.name; + match tag_name { + b"link" | b"head" | b"base" => Some(Default::default()), + _ => None, + } + } + _ => None, + }; } fn push_attribute_name(&mut self, s: &[u8]) { - self.current_attribute.as_mut().unwrap().0.extend(s); + if let Some(attr) = &mut self.current_attribute { + attr.0.extend(s) + } } fn push_attribute_value(&mut self, s: &[u8]) { - self.current_attribute.as_mut().unwrap().1.extend(s); + if let Some(attr) = &mut self.current_attribute { + attr.1.extend(s) + } } fn current_is_appropriate_end_tag_token(&mut self) -> bool { - match self.current_token { - Some(FaviconToken::EndTag(ref tag)) => !self.last_start_tag.is_empty() && self.last_start_tag == tag.name, + match &self.current_token { + Some(token) if token.closing => !self.last_start_tag.is_empty() && self.last_start_tag == token.tag.name, _ => false, } } diff --git a/src/api/identity.rs b/src/api/identity.rs index 048ac17d100..8dbb78f69a8 100644 --- a/src/api/identity.rs +++ b/src/api/identity.rs @@ -155,7 +155,27 @@ async fn _password_login( // Check password let password = data.password.as_ref().unwrap(); - if !user.check_valid_password(password) { + if let Some(auth_request_uuid) = data.auth_request.clone() { + if let Some(auth_request) = AuthRequest::find_by_uuid(auth_request_uuid.as_str(), conn).await { + if !auth_request.check_access_code(password) { + err!( + "Username or access code is incorrect. Try again", + format!("IP: {}. Username: {}.", ip.ip, username), + ErrorEvent { + event: EventType::UserFailedLogIn, + } + ) + } + } else { + err!( + "Auth request not found. Try again.", + format!("IP: {}. Username: {}.", ip.ip, username), + ErrorEvent { + event: EventType::UserFailedLogIn, + } + ) + } + } else if !user.check_valid_password(password) { err!( "Username or password is incorrect. Try again", format!("IP: {}. Username: {}.", ip.ip, username), @@ -646,6 +666,8 @@ struct ConnectData { #[field(name = uncased("two_factor_remember"))] #[field(name = uncased("twofactorremember"))] two_factor_remember: Option, + #[field(name = uncased("authrequest"))] + auth_request: Option, } fn _check_is_some(value: &Option, msg: &str) -> EmptyResult { diff --git a/src/api/mod.rs b/src/api/mod.rs index f3f79210bbb..fd181fda504 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -13,6 +13,7 @@ pub use crate::api::{ admin::catchers as admin_catchers, admin::routes as admin_routes, core::catchers as core_catchers, + core::purge_auth_requests, core::purge_sends, core::purge_trashed_ciphers, core::routes as core_routes, @@ -22,7 +23,7 @@ pub use crate::api::{ icons::routes as icons_routes, identity::routes as identity_routes, notifications::routes as notifications_routes, - notifications::{start_notification_server, Notify, UpdateType}, + notifications::{start_notification_server, AnonymousNotify, Notify, UpdateType, WS_ANONYMOUS_SUBSCRIPTIONS}, push::{ push_cipher_update, push_folder_update, push_logout, push_send_update, push_user_update, register_push_device, unregister_push_device, diff --git a/src/api/notifications.rs b/src/api/notifications.rs index 5a073723900..7e76021b359 100644 --- a/src/api/notifications.rs +++ b/src/api/notifications.rs @@ -36,10 +36,19 @@ static WS_USERS: Lazy> = Lazy::new(|| { }) }); -use super::{push_cipher_update, push_folder_update, push_logout, push_send_update, push_user_update}; +pub static WS_ANONYMOUS_SUBSCRIPTIONS: Lazy> = Lazy::new(|| { + Arc::new(AnonymousWebSocketSubscriptions { + map: Arc::new(dashmap::DashMap::new()), + }) +}); + +use super::{ + push::push_auth_request, push::push_auth_response, push_cipher_update, push_folder_update, push_logout, + push_send_update, push_user_update, +}; pub fn routes() -> Vec { - routes![websockets_hub] + routes![websockets_hub, anonymous_websockets_hub] } #[derive(FromForm, Debug)] @@ -74,6 +83,29 @@ impl Drop for WSEntryMapGuard { } } +struct WSAnonymousEntryMapGuard { + subscriptions: Arc, + token: String, + addr: IpAddr, +} + +impl WSAnonymousEntryMapGuard { + fn new(subscriptions: Arc, token: String, addr: IpAddr) -> Self { + Self { + subscriptions, + token, + addr, + } + } +} + +impl Drop for WSAnonymousEntryMapGuard { + fn drop(&mut self) { + info!("Closing WS connection from {}", self.addr); + self.subscriptions.map.remove(&self.token); + } +} + #[get("/hub?")] fn websockets_hub<'r>( ws: rocket_ws::WebSocket, @@ -144,6 +176,72 @@ fn websockets_hub<'r>( }) } +#[get("/anonymous-hub?")] +fn anonymous_websockets_hub<'r>( + ws: rocket_ws::WebSocket, + token: String, + ip: ClientIp, +) -> Result { + let addr = ip.ip; + info!("Accepting Anonymous Rocket WS connection from {addr}"); + + let (mut rx, guard) = { + let subscriptions = Arc::clone(&WS_ANONYMOUS_SUBSCRIPTIONS); + + // Add a channel to send messages to this client to the map + let (tx, rx) = tokio::sync::mpsc::channel::(100); + subscriptions.map.insert(token.clone(), tx); + + // Once the guard goes out of scope, the connection will have been closed and the entry will be deleted from the map + (rx, WSAnonymousEntryMapGuard::new(subscriptions, token, addr)) + }; + + Ok({ + rocket_ws::Stream! { ws => { + let mut ws = ws; + let _guard = guard; + let mut interval = tokio::time::interval(Duration::from_secs(15)); + loop { + tokio::select! { + res = ws.next() => { + match res { + Some(Ok(message)) => { + match message { + // Respond to any pings + Message::Ping(ping) => yield Message::Pong(ping), + Message::Pong(_) => {/* Ignored */}, + + // We should receive an initial message with the protocol and version, and we will reply to it + Message::Text(ref message) => { + let msg = message.strip_suffix(RECORD_SEPARATOR as char).unwrap_or(message); + + if serde_json::from_str(msg).ok() == Some(INITIAL_MESSAGE) { + yield Message::binary(INITIAL_RESPONSE); + continue; + } + } + // Just echo anything else the client sends + _ => yield message, + } + } + _ => break, + } + } + + res = rx.recv() => { + match res { + Some(res) => yield res, + None => break, + } + } + + _ = interval.tick() => yield Message::Ping(create_ping()) + } + } + }} + }) +} + // // Websockets server // @@ -352,6 +450,69 @@ impl WebSocketUsers { push_send_update(ut, send, acting_device_uuid, conn).await; } } + + pub async fn send_auth_request( + &self, + user_uuid: &String, + auth_request_uuid: &String, + acting_device_uuid: &String, + conn: &mut DbConn, + ) { + let data = create_update( + vec![("Id".into(), auth_request_uuid.clone().into()), ("UserId".into(), user_uuid.clone().into())], + UpdateType::AuthRequest, + Some(acting_device_uuid.to_string()), + ); + self.send_update(user_uuid, &data).await; + + if CONFIG.push_enabled() { + push_auth_request(user_uuid.to_string(), auth_request_uuid.to_string(), conn).await; + } + } + + pub async fn send_auth_response( + &self, + user_uuid: &String, + auth_response_uuid: &str, + approving_device_uuid: String, + conn: &mut DbConn, + ) { + let data = create_update( + vec![("Id".into(), auth_response_uuid.to_owned().into()), ("UserId".into(), user_uuid.clone().into())], + UpdateType::AuthRequestResponse, + approving_device_uuid.clone().into(), + ); + self.send_update(auth_response_uuid, &data).await; + + if CONFIG.push_enabled() { + push_auth_response(user_uuid.to_string(), auth_response_uuid.to_string(), approving_device_uuid, conn) + .await; + } + } +} + +#[derive(Clone)] +pub struct AnonymousWebSocketSubscriptions { + map: Arc>>, +} + +impl AnonymousWebSocketSubscriptions { + async fn send_update(&self, token: &str, data: &[u8]) { + if let Some(sender) = self.map.get(token).map(|v| v.clone()) { + if let Err(e) = sender.send(Message::binary(data)).await { + error!("Error sending WS update {e}"); + } + } + } + + pub async fn send_auth_response(&self, user_uuid: &String, auth_response_uuid: &str) { + let data = create_anonymous_update( + vec![("Id".into(), auth_response_uuid.to_owned().into()), ("UserId".into(), user_uuid.clone().into())], + UpdateType::AuthRequestResponse, + user_uuid.to_string(), + ); + self.send_update(auth_response_uuid, &data).await; + } } /* Message Structure @@ -387,6 +548,24 @@ fn create_update(payload: Vec<(Value, Value)>, ut: UpdateType, acting_device_uui serialize(value) } +fn create_anonymous_update(payload: Vec<(Value, Value)>, ut: UpdateType, user_id: String) -> Vec { + use rmpv::Value as V; + + let value = V::Array(vec![ + 1.into(), + V::Map(vec![]), + V::Nil, + "AuthRequestResponseRecieved".into(), + V::Array(vec![V::Map(vec![ + ("Type".into(), (ut as i32).into()), + ("Payload".into(), payload.into()), + ("UserId".into(), user_id.into()), + ])]), + ]); + + serialize(value) +} + fn create_ping() -> Vec { serialize(Value::Array(vec![6.into()])) } @@ -420,6 +599,7 @@ pub enum UpdateType { } pub type Notify<'a> = &'a rocket::State>; +pub type AnonymousNotify<'a> = &'a rocket::State>; pub fn start_notification_server() -> Arc { let users = Arc::clone(&WS_USERS); diff --git a/src/api/push.rs b/src/api/push.rs index da9255a662c..e6a931e6094 100644 --- a/src/api/push.rs +++ b/src/api/push.rs @@ -255,3 +255,40 @@ async fn send_to_push_relay(notification_data: Value) { error!("An error occured while sending a send update to the push relay: {}", e); }; } + +pub async fn push_auth_request(user_uuid: String, auth_request_uuid: String, conn: &mut crate::db::DbConn) { + if Device::check_user_has_push_device(user_uuid.as_str(), conn).await { + tokio::task::spawn(send_to_push_relay(json!({ + "userId": user_uuid, + "organizationId": (), + "deviceId": null, + "identifier": null, + "type": UpdateType::AuthRequest as i32, + "payload": { + "id": auth_request_uuid, + "userId": user_uuid, + } + }))); + } +} + +pub async fn push_auth_response( + user_uuid: String, + auth_request_uuid: String, + approving_device_uuid: String, + conn: &mut crate::db::DbConn, +) { + if Device::check_user_has_push_device(user_uuid.as_str(), conn).await { + tokio::task::spawn(send_to_push_relay(json!({ + "userId": user_uuid, + "organizationId": (), + "deviceId": approving_device_uuid, + "identifier": approving_device_uuid, + "type": UpdateType::AuthRequestResponse as i32, + "payload": { + "id": auth_request_uuid, + "userId": user_uuid, + } + }))); + } +} diff --git a/src/config.rs b/src/config.rs index 7351b94168d..d54b356b152 100644 --- a/src/config.rs +++ b/src/config.rs @@ -409,6 +409,10 @@ make_config! { /// Event cleanup schedule |> Cron schedule of the job that cleans old events from the event table. /// Defaults to daily. Set blank to disable this job. event_cleanup_schedule: String, false, def, "0 10 0 * * *".to_string(); + /// Auth Request cleanup schedule |> Cron schedule of the job that cleans old auth requests from the auth request. + /// Defaults to every minute. Set blank to disable this job. + auth_request_purge_schedule: String, false, def, "30 * * * * *".to_string(); + }, /// General settings @@ -492,7 +496,7 @@ make_config! { /// Invitation organization name |> Name shown in the invitation emails that don't come from a specific organization invitation_org_name: String, true, def, "Vaultwarden".to_string(); - /// Events days retain |> Number of days to retain events stored in the database. If unset, events are kept indefently. + /// Events days retain |> Number of days to retain events stored in the database. If unset, events are kept indefinitely. events_days_retain: i64, false, option; }, @@ -520,7 +524,7 @@ make_config! { /// has been decided on, consider using permanent redirects for cacheability. The legacy codes /// are currently better supported by the Bitwarden clients. icon_redirect_code: u32, true, def, 302; - /// Positive icon cache expiry |> Number of seconds to consider that an already cached icon is fresh. After this period, the icon will be redownloaded + /// Positive icon cache expiry |> Number of seconds to consider that an already cached icon is fresh. After this period, the icon will be refreshed icon_cache_ttl: u64, true, def, 2_592_000; /// Negative icon cache expiry |> Number of seconds before trying to download an icon that failed again. icon_cache_negttl: u64, true, def, 259_200; @@ -530,7 +534,7 @@ make_config! { /// Useful to hide other servers in the local network. Check the WIKI for more details icon_blacklist_regex: String, true, option; /// Icon blacklist non global IPs |> Any IP which is not defined as a global IP will be blacklisted. - /// Usefull to secure your internal environment: See https://en.wikipedia.org/wiki/Reserved_IP_addresses for a list of IPs which it will block + /// Useful to secure your internal environment: See https://en.wikipedia.org/wiki/Reserved_IP_addresses for a list of IPs which it will block icon_blacklist_non_global_ips: bool, true, def, true; /// Disable Two-Factor remember |> Enabling this would force the users to use a second factor to login every time. @@ -566,7 +570,7 @@ make_config! { /// Max database connection retries |> Number of times to retry the database connection during startup, with 1 second between each retry, set to 0 to retry indefinitely db_connection_retries: u32, false, def, 15; - /// Timeout when aquiring database connection + /// Timeout when acquiring database connection database_timeout: u64, false, def, 30; /// Database connection pool size @@ -893,6 +897,10 @@ fn validate_config(cfg: &ConfigItems) -> Result<(), Error> { err!("`EVENT_CLEANUP_SCHEDULE` is not a valid cron expression") } + if !cfg.auth_request_purge_schedule.is_empty() && cfg.auth_request_purge_schedule.parse::().is_err() { + err!("`AUTH_REQUEST_PURGE_SCHEDULE` is not a valid cron expression") + } + if !cfg.disable_admin_token { match cfg.admin_token.as_ref() { Some(t) if t.starts_with("$argon2") => { diff --git a/src/db/models/auth_request.rs b/src/db/models/auth_request.rs new file mode 100644 index 00000000000..0b129ac16ad --- /dev/null +++ b/src/db/models/auth_request.rs @@ -0,0 +1,148 @@ +use crate::crypto::ct_eq; +use chrono::{NaiveDateTime, Utc}; + +db_object! { + #[derive(Debug, Identifiable, Queryable, Insertable, AsChangeset, Deserialize, Serialize)] + #[diesel(table_name = auth_requests)] + #[diesel(treat_none_as_null = true)] + #[diesel(primary_key(uuid))] + pub struct AuthRequest { + pub uuid: String, + pub user_uuid: String, + pub organization_uuid: Option, + + pub request_device_identifier: String, + pub device_type: i32, // https://github.com/bitwarden/server/blob/master/src/Core/Enums/DeviceType.cs + + pub request_ip: String, + pub response_device_id: Option, + + pub access_code: String, + pub public_key: String, + + pub enc_key: String, + + pub master_password_hash: String, + pub approved: Option, + pub creation_date: NaiveDateTime, + pub response_date: Option, + + pub authentication_date: Option, + } +} + +impl AuthRequest { + pub fn new( + user_uuid: String, + request_device_identifier: String, + device_type: i32, + request_ip: String, + access_code: String, + public_key: String, + ) -> Self { + let now = Utc::now().naive_utc(); + + Self { + uuid: crate::util::get_uuid(), + user_uuid, + organization_uuid: None, + + request_device_identifier, + device_type, + request_ip, + response_device_id: None, + access_code, + public_key, + enc_key: String::new(), + master_password_hash: String::new(), + approved: None, + creation_date: now, + response_date: None, + authentication_date: None, + } + } +} + +use crate::db::DbConn; + +use crate::api::EmptyResult; +use crate::error::MapResult; + +impl AuthRequest { + pub async fn save(&mut self, conn: &mut DbConn) -> EmptyResult { + db_run! { conn: + sqlite, mysql { + match diesel::replace_into(auth_requests::table) + .values(AuthRequestDb::to_db(self)) + .execute(conn) + { + Ok(_) => Ok(()), + // Record already exists and causes a Foreign Key Violation because replace_into() wants to delete the record first. + Err(diesel::result::Error::DatabaseError(diesel::result::DatabaseErrorKind::ForeignKeyViolation, _)) => { + diesel::update(auth_requests::table) + .filter(auth_requests::uuid.eq(&self.uuid)) + .set(AuthRequestDb::to_db(self)) + .execute(conn) + .map_res("Error auth_request") + } + Err(e) => Err(e.into()), + }.map_res("Error auth_request") + } + postgresql { + let value = AuthRequestDb::to_db(self); + diesel::insert_into(auth_requests::table) + .values(&value) + .on_conflict(auth_requests::uuid) + .do_update() + .set(&value) + .execute(conn) + .map_res("Error saving auth_request") + } + } + } + + pub async fn find_by_uuid(uuid: &str, conn: &mut DbConn) -> Option { + db_run! {conn: { + auth_requests::table + .filter(auth_requests::uuid.eq(uuid)) + .first::(conn) + .ok() + .from_db() + }} + } + + pub async fn find_by_user(user_uuid: &str, conn: &mut DbConn) -> Vec { + db_run! {conn: { + auth_requests::table + .filter(auth_requests::user_uuid.eq(user_uuid)) + .load::(conn).expect("Error loading auth_requests").from_db() + }} + } + + pub async fn find_created_before(dt: &NaiveDateTime, conn: &mut DbConn) -> Vec { + db_run! {conn: { + auth_requests::table + .filter(auth_requests::creation_date.lt(dt)) + .load::(conn).expect("Error loading auth_requests").from_db() + }} + } + + pub async fn delete(&self, conn: &mut DbConn) -> EmptyResult { + db_run! { conn: { + diesel::delete(auth_requests::table.filter(auth_requests::uuid.eq(&self.uuid))) + .execute(conn) + .map_res("Error deleting auth request") + }} + } + + pub fn check_access_code(&self, access_code: &str) -> bool { + ct_eq(&self.access_code, access_code) + } + + pub async fn purge_expired_auth_requests(conn: &mut DbConn) { + let expiry_time = Utc::now().naive_utc() - chrono::Duration::minutes(5); //after 5 minutes, clients reject the request + for auth_request in Self::find_created_before(&expiry_time, conn).await { + auth_request.delete(conn).await.ok(); + } + } +} diff --git a/src/db/models/device.rs b/src/db/models/device.rs index 78519737e7e..b80b47a104c 100644 --- a/src/db/models/device.rs +++ b/src/db/models/device.rs @@ -1,6 +1,7 @@ use chrono::{NaiveDateTime, Utc}; use crate::{crypto, CONFIG}; +use core::fmt; db_object! { #[derive(Identifiable, Queryable, Insertable, AsChangeset)] @@ -225,3 +226,90 @@ impl Device { }} } } + +pub enum DeviceType { + Android = 0, + Ios = 1, + ChromeExtension = 2, + FirefoxExtension = 3, + OperaExtension = 4, + EdgeExtension = 5, + WindowsDesktop = 6, + MacOsDesktop = 7, + LinuxDesktop = 8, + ChromeBrowser = 9, + FirefoxBrowser = 10, + OperaBrowser = 11, + EdgeBrowser = 12, + IEBrowser = 13, + UnknownBrowser = 14, + AndroidAmazon = 15, + Uwp = 16, + SafariBrowser = 17, + VivaldiBrowser = 18, + VivaldiExtension = 19, + SafariExtension = 20, + Sdk = 21, + Server = 22, +} + +impl fmt::Display for DeviceType { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + DeviceType::Android => write!(f, "Android"), + DeviceType::Ios => write!(f, "iOS"), + DeviceType::ChromeExtension => write!(f, "Chrome Extension"), + DeviceType::FirefoxExtension => write!(f, "Firefox Extension"), + DeviceType::OperaExtension => write!(f, "Opera Extension"), + DeviceType::EdgeExtension => write!(f, "Edge Extension"), + DeviceType::WindowsDesktop => write!(f, "Windows Desktop"), + DeviceType::MacOsDesktop => write!(f, "MacOS Desktop"), + DeviceType::LinuxDesktop => write!(f, "Linux Desktop"), + DeviceType::ChromeBrowser => write!(f, "Chrome Browser"), + DeviceType::FirefoxBrowser => write!(f, "Firefox Browser"), + DeviceType::OperaBrowser => write!(f, "Opera Browser"), + DeviceType::EdgeBrowser => write!(f, "Edge Browser"), + DeviceType::IEBrowser => write!(f, "Internet Explorer"), + DeviceType::UnknownBrowser => write!(f, "Unknown Browser"), + DeviceType::AndroidAmazon => write!(f, "Android Amazon"), + DeviceType::Uwp => write!(f, "UWP"), + DeviceType::SafariBrowser => write!(f, "Safari Browser"), + DeviceType::VivaldiBrowser => write!(f, "Vivaldi Browser"), + DeviceType::VivaldiExtension => write!(f, "Vivaldi Extension"), + DeviceType::SafariExtension => write!(f, "Safari Extension"), + DeviceType::Sdk => write!(f, "SDK"), + DeviceType::Server => write!(f, "Server"), + } + } +} + +impl DeviceType { + pub fn from_i32(value: i32) -> DeviceType { + match value { + 0 => DeviceType::Android, + 1 => DeviceType::Ios, + 2 => DeviceType::ChromeExtension, + 3 => DeviceType::FirefoxExtension, + 4 => DeviceType::OperaExtension, + 5 => DeviceType::EdgeExtension, + 6 => DeviceType::WindowsDesktop, + 7 => DeviceType::MacOsDesktop, + 8 => DeviceType::LinuxDesktop, + 9 => DeviceType::ChromeBrowser, + 10 => DeviceType::FirefoxBrowser, + 11 => DeviceType::OperaBrowser, + 12 => DeviceType::EdgeBrowser, + 13 => DeviceType::IEBrowser, + 14 => DeviceType::UnknownBrowser, + 15 => DeviceType::AndroidAmazon, + 16 => DeviceType::Uwp, + 17 => DeviceType::SafariBrowser, + 18 => DeviceType::VivaldiBrowser, + 19 => DeviceType::VivaldiExtension, + 20 => DeviceType::SafariExtension, + 21 => DeviceType::Sdk, + 22 => DeviceType::Server, + _ => DeviceType::UnknownBrowser, + } + } +} diff --git a/src/db/models/mod.rs b/src/db/models/mod.rs index 6cbde05fe43..0379141ad26 100644 --- a/src/db/models/mod.rs +++ b/src/db/models/mod.rs @@ -1,4 +1,5 @@ mod attachment; +mod auth_request; mod cipher; mod collection; mod device; @@ -15,9 +16,10 @@ mod two_factor_incomplete; mod user; pub use self::attachment::Attachment; +pub use self::auth_request::AuthRequest; pub use self::cipher::Cipher; pub use self::collection::{Collection, CollectionCipher, CollectionUser}; -pub use self::device::Device; +pub use self::device::{Device, DeviceType}; pub use self::emergency_access::{EmergencyAccess, EmergencyAccessStatus, EmergencyAccessType}; pub use self::event::{Event, EventType}; pub use self::favorite::Favorite; diff --git a/src/db/schemas/mysql/schema.rs b/src/db/schemas/mysql/schema.rs index 695d5bd77b8..c2b2c9617c0 100644 --- a/src/db/schemas/mysql/schema.rs +++ b/src/db/schemas/mysql/schema.rs @@ -286,6 +286,26 @@ table! { } } +table! { + auth_requests (uuid) { + uuid -> Text, + user_uuid -> Text, + organization_uuid -> Nullable, + request_device_identifier -> Text, + device_type -> Integer, + request_ip -> Text, + response_device_id -> Nullable, + access_code -> Text, + public_key -> Text, + enc_key -> Text, + master_password_hash -> Text, + approved -> Nullable, + creation_date -> Timestamp, + response_date -> Nullable, + authentication_date -> Nullable, + } +} + joinable!(attachments -> ciphers (cipher_uuid)); joinable!(ciphers -> organizations (organization_uuid)); joinable!(ciphers -> users (user_uuid)); @@ -312,6 +332,7 @@ joinable!(groups_users -> groups (groups_uuid)); joinable!(collections_groups -> collections (collections_uuid)); joinable!(collections_groups -> groups (groups_uuid)); joinable!(event -> users_organizations (uuid)); +joinable!(auth_requests -> users (user_uuid)); allow_tables_to_appear_in_same_query!( attachments, @@ -335,4 +356,5 @@ allow_tables_to_appear_in_same_query!( groups_users, collections_groups, event, + auth_requests, ); diff --git a/src/db/schemas/postgresql/schema.rs b/src/db/schemas/postgresql/schema.rs index 766c03e7bae..4ae9e821569 100644 --- a/src/db/schemas/postgresql/schema.rs +++ b/src/db/schemas/postgresql/schema.rs @@ -286,6 +286,26 @@ table! { } } +table! { + auth_requests (uuid) { + uuid -> Text, + user_uuid -> Text, + organization_uuid -> Nullable, + request_device_identifier -> Text, + device_type -> Integer, + request_ip -> Text, + response_device_id -> Nullable, + access_code -> Text, + public_key -> Text, + enc_key -> Text, + master_password_hash -> Text, + approved -> Nullable, + creation_date -> Timestamp, + response_date -> Nullable, + authentication_date -> Nullable, + } +} + joinable!(attachments -> ciphers (cipher_uuid)); joinable!(ciphers -> organizations (organization_uuid)); joinable!(ciphers -> users (user_uuid)); @@ -312,6 +332,7 @@ joinable!(groups_users -> groups (groups_uuid)); joinable!(collections_groups -> collections (collections_uuid)); joinable!(collections_groups -> groups (groups_uuid)); joinable!(event -> users_organizations (uuid)); +joinable!(auth_requests -> users (user_uuid)); allow_tables_to_appear_in_same_query!( attachments, @@ -335,4 +356,5 @@ allow_tables_to_appear_in_same_query!( groups_users, collections_groups, event, + auth_requests, ); diff --git a/src/db/schemas/sqlite/schema.rs b/src/db/schemas/sqlite/schema.rs index 031ec7aa8bf..62c04e91472 100644 --- a/src/db/schemas/sqlite/schema.rs +++ b/src/db/schemas/sqlite/schema.rs @@ -286,6 +286,26 @@ table! { } } +table! { + auth_requests (uuid) { + uuid -> Text, + user_uuid -> Text, + organization_uuid -> Nullable, + request_device_identifier -> Text, + device_type -> Integer, + request_ip -> Text, + response_device_id -> Nullable, + access_code -> Text, + public_key -> Text, + enc_key -> Text, + master_password_hash -> Text, + approved -> Nullable, + creation_date -> Timestamp, + response_date -> Nullable, + authentication_date -> Nullable, + } +} + joinable!(attachments -> ciphers (cipher_uuid)); joinable!(ciphers -> organizations (organization_uuid)); joinable!(ciphers -> users (user_uuid)); @@ -313,6 +333,7 @@ joinable!(groups_users -> groups (groups_uuid)); joinable!(collections_groups -> collections (collections_uuid)); joinable!(collections_groups -> groups (groups_uuid)); joinable!(event -> users_organizations (uuid)); +joinable!(auth_requests -> users (user_uuid)); allow_tables_to_appear_in_same_query!( attachments, @@ -336,4 +357,5 @@ allow_tables_to_appear_in_same_query!( groups_users, collections_groups, event, + auth_requests, ); diff --git a/src/main.rs b/src/main.rs index 29eccaeab1f..33d802ee529 100644 --- a/src/main.rs +++ b/src/main.rs @@ -82,9 +82,12 @@ mod mail; mod ratelimit; mod util; +use crate::api::purge_auth_requests; +use crate::api::WS_ANONYMOUS_SUBSCRIPTIONS; pub use config::CONFIG; pub use error::{Error, MapResult}; use rocket::data::{Limits, ToByteUnit}; +use std::sync::Arc; pub use util::is_running_in_docker; #[rocket::main] @@ -533,6 +536,7 @@ async fn launch_rocket(pool: db::DbPool, extra_debug: bool) -> Result<(), Error> .register([basepath, "/admin"].concat(), api::admin_catchers()) .manage(pool) .manage(api::start_notification_server()) + .manage(Arc::clone(&WS_ANONYMOUS_SUBSCRIPTIONS)) .attach(util::AppHeaders()) .attach(util::Cors()) .attach(util::BetterLogging(extra_debug)) @@ -608,6 +612,12 @@ fn schedule_jobs(pool: db::DbPool) { })); } + if !CONFIG.auth_request_purge_schedule().is_empty() { + sched.add(Job::new(CONFIG.auth_request_purge_schedule().parse().unwrap(), || { + runtime.spawn(purge_auth_requests(pool.clone())); + })); + } + // Cleanup the event table of records x days old. if CONFIG.org_events_enabled() && !CONFIG.event_cleanup_schedule().is_empty()