Compare commits

..

8 Commits

Author SHA1 Message Date
Daniel
1109293992 Update Rust to 1.84.1 (#5508)
- also update the crates
- add necessary modifications for `rand` upgrade
- `small_rng` is enabled by default now
2025-02-01 13:16:32 +01:00
Mathijs van Veluw
3c29f82974 Allow all manager to create collections again (#5488)
* Allow all manager to create collections again

This commit checks if the member is a manager or better, and if so allows it to createCollections.
We actually check if it is less then a Manager, since the `limitCollectionCreation` should be set to false to allow it and true to prevent.

This should fix an issue discussed in #5484

Signed-off-by: BlackDex <black.dex@gmail.com>

* Fix some small issues

Signed-off-by: BlackDex <black.dex@gmail.com>

---------

Signed-off-by: BlackDex <black.dex@gmail.com>
2025-01-29 20:41:31 +01:00
Roman Ratiner
663f88e717 Fix Duo Field Names for Web Client (#5491)
* Fix Duo Field Names for Web Client

* Fix Api Validation

* Rename Duo Labels In Admin
2025-01-29 12:00:14 +01:00
Stefan Melmuk
a3dccee243 add and use new event types (#5482)
* add additional event_types

* use correct event_type when leaving an org

* use correct event type when deleting a user

* also correctly log auth requests

* add correct membership info to event log
2025-01-28 11:25:53 +01:00
Mathijs van Veluw
c0ebe0d982 Fix passwordRevisionDate format (#5477) 2025-01-27 20:16:59 +01:00
Win‮8201‭Linux‬
1b46c80389 Make sure the icons are displayed correctly in desktop clients (#5469) 2025-01-27 18:29:24 +01:00
Stefan Melmuk
2c549984c0 let invited members access OrgMemberHeaders (#5461) 2025-01-27 18:27:11 +01:00
Stefan Melmuk
ecab7a50ea hide already approved (or declined) devices (#5467) 2025-01-27 18:21:22 +01:00
20 changed files with 310 additions and 138 deletions

220
Cargo.lock generated
View File

@@ -26,7 +26,7 @@ dependencies = [
"cfg-if",
"once_cell",
"version_check",
"zerocopy",
"zerocopy 0.7.35",
]
[[package]]
@@ -275,9 +275,9 @@ checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de"
[[package]]
name = "async-trait"
version = "0.1.85"
version = "0.1.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f934833b4b7233644e5848f235df3f57ed8c80f1528a26c3dfa13d2147fa056"
checksum = "644dd749086bf3771a2fbc5f256fdb982d53f011c7d5d560304eafeecebce79d"
dependencies = [
"proc-macro2",
"quote",
@@ -429,9 +429,9 @@ dependencies = [
[[package]]
name = "bumpalo"
version = "3.16.0"
version = "3.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
[[package]]
name = "bytemuck"
@@ -489,9 +489,9 @@ checksum = "ade8366b8bd5ba243f0a58f036cc0ca8a2f069cff1a2351ef1cac6b083e16fc0"
[[package]]
name = "cc"
version = "1.2.10"
version = "1.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13208fcbb66eaeffe09b99fffbe1af420f00a7b35aa99ad683dfc1aa76145229"
checksum = "e4730490333d58093109dc02c23174c3f4d490998c3fed3cc8e82d57afedb9cf"
dependencies = [
"shlex",
]
@@ -608,9 +608,9 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "cpufeatures"
version = "0.2.16"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3"
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
dependencies = [
"libc",
]
@@ -808,9 +808,9 @@ dependencies = [
[[package]]
name = "diesel"
version = "2.2.6"
version = "2.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccf1bedf64cdb9643204a36dd15b19a6ce8e7aa7f7b105868e9f1fad5ffa7d12"
checksum = "04001f23ba8843dc315804fa324000376084dfb1c30794ff68dd279e6e5696d5"
dependencies = [
"bigdecimal",
"bitflags",
@@ -923,9 +923,9 @@ checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
[[package]]
name = "dsl_auto_type"
version = "0.1.2"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5d9abe6314103864cc2d8901b7ae224e0ab1a103a0a416661b4097b0779b607"
checksum = "139ae9aca7527f85f26dd76483eb38533fd84bd571065da1739656ef71c5ff5b"
dependencies = [
"darling",
"either",
@@ -1242,10 +1242,22 @@ dependencies = [
"cfg-if",
"js-sys",
"libc",
"wasi",
"wasi 0.11.0+wasi-snapshot-preview1",
"wasm-bindgen",
]
[[package]]
name = "getrandom"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8"
dependencies = [
"cfg-if",
"libc",
"wasi 0.13.3+wasi-0.2.2",
"windows-targets 0.52.6",
]
[[package]]
name = "gimli"
version = "0.31.1"
@@ -1286,7 +1298,7 @@ dependencies = [
"parking_lot",
"portable-atomic",
"quanta",
"rand",
"rand 0.8.5",
"smallvec",
"spinning_top",
]
@@ -1396,7 +1408,7 @@ dependencies = [
"idna",
"ipnet",
"once_cell",
"rand",
"rand 0.8.5",
"thiserror 1.0.69",
"tinyvec",
"tokio",
@@ -1417,7 +1429,7 @@ dependencies = [
"lru-cache",
"once_cell",
"parking_lot",
"rand",
"rand 0.8.5",
"resolv-conf",
"smallvec",
"thiserror 1.0.69",
@@ -1523,9 +1535,9 @@ dependencies = [
[[package]]
name = "httparse"
version = "1.9.5"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946"
checksum = "f2d708df4e7140240a16cd6ab0ab65c972d7433ab77819ea693fde9c43811e2a"
[[package]]
name = "httpdate"
@@ -1558,9 +1570,9 @@ dependencies = [
[[package]]
name = "hyper"
version = "1.5.2"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "256fb8d4bd6413123cc9d91832d78325c48ff41677595be797d90f42969beae0"
checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80"
dependencies = [
"bytes",
"futures-channel",
@@ -1584,9 +1596,9 @@ checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2"
dependencies = [
"futures-util",
"http 1.2.0",
"hyper 1.5.2",
"hyper 1.6.0",
"hyper-util",
"rustls 0.23.21",
"rustls 0.23.22",
"rustls-pki-types",
"tokio",
"tokio-rustls 0.26.1",
@@ -1601,7 +1613,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
dependencies = [
"bytes",
"http-body-util",
"hyper 1.5.2",
"hyper 1.6.0",
"hyper-util",
"native-tls",
"tokio",
@@ -1620,7 +1632,7 @@ dependencies = [
"futures-util",
"http 1.2.0",
"http-body 1.0.1",
"hyper 1.5.2",
"hyper 1.6.0",
"pin-project-lite",
"socket2",
"tokio",
@@ -1969,9 +1981,9 @@ dependencies = [
[[package]]
name = "libsqlite3-sys"
version = "0.30.1"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149"
checksum = "ad8935b44e7c13394a179a438e0cebba0fe08fe01b54f152e29a93b5cf993fd4"
dependencies = [
"cc",
"pkg-config",
@@ -2132,7 +2144,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
dependencies = [
"libc",
"wasi",
"wasi 0.11.0+wasi-snapshot-preview1",
"windows-sys 0.52.0",
]
@@ -2167,9 +2179,9 @@ dependencies = [
[[package]]
name = "native-tls"
version = "0.2.12"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466"
checksum = "0dab59f8e050d5df8e4dd87d9206fb6f65a483e20ac9fda365ade4fab353196c"
dependencies = [
"libc",
"log",
@@ -2310,9 +2322,9 @@ checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
[[package]]
name = "openssl"
version = "0.10.68"
version = "0.10.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5"
checksum = "f5e534d133a060a3c19daec1eb3e98ec6f4685978834f2dbadfe2ec215bab64e"
dependencies = [
"bitflags",
"cfg-if",
@@ -2413,7 +2425,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166"
dependencies = [
"base64ct",
"rand_core",
"rand_core 0.6.4",
"subtle",
]
@@ -2534,7 +2546,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
dependencies = [
"phf_shared",
"rand",
"rand 0.8.5",
]
[[package]]
@@ -2627,15 +2639,16 @@ version = "0.2.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
dependencies = [
"zerocopy",
"zerocopy 0.7.35",
]
[[package]]
name = "pq-sys"
version = "0.6.3"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6cc05d7ea95200187117196eee9edd0644424911821aeb28a18ce60ea0b8793"
checksum = "30b51d65ebe1cb1f40641b15abae017fed35ccdda46e3dab1ff8768f625a3222"
dependencies = [
"libc",
"vcpkg",
]
@@ -2696,7 +2709,7 @@ dependencies = [
"libc",
"once_cell",
"raw-cpuid",
"wasi",
"wasi 0.11.0+wasi-snapshot-preview1",
"web-sys",
"winapi",
]
@@ -2740,8 +2753,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
"rand_chacha 0.3.1",
"rand_core 0.6.4",
]
[[package]]
name = "rand"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
dependencies = [
"rand_chacha 0.9.0",
"rand_core 0.9.0",
"zerocopy 0.8.14",
]
[[package]]
@@ -2751,7 +2775,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
"rand_core 0.6.4",
]
[[package]]
name = "rand_chacha"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
dependencies = [
"ppv-lite86",
"rand_core 0.9.0",
]
[[package]]
@@ -2760,7 +2794,17 @@ version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
"getrandom 0.2.15",
]
[[package]]
name = "rand_core"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b08f3c9802962f7e1b25113931d94f43ed9725bebc59db9d0c3e9a23b67e15ff"
dependencies = [
"getrandom 0.3.1",
"zerocopy 0.8.14",
]
[[package]]
@@ -2875,7 +2919,7 @@ dependencies = [
"http 1.2.0",
"http-body 1.0.1",
"http-body-util",
"hyper 1.5.2",
"hyper 1.6.0",
"hyper-rustls",
"hyper-tls",
"hyper-util",
@@ -2925,7 +2969,7 @@ checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d"
dependencies = [
"cc",
"cfg-if",
"getrandom",
"getrandom 0.2.15",
"libc",
"spin",
"untrusted",
@@ -2974,7 +3018,7 @@ dependencies = [
"num_cpus",
"parking_lot",
"pin-project-lite",
"rand",
"rand 0.8.5",
"ref-cast",
"rocket_codegen",
"rocket_http",
@@ -3102,9 +3146,9 @@ dependencies = [
[[package]]
name = "rustls"
version = "0.23.21"
version = "0.23.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f287924602bf649d949c63dc8ac8b235fa5387d394020705b80c4eb597ce5b8"
checksum = "9fb9263ab4eb695e42321db096e3b8fbd715a59b154d5c88d82db2175b681ba7"
dependencies = [
"once_cell",
"rustls-pki-types",
@@ -3133,9 +3177,9 @@ dependencies = [
[[package]]
name = "rustls-pki-types"
version = "1.10.1"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2bf47e6ff922db3825eb750c4e2ff784c6ff8fb9e13046ef6a1d1c5401b0b37"
checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c"
[[package]]
name = "rustls-webpki"
@@ -3166,9 +3210,9 @@ checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4"
[[package]]
name = "ryu"
version = "1.0.18"
version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd"
[[package]]
name = "same-file"
@@ -3280,9 +3324,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.137"
version = "1.0.138"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "930cfb6e6abf99298aaad7d29abbef7a9999a9a8806a40088f55f0dcec03146b"
checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949"
dependencies = [
"itoa",
"memchr",
@@ -3540,13 +3584,13 @@ dependencies = [
[[package]]
name = "tempfile"
version = "3.15.0"
version = "3.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704"
checksum = "38c246215d7d24f48ae091a2902398798e05d978b24315d6efbc00ede9a8bb91"
dependencies = [
"cfg-if",
"fastrand",
"getrandom",
"getrandom 0.3.1",
"once_cell",
"rustix",
"windows-sys 0.59.0",
@@ -3724,7 +3768,7 @@ version = "0.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37"
dependencies = [
"rustls 0.23.21",
"rustls 0.23.22",
"tokio",
]
@@ -3799,9 +3843,9 @@ dependencies = [
[[package]]
name = "toml_edit"
version = "0.22.22"
version = "0.22.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
checksum = "02a8b472d1a3d7c18e2d61a489aee3453fd9031c33e4f55bd533f4a7adca1bee"
dependencies = [
"indexmap",
"serde",
@@ -3929,7 +3973,7 @@ dependencies = [
"http 1.2.0",
"httparse",
"log",
"rand",
"rand 0.8.5",
"sha1",
"thiserror 1.0.69",
"url",
@@ -3969,9 +4013,9 @@ dependencies = [
[[package]]
name = "unicode-ident"
version = "1.0.15"
version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11cd88e12b17c6494200a9c1b683a04fcac9573ed74cd1b62aeb2727c5592243"
checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"
[[package]]
name = "unicode-xid"
@@ -4021,7 +4065,7 @@ version = "1.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3758f5e68192bb96cc8f9b7e2c2cfdabb435499a28499a42f8f984092adad4b"
dependencies = [
"getrandom",
"getrandom 0.2.15",
]
[[package]]
@@ -4079,7 +4123,7 @@ dependencies = [
"paste",
"percent-encoding",
"pico-args",
"rand",
"rand 0.9.0",
"regex",
"reqwest",
"ring",
@@ -4139,6 +4183,15 @@ version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasi"
version = "0.13.3+wasi-0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2"
dependencies = [
"wit-bindgen-rt",
]
[[package]]
name = "wasm-bindgen"
version = "0.2.100"
@@ -4252,7 +4305,7 @@ dependencies = [
"base64 0.13.1",
"nom",
"openssl",
"rand",
"rand 0.8.5",
"serde",
"serde_cbor",
"serde_derive",
@@ -4519,9 +4572,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "winnow"
version = "0.6.24"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8d71a593cc5c42ad7876e2c1fda56f314f3754c084128833e64f1345ff8a03a"
checksum = "7e49d2d35d3fad69b39b94139037ecfb4f359f08958b9c11e7315ce770462419"
dependencies = [
"memchr",
]
@@ -4542,6 +4595,15 @@ version = "0.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904"
[[package]]
name = "wit-bindgen-rt"
version = "0.33.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
dependencies = [
"bitflags",
]
[[package]]
name = "write16"
version = "1.0.0"
@@ -4596,7 +4658,7 @@ dependencies = [
"form_urlencoded",
"futures",
"hmac",
"rand",
"rand 0.8.5",
"reqwest",
"sha1",
"threadpool",
@@ -4609,7 +4671,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
dependencies = [
"byteorder",
"zerocopy-derive",
"zerocopy-derive 0.7.35",
]
[[package]]
name = "zerocopy"
version = "0.8.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a367f292d93d4eab890745e75a778da40909cab4d6ff8173693812f79c4a2468"
dependencies = [
"zerocopy-derive 0.8.14",
]
[[package]]
@@ -4623,6 +4694,17 @@ dependencies = [
"syn",
]
[[package]]
name = "zerocopy-derive"
version = "0.8.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3931cb58c62c13adec22e38686b559c86a30565e16ad6e8510a337cedc611e1"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "zerofrom"
version = "0.1.5"

View File

@@ -75,10 +75,10 @@ tokio = { version = "1.43.0", features = ["rt-multi-thread", "fs", "io-util", "p
# A generic serialization/deserialization framework
serde = { version = "1.0.217", features = ["derive"] }
serde_json = "1.0.137"
serde_json = "1.0.138"
# A safe, extensible ORM and Query builder
diesel = { version = "2.2.6", features = ["chrono", "r2d2", "numeric"] }
diesel = { version = "2.2.7", features = ["chrono", "r2d2", "numeric"] }
diesel_migrations = "2.2.0"
diesel_logger = { version = "0.4.0", optional = true }
@@ -86,10 +86,10 @@ derive_more = { version = "1.0.0", features = ["from", "into", "as_ref", "deref"
diesel-derive-newtype = "2.1.2"
# Bundled/Static SQLite
libsqlite3-sys = { version = "0.30.1", features = ["bundled"], optional = true }
libsqlite3-sys = { version = "0.31.0", features = ["bundled"], optional = true }
# Crypto-related libraries
rand = { version = "0.8.5", features = ["small_rng"] }
rand = "0.9.0"
ring = "0.17.8"
# UUID generation
@@ -147,7 +147,7 @@ cookie = "0.18.1"
cookie_store = "0.21.1"
# Used by U2F, JWT and PostgreSQL
openssl = "0.10.68"
openssl = "0.10.69"
# CLI argument parsing
pico-args = "0.5.0"

View File

@@ -5,7 +5,7 @@ vault_image_digest: "sha256:cb6b2095a4afc1d9d243a33f6d09211f40e3d82c7ae829fd025d
# We use the linux/amd64 platform shell scripts since there is no difference between the different platform scripts
# https://github.com/tonistiigi/xx | https://hub.docker.com/r/tonistiigi/xx/tags
xx_image_digest: "sha256:9c207bead753dda9430bdd15425c6518fc7a03d866103c516a2c6889188f5894"
rust_version: 1.84.0 # Rust version to be used
rust_version: 1.84.1 # Rust version to be used
debian_version: bookworm # Debian release name to be used
alpine_version: "3.21" # Alpine version to be used
# For which platforms/architectures will we try to build images

View File

@@ -32,10 +32,10 @@ FROM --platform=linux/amd64 docker.io/vaultwarden/web-vault@sha256:cb6b2095a4afc
########################## ALPINE BUILD IMAGES ##########################
## NOTE: The Alpine Base Images do not support other platforms then linux/amd64
## And for Alpine we define all build images here, they will only be loaded when actually used
FROM --platform=linux/amd64 ghcr.io/blackdex/rust-musl:x86_64-musl-stable-1.84.0 AS build_amd64
FROM --platform=linux/amd64 ghcr.io/blackdex/rust-musl:aarch64-musl-stable-1.84.0 AS build_arm64
FROM --platform=linux/amd64 ghcr.io/blackdex/rust-musl:armv7-musleabihf-stable-1.84.0 AS build_armv7
FROM --platform=linux/amd64 ghcr.io/blackdex/rust-musl:arm-musleabi-stable-1.84.0 AS build_armv6
FROM --platform=linux/amd64 ghcr.io/blackdex/rust-musl:x86_64-musl-stable-1.84.1 AS build_amd64
FROM --platform=linux/amd64 ghcr.io/blackdex/rust-musl:aarch64-musl-stable-1.84.1 AS build_arm64
FROM --platform=linux/amd64 ghcr.io/blackdex/rust-musl:armv7-musleabihf-stable-1.84.1 AS build_armv7
FROM --platform=linux/amd64 ghcr.io/blackdex/rust-musl:arm-musleabi-stable-1.84.1 AS build_armv6
########################## BUILD IMAGE ##########################
# hadolint ignore=DL3006

View File

@@ -36,7 +36,7 @@ FROM --platform=linux/amd64 docker.io/tonistiigi/xx@sha256:9c207bead753dda9430bd
########################## BUILD IMAGE ##########################
# hadolint ignore=DL3006
FROM --platform=$BUILDPLATFORM docker.io/library/rust:1.84.0-slim-bookworm AS build
FROM --platform=$BUILDPLATFORM docker.io/library/rust:1.84.1-slim-bookworm AS build
COPY --from=xx / /
ARG TARGETARCH
ARG TARGETVARIANT

View File

@@ -1,4 +1,4 @@
[toolchain]
channel = "1.84.0"
channel = "1.84.1"
components = [ "rustfmt", "clippy" ]
profile = "minimal"

View File

@@ -403,7 +403,7 @@ async fn delete_user(user_id: UserId, token: AdminToken, mut conn: DbConn) -> Em
for membership in memberships {
log_event(
EventType::OrganizationUserRemoved as i32,
EventType::OrganizationUserDeleted as i32,
&membership.uuid,
&membership.org_uuid,
&ACTING_ADMIN_USER.into(),

View File

@@ -925,9 +925,9 @@ async fn password_hint(data: Json<PasswordHintData>, mut conn: DbConn) -> EmptyR
// paths that send mail take noticeably longer than ones that
// don't. Add a randomized sleep to mitigate this somewhat.
use rand::{rngs::SmallRng, Rng, SeedableRng};
let mut rng = SmallRng::from_entropy();
let mut rng = SmallRng::from_os_rng();
let delta: i32 = 100;
let sleep_ms = (1_000 + rng.gen_range(-delta..=delta)) as u64;
let sleep_ms = (1_000 + rng.random_range(-delta..=delta)) as u64;
tokio::time::sleep(tokio::time::Duration::from_millis(sleep_ms)).await;
Ok(())
} else {
@@ -1206,6 +1206,15 @@ async fn post_auth_request(
nt.send_auth_request(&user.uuid, &auth_request.uuid, &data.device_identifier, &mut conn).await;
log_user_event(
EventType::UserRequestedDeviceApproval as i32,
&user.uuid,
client_headers.device_type,
&client_headers.ip.ip,
&mut conn,
)
.await;
Ok(Json(json!({
"id": auth_request.uuid,
"publicKey": auth_request.public_key,
@@ -1287,9 +1296,26 @@ async fn put_auth_request(
ant.send_auth_response(&auth_request.user_uuid, &auth_request.uuid).await;
nt.send_auth_response(&auth_request.user_uuid, &auth_request.uuid, &data.device_identifier, &mut conn).await;
log_user_event(
EventType::OrganizationUserApprovedAuthRequest as i32,
&headers.user.uuid,
headers.device.atype,
&headers.ip.ip,
&mut conn,
)
.await;
} else {
// If denied, there's no reason to keep the request
auth_request.delete(&mut conn).await?;
log_user_event(
EventType::OrganizationUserRejectedAuthRequest as i32,
&headers.user.uuid,
headers.device.atype,
&headers.ip.ip,
&mut conn,
)
.await;
}
Ok(Json(json!({

View File

@@ -245,8 +245,8 @@ async fn _log_user_event(
ip: &IpAddr,
conn: &mut DbConn,
) {
let orgs = Membership::get_orgs_by_user(user_id, conn).await;
let mut events: Vec<Event> = Vec::with_capacity(orgs.len() + 1); // We need an event per org and one without an org
let memberships = Membership::find_by_user(user_id, conn).await;
let mut events: Vec<Event> = Vec::with_capacity(memberships.len() + 1); // We need an event per org and one without an org
// Upstream saves the event also without any org_id.
let mut event = Event::new(event_type, event_date);
@@ -257,10 +257,11 @@ async fn _log_user_event(
events.push(event);
// For each org a user is a member of store these events per org
for org_id in orgs {
for membership in memberships {
let mut event = Event::new(event_type, event_date);
event.user_uuid = Some(user_id.clone());
event.org_uuid = Some(org_id);
event.org_uuid = Some(membership.org_uuid);
event.org_user_uuid = Some(membership.uuid);
event.act_user_uuid = Some(user_id.clone());
event.device_type = Some(device_type);
event.ip_address = Some(ip.to_string());

View File

@@ -251,7 +251,7 @@ async fn leave_organization(org_id: OrganizationId, headers: Headers, mut conn:
}
log_event(
EventType::OrganizationUserRemoved as i32,
EventType::OrganizationUserLeft as i32,
&member.uuid,
&org_id,
&headers.user.uuid,
@@ -485,7 +485,7 @@ async fn post_organization_collections(
CollectionUser::save(&headers.membership.user_uuid, &collection.uuid, false, false, false, &mut conn).await?;
}
Ok(Json(collection.to_json()))
Ok(Json(collection.to_json_details(&headers.membership.user_uuid, None, &mut conn).await))
}
#[put("/organizations/<org_id>/collections/<col_id>", data = "<data>")]
@@ -722,18 +722,19 @@ async fn get_org_collection_detail(
.map(|m| (m.uuid, m.atype))
.collect();
let users: Vec<Value> =
CollectionUser::find_by_collection_swap_user_uuid_with_member_uuid(&collection.uuid, &mut conn)
.await
.iter()
.map(|collection_member| {
collection_member.to_json_details_for_member(
*membership_type
.get(&collection_member.membership_uuid)
.unwrap_or(&(MembershipType::User as i32)),
)
})
.collect();
let users: Vec<Value> = CollectionUser::find_by_org_and_coll_swap_user_uuid_with_member_uuid(
&org_id,
&collection.uuid,
&mut conn,
)
.await
.iter()
.map(|collection_member| {
collection_member.to_json_details_for_member(
*membership_type.get(&collection_member.membership_uuid).unwrap_or(&(MembershipType::User as i32)),
)
})
.collect();
let assigned = Collection::can_access_collection(&member, &collection.uuid, &mut conn).await;

View File

@@ -26,8 +26,8 @@ pub fn routes() -> Vec<Route> {
#[derive(Serialize, Deserialize)]
struct DuoData {
host: String, // Duo API hostname
ik: String, // integration key
sk: String, // secret key
ik: String, // client id
sk: String, // client secret
}
impl DuoData {
@@ -111,8 +111,8 @@ async fn get_duo(data: Json<PasswordOrOtpData>, headers: Headers, mut conn: DbCo
json!({
"enabled": enabled,
"host": data.host,
"secretKey": data.sk,
"integrationKey": data.ik,
"clientSecret": data.sk,
"clientId": data.ik,
"object": "twoFactorDuo"
})
} else {
@@ -129,8 +129,8 @@ async fn get_duo(data: Json<PasswordOrOtpData>, headers: Headers, mut conn: DbCo
#[serde(rename_all = "camelCase")]
struct EnableDuoData {
host: String,
secret_key: String,
integration_key: String,
client_secret: String,
client_id: String,
master_password_hash: Option<String>,
otp: Option<String>,
}
@@ -139,8 +139,8 @@ impl From<EnableDuoData> for DuoData {
fn from(d: EnableDuoData) -> Self {
Self {
host: d.host,
ik: d.integration_key,
sk: d.secret_key,
ik: d.client_id,
sk: d.client_secret,
}
}
}
@@ -151,7 +151,7 @@ fn check_duo_fields_custom(data: &EnableDuoData) -> bool {
st.is_empty() || s == DISABLED_MESSAGE_DEFAULT
}
!empty_or_default(&data.host) && !empty_or_default(&data.secret_key) && !empty_or_default(&data.integration_key)
!empty_or_default(&data.host) && !empty_or_default(&data.client_secret) && !empty_or_default(&data.client_id)
}
#[post("/two-factor/duo", data = "<data>")]
@@ -186,8 +186,8 @@ async fn activate_duo(data: Json<EnableDuoData>, headers: Headers, mut conn: DbC
Ok(Json(json!({
"enabled": true,
"host": data.host,
"secretKey": data.sk,
"integrationKey": data.ik,
"clientSecret": data.sk,
"clientId": data.ik,
"object": "twoFactorDuo"
})))
}

View File

@@ -542,10 +542,29 @@ pub struct OrgHeaders {
pub device: Device,
pub user: User,
pub membership_type: MembershipType,
pub membership_status: MembershipStatus,
pub membership: Membership,
pub ip: ClientIp,
}
impl OrgHeaders {
fn is_member(&self) -> bool {
// NOTE: we don't care about MembershipStatus at the moment because this is only used
// where an invited, accepted or confirmed user is expected if this ever changes or
// if from_i32 is changed to return Some(Revoked) this check needs to be changed accordingly
self.membership_type >= MembershipType::User
}
fn is_confirmed_and_admin(&self) -> bool {
self.membership_status == MembershipStatus::Confirmed && self.membership_type >= MembershipType::Admin
}
fn is_confirmed_and_manager(&self) -> bool {
self.membership_status == MembershipStatus::Confirmed && self.membership_type >= MembershipType::Manager
}
fn is_confirmed_and_owner(&self) -> bool {
self.membership_status == MembershipStatus::Confirmed && self.membership_type == MembershipType::Owner
}
}
#[rocket::async_trait]
impl<'r> FromRequest<'r> for OrgHeaders {
type Error = &'static str;
@@ -574,15 +593,8 @@ impl<'r> FromRequest<'r> for OrgHeaders {
};
let user = headers.user;
let membership = match Membership::find_by_user_and_org(&user.uuid, &org_id, &mut conn).await {
Some(member) => {
if member.status == MembershipStatus::Confirmed as i32 {
member
} else {
err_handler!("The current user isn't confirmed member of the organization")
}
}
None => err_handler!("The current user isn't member of the organization"),
let Some(membership) = Membership::find_by_user_and_org(&user.uuid, &org_id, &mut conn).await else {
err_handler!("The current user isn't member of the organization");
};
Outcome::Success(Self {
@@ -590,13 +602,22 @@ impl<'r> FromRequest<'r> for OrgHeaders {
device: headers.device,
user,
membership_type: {
if let Some(org_usr_type) = MembershipType::from_i32(membership.atype) {
org_usr_type
if let Some(member_type) = MembershipType::from_i32(membership.atype) {
member_type
} else {
// This should only happen if the DB is corrupted
err_handler!("Unknown user type in the database")
}
},
membership_status: {
if let Some(member_status) = MembershipStatus::from_i32(membership.status) {
// NOTE: add additional check for revoked if from_i32 is ever changed
// to return Revoked status.
member_status
} else {
err_handler!("User status is either revoked or invalid.")
}
},
membership,
ip: headers.ip,
})
@@ -621,7 +642,7 @@ impl<'r> FromRequest<'r> for AdminHeaders {
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
let headers = try_outcome!(OrgHeaders::from_request(request).await);
if headers.membership_type >= MembershipType::Admin {
if headers.is_confirmed_and_admin() {
Outcome::Success(Self {
host: headers.host,
device: headers.device,
@@ -683,7 +704,7 @@ impl<'r> FromRequest<'r> for ManagerHeaders {
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
let headers = try_outcome!(OrgHeaders::from_request(request).await);
if headers.membership_type >= MembershipType::Manager {
if headers.is_confirmed_and_manager() {
match get_col_id(request) {
Some(col_id) => {
let mut conn = match DbConn::from_request(request).await {
@@ -738,7 +759,7 @@ impl<'r> FromRequest<'r> for ManagerHeadersLoose {
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
let headers = try_outcome!(OrgHeaders::from_request(request).await);
if headers.membership_type >= MembershipType::Manager {
if headers.is_confirmed_and_manager() {
Outcome::Success(Self {
host: headers.host,
device: headers.device,
@@ -801,7 +822,7 @@ impl<'r> FromRequest<'r> for OwnerHeaders {
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
let headers = try_outcome!(OrgHeaders::from_request(request).await);
if headers.membership_type == MembershipType::Owner {
if headers.is_confirmed_and_owner() {
Outcome::Success(Self {
device: headers.device,
user: headers.user,
@@ -826,7 +847,7 @@ impl<'r> FromRequest<'r> for OrgMemberHeaders {
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
let headers = try_outcome!(OrgHeaders::from_request(request).await);
if headers.membership_type >= MembershipType::User {
if headers.is_member() {
Outcome::Success(Self {
host: headers.host,
user: headers.user,

View File

@@ -670,9 +670,9 @@ make_config! {
_enable_duo: bool, true, def, true;
/// Attempt to use deprecated iframe-based Traditional Prompt (Duo WebSDK 2)
duo_use_iframe: bool, false, def, false;
/// Integration Key
/// Client Id
duo_ikey: String, true, option;
/// Secret Key
/// Client Secret
duo_skey: Pass, true, option;
/// Host
duo_host: String, true, option;

View File

@@ -56,11 +56,11 @@ pub fn encode_random_bytes<const N: usize>(e: Encoding) -> String {
pub fn get_random_string(alphabet: &[u8], num_chars: usize) -> String {
// Ref: https://rust-lang-nursery.github.io/rust-cookbook/algorithms/randomness.html
use rand::Rng;
let mut rng = rand::thread_rng();
let mut rng = rand::rng();
(0..num_chars)
.map(|_| {
let i = rng.gen_range(0..alphabet.len());
let i = rng.random_range(0..alphabet.len());
alphabet[i] as char
})
.collect()

View File

@@ -150,6 +150,7 @@ impl AuthRequest {
auth_requests::table
.filter(auth_requests::user_uuid.eq(user_uuid))
.filter(auth_requests::request_device_identifier.eq(device_uuid))
.filter(auth_requests::approved.is_null())
.order_by(auth_requests::creation_date.desc())
.first::<AuthRequestDb>(conn).ok().from_db()
}}

View File

@@ -142,7 +142,7 @@ impl Cipher {
sync_type: CipherSyncType,
conn: &mut DbConn,
) -> Value {
use crate::util::format_date;
use crate::util::{format_date, validate_and_format_date};
let mut attachments_json: Value = Value::Null;
if let Some(cipher_sync_data) = cipher_sync_data {
@@ -220,7 +220,7 @@ impl Cipher {
})
.map(|mut d| match d.get("lastUsedDate").and_then(|l| l.as_str()) {
Some(l) => {
d["lastUsedDate"] = json!(crate::util::validate_and_format_date(l));
d["lastUsedDate"] = json!(validate_and_format_date(l));
d
}
_ => {
@@ -261,6 +261,11 @@ impl Cipher {
type_data_json["uri"] = uris[0]["uri"].clone();
}
}
// Check if `passwordRevisionDate` is a valid date, else convert it
if let Some(pw_revision) = type_data_json["passwordRevisionDate"].as_str() {
type_data_json["passwordRevisionDate"] = json!(validate_and_format_date(pw_revision));
}
}
// Fix secure note issues when data is invalid

View File

@@ -589,6 +589,7 @@ impl CollectionUser {
.inner_join(collections::table.on(collections::uuid.eq(users_collections::collection_uuid)))
.filter(collections::org_uuid.eq(org_uuid))
.inner_join(users_organizations::table.on(users_organizations::user_uuid.eq(users_collections::user_uuid)))
.filter(users_organizations::org_uuid.eq(org_uuid))
.select((users_organizations::uuid, users_collections::collection_uuid, users_collections::read_only, users_collections::hide_passwords, users_collections::manage))
.load::<CollectionUserDb>(conn)
.expect("Error loading users_collections")
@@ -685,13 +686,15 @@ impl CollectionUser {
}}
}
pub async fn find_by_collection_swap_user_uuid_with_member_uuid(
pub async fn find_by_org_and_coll_swap_user_uuid_with_member_uuid(
org_uuid: &OrganizationId,
collection_uuid: &CollectionId,
conn: &mut DbConn,
) -> Vec<CollectionMembership> {
let col_users = db_run! { conn: {
users_collections::table
.filter(users_collections::collection_uuid.eq(collection_uuid))
.filter(users_organizations::org_uuid.eq(org_uuid))
.inner_join(users_organizations::table.on(users_organizations::user_uuid.eq(users_collections::user_uuid)))
.select((users_organizations::uuid, users_collections::collection_uuid, users_collections::read_only, users_collections::hide_passwords, users_collections::manage))
.load::<CollectionUserDb>(conn)

View File

@@ -49,6 +49,8 @@ pub enum EventType {
UserClientExportedVault = 1007,
// UserUpdatedTempPassword = 1008, // Not supported
// UserMigratedKeyToKeyConnector = 1009, // Not supported
UserRequestedDeviceApproval = 1010,
// UserTdeOffboardingPasswordSet = 1011, // Not supported
// Cipher
CipherCreated = 1100,
@@ -69,6 +71,7 @@ pub enum EventType {
CipherSoftDeleted = 1115,
CipherRestored = 1116,
CipherClientToggledCardNumberVisible = 1117,
CipherClientToggledTOTPSeedVisible = 1118,
// Collection
CollectionCreated = 1300,
@@ -94,6 +97,10 @@ pub enum EventType {
// OrganizationUserFirstSsoLogin = 1510, // Not supported
OrganizationUserRevoked = 1511,
OrganizationUserRestored = 1512,
OrganizationUserApprovedAuthRequest = 1513,
OrganizationUserRejectedAuthRequest = 1514,
OrganizationUserDeleted = 1515,
OrganizationUserLeft = 1516,
// Organization
OrganizationUpdated = 1600,
@@ -105,6 +112,7 @@ pub enum EventType {
// OrganizationEnabledKeyConnector = 1606, // Not supported
// OrganizationDisabledKeyConnector = 1607, // Not supported
// OrganizationSponsorshipsSynced = 1608, // Not supported
// OrganizationCollectionManagementUpdated = 1609, // Not supported
// Policy
PolicyUpdated = 1700,
@@ -117,6 +125,13 @@ pub enum EventType {
// ProviderOrganizationAdded = 1901, // Not supported
// ProviderOrganizationRemoved = 1902, // Not supported
// ProviderOrganizationVaultAccessed = 1903, // Not supported
// OrganizationDomainAdded = 2000, // Not supported
// OrganizationDomainRemoved = 2001, // Not supported
// OrganizationDomainVerified = 2002, // Not supported
// OrganizationDomainNotVerified = 2003, // Not supported
// SecretRetrieved = 2100, // Not supported
}
/// Local methods

View File

@@ -55,6 +55,7 @@ db_object! {
}
// https://github.com/bitwarden/server/blob/b86a04cef9f1e1b82cf18e49fc94e017c641130c/src/Core/Enums/OrganizationUserStatusType.cs
#[derive(PartialEq)]
pub enum MembershipStatus {
Revoked = -1,
Invited = 0,
@@ -62,6 +63,19 @@ pub enum MembershipStatus {
Confirmed = 2,
}
impl MembershipStatus {
pub fn from_i32(status: i32) -> Option<Self> {
match status {
0 => Some(Self::Invited),
1 => Some(Self::Accepted),
2 => Some(Self::Confirmed),
// NOTE: we don't care about revoked members where this is used
// if this ever changes also adapt the OrgHeaders check.
_ => None,
}
}
}
#[derive(Copy, Clone, PartialEq, Eq, num_derive::FromPrimitive)]
pub enum MembershipType {
Owner = 0,
@@ -450,7 +464,7 @@ impl Membership {
"familySponsorshipValidUntil": null,
"familySponsorshipToDelete": null,
"accessSecretsManager": false,
"limitCollectionCreation": true,
"limitCollectionCreation": self.atype < MembershipType::Manager, // If less then a manager return true, to limit collection creations
"limitCollectionCreationDeletion": true,
"limitCollectionDeletion": true,
"allowAdminAccessToAllCollectionItems": true,

View File

@@ -55,7 +55,10 @@ impl Fairing for AppHeaders {
res.set_raw_header("Referrer-Policy", "same-origin");
res.set_raw_header("X-Content-Type-Options", "nosniff");
res.set_raw_header("X-Robots-Tag", "noindex, nofollow");
res.set_raw_header("Cross-Origin-Resource-Policy", "same-origin");
if !res.headers().get_one("Content-Type").is_some_and(|v| v.starts_with("image/")) {
res.set_raw_header("Cross-Origin-Resource-Policy", "same-origin");
}
// Obsolete in modern browsers, unsafe (XS-Leak), and largely replaced by CSP
res.set_raw_header("X-XSS-Protection", "0");