bump to v1.6.2

This commit is contained in:
rustmailer
2026-07-08 23:55:05 +08:00
parent 166ac21549
commit 7dee5a7874
4 changed files with 380 additions and 148 deletions
Generated
+223 -104
View File
@@ -225,7 +225,7 @@ dependencies = [
"async-channel 2.5.0",
"async-compression",
"base64 0.22.1",
"bytes 1.11.1",
"bytes 1.12.0",
"chrono",
"futures",
"imap-proto",
@@ -299,7 +299,7 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "bichon-admin"
version = "1.6.1"
version = "1.6.2"
dependencies = [
"bichon-core",
"bichon-memdb",
@@ -323,7 +323,7 @@ dependencies = [
"crc32fast",
"criterion",
"lz4_flex",
"rand 0.10.1",
"rand 0.10.2",
"serde",
"serde_json",
"tempfile",
@@ -334,7 +334,7 @@ dependencies = [
[[package]]
name = "bichon-cli"
version = "1.6.1"
version = "1.6.2"
dependencies = [
"base64 0.22.1",
"bichon-core",
@@ -356,13 +356,13 @@ dependencies = [
[[package]]
name = "bichon-core"
version = "1.6.1"
version = "1.6.2"
dependencies = [
"async-imap",
"base64 0.22.1",
"bichon-memdb",
"blake3",
"bytes 1.11.1",
"bytes 1.12.0",
"chrono",
"clap",
"codepage-strings",
@@ -389,8 +389,8 @@ dependencies = [
"oauth2",
"outlook-pst",
"poem-openapi",
"quick-xml 0.40.0",
"rand 0.10.1",
"quick-xml 0.41.0",
"rand 0.10.2",
"regex",
"reqwest",
"ring",
@@ -432,7 +432,7 @@ dependencies = [
[[package]]
name = "bichon-server"
version = "1.6.1"
version = "1.6.2"
dependencies = [
"bichon-core",
"bichon-smtp",
@@ -457,7 +457,7 @@ dependencies = [
[[package]]
name = "bichon-smtp"
version = "1.6.1"
version = "1.6.2"
dependencies = [
"base64 0.22.1",
"bichon-core",
@@ -577,6 +577,16 @@ dependencies = [
"alloc-stdlib",
]
[[package]]
name = "bstr"
version = "1.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5cee35f73844aa3014bb606320a6c1f010249dbdf43342fe54b5a4f6a8ed4b79"
dependencies = [
"memchr",
"serde_core",
]
[[package]]
name = "bumpalo"
version = "3.20.2"
@@ -609,9 +619,9 @@ checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
[[package]]
name = "bytes"
version = "1.11.1"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
checksum = "8ae3f5d315924270530207e2a68396c3cc547f6dca3fbdca317cfb1a51edb593"
[[package]]
name = "byteview"
@@ -819,7 +829,7 @@ version = "4.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd"
dependencies = [
"bytes 1.11.1",
"bytes 1.12.0",
"memchr",
]
@@ -870,9 +880,9 @@ dependencies = [
[[package]]
name = "console"
version = "0.16.3"
version = "0.16.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d64e8af5551369d19cf50138de61f1c42074ab970f74e99be916646777f8fc87"
checksum = "4fe5f465a4f6fee88fad41b85d990f84c835335e85b5d9e6e63e0d06d28cba7c"
dependencies = [
"encode_unicode",
"libc",
@@ -895,6 +905,16 @@ dependencies = [
"unicode-segmentation",
]
[[package]]
name = "core-foundation"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "core-foundation"
version = "0.10.1"
@@ -979,13 +999,14 @@ checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
[[package]]
name = "cron"
version = "0.15.0"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5877d3fbf742507b66bc2a1945106bd30dd8504019d596901ddd012a4dd01740"
checksum = "a5dcd6f69605c2956916ce24e8af637b754964c9a83f4662d3a2361654cdba09"
dependencies = [
"chrono",
"once_cell",
"winnow 0.6.26",
"phf 0.11.3",
"winnow 0.7.15",
]
[[package]]
@@ -1290,18 +1311,6 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "enum-as-inner"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn 2.0.117",
]
[[package]]
name = "enum_dispatch"
version = "0.3.13"
@@ -1397,9 +1406,9 @@ checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
[[package]]
name = "fjall"
version = "3.1.5"
version = "3.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "038acd422d607e0eca09e093f299f9eccf9bd097554343d93746afff81a45113"
checksum = "9fcdc69609906151dff9b534e30eaf8515082055d36f628e382bd0b5d6a1d362"
dependencies = [
"byteorder-lite",
"byteview",
@@ -1649,11 +1658,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555"
dependencies = [
"cfg-if",
"js-sys",
"libc",
"r-efi 6.0.0",
"rand_core 0.10.1",
"wasip2",
"wasip3",
"wasm-bindgen",
]
[[package]]
@@ -1692,7 +1703,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54"
dependencies = [
"atomic-waker",
"bytes 1.11.1",
"bytes 1.12.0",
"fnv",
"futures-core",
"futures-sink",
@@ -1771,7 +1782,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb"
dependencies = [
"base64 0.22.1",
"bytes 1.11.1",
"bytes 1.12.0",
"headers-core",
"http",
"httpdate",
@@ -1807,28 +1818,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "hickory-proto"
version = "0.26.0-alpha.1"
name = "hickory-net"
version = "0.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a62d7684f766b0f96344be88c023f9b6650039aea09d526b4974cce302eb61b1"
checksum = "e2295ed2f9c31e471e1428a8f88a3f0e1f4b27c15049592138d1eebe9c35b183"
dependencies = [
"async-trait",
"aws-lc-rs",
"bitflags",
"bytes 1.11.1",
"bytes 1.12.0",
"cfg-if",
"data-encoding",
"enum-as-inner",
"futures-channel",
"futures-io",
"futures-util",
"hickory-proto",
"idna",
"ipnet",
"once_cell",
"rand 0.9.2",
"ring",
"jni",
"lru-cache",
"parking_lot",
"rand 0.10.2",
"rustls",
"rustls-pki-types",
"rustls-platform-verifier",
"thiserror 2.0.18",
"time",
"tinyvec",
@@ -1839,22 +1852,51 @@ dependencies = [
]
[[package]]
name = "hickory-resolver"
version = "0.26.0-alpha.1"
name = "hickory-proto"
version = "0.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbab5e26a7f82341145ba1fbd1f1858d0490624fcc46270db2d3c4a101f763f4"
checksum = "0bab31817bfb44672a252e97fe81cd0c18d1b2cf892108922f6818820df8c643"
dependencies = [
"aws-lc-rs",
"bitflags",
"data-encoding",
"idna",
"ipnet",
"jni",
"once_cell",
"prefix-trie",
"rand 0.10.2",
"ring",
"rustls-pki-types",
"thiserror 2.0.18",
"time",
"tinyvec",
"tracing",
"url",
]
[[package]]
name = "hickory-resolver"
version = "0.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0d58d28879ceecde6607729660c2667a081ccdc082e082675042793960f178c"
dependencies = [
"cfg-if",
"futures-util",
"hickory-net",
"hickory-proto",
"ipconfig",
"ipnet",
"jni",
"moka",
"ndk-context",
"once_cell",
"parking_lot",
"rand 0.9.2",
"rand 0.10.2",
"resolv-conf",
"rustls",
"smallvec",
"system-configuration",
"thiserror 2.0.18",
"tokio",
"tokio-rustls",
@@ -1906,7 +1948,7 @@ version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425"
dependencies = [
"bytes 1.11.1",
"bytes 1.12.0",
"itoa",
]
@@ -1916,7 +1958,7 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
dependencies = [
"bytes 1.11.1",
"bytes 1.12.0",
"http",
]
@@ -1926,7 +1968,7 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
dependencies = [
"bytes 1.11.1",
"bytes 1.12.0",
"futures-core",
"http",
"http-body",
@@ -1952,7 +1994,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca"
dependencies = [
"atomic-waker",
"bytes 1.11.1",
"bytes 1.12.0",
"futures-channel",
"futures-core",
"h2",
@@ -1990,7 +2032,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0"
dependencies = [
"base64 0.22.1",
"bytes 1.11.1",
"bytes 1.12.0",
"futures-channel",
"futures-util",
"http",
@@ -2168,9 +2210,9 @@ dependencies = [
[[package]]
name = "indicatif"
version = "0.18.4"
version = "0.18.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25470f23803092da7d239834776d653104d551bc4d7eacaf31e6837854b8e9eb"
checksum = "9433806cd6b4ec1aba79c021c7e4c58fb4c3b9977c085062e611ac929998fb0c"
dependencies = [
"console",
"portable-atomic",
@@ -2215,6 +2257,9 @@ name = "ipnet"
version = "2.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2"
dependencies = [
"serde",
]
[[package]]
name = "iri-string"
@@ -2402,6 +2447,12 @@ version = "0.2.185"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f"
[[package]]
name = "linked-hash-map"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
[[package]]
name = "linux-raw-sys"
version = "0.12.1"
@@ -2447,6 +2498,15 @@ dependencies = [
"hashbrown 0.17.0",
]
[[package]]
name = "lru-cache"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c"
dependencies = [
"linked-hash-map",
]
[[package]]
name = "lru-slab"
version = "0.1.2"
@@ -2455,12 +2515,12 @@ checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154"
[[package]]
name = "lsm-tree"
version = "3.1.5"
version = "3.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ef86c3c797c10eefcc73407c43ae48c19d4df686131a8334b2895a513e91df4"
checksum = "39ca67401338b98d58447387dd5230552d2241bc388206e491d137b18dfea9d6"
dependencies = [
"byteorder-lite",
"bytes 1.11.1",
"bytes 1.12.0",
"byteview",
"crossbeam-skiplist",
"enum_dispatch",
@@ -2487,20 +2547,23 @@ dependencies = [
[[package]]
name = "mail-auth"
version = "0.8.0"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f026538d37471da028cd5c6a907777c3de2d84e2c71b2b47ae301a10977c5e6"
checksum = "a88908ddf3a07fa2e76873f84d28476d3c802173fee0a44f6c5e5472523e6986"
dependencies = [
"aws-lc-rs",
"flate2",
"getrandom 0.2.17",
"getrandom 0.4.2",
"hashify",
"hickory-resolver",
"mail-builder",
"mail-parser",
"quick-xml 0.39.2",
"quick-xml 0.41.0",
"rustls-pki-types",
"serde",
"serde_json",
"similar",
"zip",
]
@@ -2526,9 +2589,9 @@ dependencies = [
[[package]]
name = "mail-send"
version = "0.6.0"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d06f18f6ad15354b83645a05466570ced7bf770a17b138742e705d54407d83ba"
checksum = "dc851b8321041a68cc3b017135b6b8d2789a8b6e455aaebe60594bd6a39b2268"
dependencies = [
"base64 0.22.1",
"gethostname",
@@ -2660,7 +2723,7 @@ version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b"
dependencies = [
"bytes 1.11.1",
"bytes 1.12.0",
"encoding_rs",
"futures-util",
"http",
@@ -2754,6 +2817,12 @@ dependencies = [
"syn 2.0.117",
]
[[package]]
name = "ndk-context"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b"
[[package]]
name = "new_debug_unreachable"
version = "1.0.6"
@@ -3115,6 +3184,7 @@ version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078"
dependencies = [
"phf_macros",
"phf_shared 0.11.3",
]
@@ -3134,10 +3204,20 @@ version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49aa7f9d80421bca176ca8dbfebe668cc7a2684708594ec9f3c0db0805d5d6e1"
dependencies = [
"phf_generator",
"phf_generator 0.13.1",
"phf_shared 0.13.1",
]
[[package]]
name = "phf_generator"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
dependencies = [
"phf_shared 0.11.3",
"rand 0.8.6",
]
[[package]]
name = "phf_generator"
version = "0.13.1"
@@ -3148,6 +3228,19 @@ dependencies = [
"phf_shared 0.13.1",
]
[[package]]
name = "phf_macros"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216"
dependencies = [
"phf_generator 0.11.3",
"phf_shared 0.11.3",
"proc-macro2",
"quote",
"syn 2.0.117",
]
[[package]]
name = "phf_shared"
version = "0.11.3"
@@ -3259,7 +3352,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f977080932c87287147dca052951c3e2696f8759863f6b4e4c0c9ffe7a4cc8b"
dependencies = [
"async-compression",
"bytes 1.11.1",
"bytes 1.12.0",
"futures-util",
"headers",
"hex",
@@ -3316,7 +3409,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ccbcc395bf4dd03df1da32da351b6b6732e4074ce27ddec315650e52a2be44c"
dependencies = [
"base64 0.22.1",
"bytes 1.11.1",
"bytes 1.12.0",
"derive_more",
"email_address",
"futures-util",
@@ -3390,6 +3483,17 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
[[package]]
name = "prefix-trie"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cf6e3177f0684016a5c209b00882e15f8bdd3f3bb48f0491df10cd102d0c6e7"
dependencies = [
"either",
"ipnet",
"num-traits",
]
[[package]]
name = "prettyplease"
version = "0.2.37"
@@ -3456,18 +3560,9 @@ dependencies = [
[[package]]
name = "quick-xml"
version = "0.39.2"
version = "0.41.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "958f21e8e7ceb5a1aa7fa87fab28e7c75976e0bfe7e23ff069e0a260f894067d"
dependencies = [
"memchr",
]
[[package]]
name = "quick-xml"
version = "0.40.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7315c86b26aaef0321fba33c9dcc160da659c6a9d278f0f6a5656d6561c03b"
checksum = "e660451e55124f798a69a5af3f49ccfbefbd41910eefd25caf2393e1f3473ec1"
dependencies = [
"memchr",
"serde",
@@ -3489,7 +3584,7 @@ version = "0.11.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20"
dependencies = [
"bytes 1.11.1",
"bytes 1.12.0",
"cfg_aliases",
"pin-project-lite",
"quinn-proto",
@@ -3509,7 +3604,7 @@ version = "0.11.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098"
dependencies = [
"bytes 1.11.1",
"bytes 1.12.0",
"getrandom 0.3.4",
"lru-slab",
"rand 0.9.2",
@@ -3588,9 +3683,9 @@ dependencies = [
[[package]]
name = "rand"
version = "0.10.1"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207"
checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80"
dependencies = [
"chacha20",
"getrandom 0.4.2",
@@ -3747,7 +3842,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147"
dependencies = [
"base64 0.22.1",
"bytes 1.11.1",
"bytes 1.12.0",
"futures-channel",
"futures-core",
"futures-util",
@@ -3931,9 +4026,9 @@ dependencies = [
[[package]]
name = "rustls-pki-types"
version = "1.14.1"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9"
checksum = "764899a24af3980067ee14bc143654f297b22eaebfe3c7b6b211920a5a59b046"
dependencies = [
"web-time",
"zeroize",
@@ -3945,7 +4040,7 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0"
dependencies = [
"core-foundation",
"core-foundation 0.10.1",
"core-foundation-sys",
"jni",
"log",
@@ -4021,7 +4116,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d"
dependencies = [
"bitflags",
"core-foundation",
"core-foundation 0.10.1",
"core-foundation-sys",
"libc",
"security-framework-sys",
@@ -4227,6 +4322,15 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e"
[[package]]
name = "similar"
version = "3.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6505efef05804732ed8a3f2d4f279429eb485bd69d5b0cc6b19cc02005cda16"
dependencies = [
"bstr",
]
[[package]]
name = "siphasher"
version = "1.0.2"
@@ -4372,7 +4476,7 @@ version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "585635e46db231059f76c5849798146164652513eb9e8ab2685939dd90f29b69"
dependencies = [
"phf_generator",
"phf_generator 0.13.1",
"phf_shared 0.13.1",
"proc-macro2",
"quote",
@@ -4453,6 +4557,27 @@ dependencies = [
"windows",
]
[[package]]
name = "system-configuration"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b"
dependencies = [
"bitflags",
"core-foundation 0.9.4",
"system-configuration-sys",
]
[[package]]
name = "system-configuration-sys"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "tagptr"
version = "0.2.0"
@@ -4685,9 +4810,9 @@ dependencies = [
[[package]]
name = "time"
version = "0.3.51"
version = "0.3.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85c17d80feb7334b40c484e45ed1a5273dfd8bfda537c3be2e74a06a6686f327"
checksum = "18dfaaeddcb932337b5e7866ee7d0ce9b76d2fd092997146f187ec09b4558a50"
dependencies = [
"deranged",
"libc",
@@ -4707,9 +4832,9 @@ checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109"
[[package]]
name = "time-macros"
version = "0.2.30"
version = "0.2.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcef1a61bdb119096e153208ec5cbec23944ce8bca13be5c7f60c634f7403935"
checksum = "c431b87111666e491a90baa837f914fb45cd5dc3c268591b0220ff5057f2085f"
dependencies = [
"num-conv",
"time-core",
@@ -4717,9 +4842,9 @@ dependencies = [
[[package]]
name = "timeago"
version = "0.6.0"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e86660b0935ca5912eb155f5b3794e2f8f1a09d8c00c9efd5c1075ca26403638"
checksum = "46c29b13d230e9cd58513d38701a661fc06e1215398937532a2d938ecca6f219"
dependencies = [
"chrono",
"isolang",
@@ -4766,7 +4891,7 @@ version = "1.52.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe"
dependencies = [
"bytes 1.11.1",
"bytes 1.12.0",
"libc",
"mio",
"parking_lot",
@@ -4837,7 +4962,7 @@ version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098"
dependencies = [
"bytes 1.11.1",
"bytes 1.12.0",
"futures-core",
"futures-io",
"futures-sink",
@@ -4927,7 +5052,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8"
dependencies = [
"bitflags",
"bytes 1.11.1",
"bytes 1.12.0",
"futures-util",
"http",
"http-body",
@@ -5774,20 +5899,14 @@ version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
[[package]]
name = "winnow"
version = "0.6.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e90edd2ac1aa278a5c4599b1d89cf03074b610800f866d4026dc199d7929a28"
dependencies = [
"memchr",
]
[[package]]
name = "winnow"
version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945"
dependencies = [
"memchr",
]
[[package]]
name = "winnow"
+11 -11
View File
@@ -13,7 +13,7 @@ members = [
resolver = "2"
[workspace.package]
version = "1.6.1"
version = "1.6.2"
edition = "2021"
[workspace.dependencies]
@@ -51,46 +51,46 @@ tokio-rustls = { version = "0.26.4", default-features = false, features = [
"ring",
"tls12",
] }
timeago = "0.6.0"
timeago = "0.6.1"
oauth2 = { version = "5.0.0", features = ["reqwest-blocking"] }
url = { version = "2.5.8", features = ["serde"] }
sysinfo = "0.39.4"
num_cpus = "1.17.0"
rand = "0.10.1"
rand = "0.10.2"
encoding_rs = "0.8.35"
webpki-roots = "1.0.8"
rustls = { version = "0.23.41", default-features = false, features = ["ring"] }
rustls-pki-types = "1.14.1"
rustls-pki-types = "1.15.0"
tokio-io-timeout = "1.2.1"
semver = "1.0.28"
governor = "0.10.4"
lru = "0.18.0"
mime_guess = "2.0.5"
hex = "0.4.3"
time = { version = "0.3.51", features = [
time = { version = "0.3.53", features = [
"formatting",
"parsing",
"local-offset",
] }
rust-embed = "8.11.0"
rust-embed = "8.12.0"
murmur3 = "0.5.2"
urlencoding = "2.1.3"
dashmap = "6.2.1"
gethostname = "1.1.0"
itoa = "1.0.18"
html2text = "0.17.1"
bytes = "1.11.1"
bytes = "1.12.0"
dialoguer = "0.12.0"
console = "0.16.3"
mail-send = "0.6.0"
console = "0.16.4"
mail-send = "0.6.1"
rcgen = "0.14.8"
rustls-pemfile = "2.2.0"
blake3 = "1.8.5"
uuid = { version = "1.23.4", features = ["v4", "serde"] }
fjall = { version = "3.1.5", features = ["lz4", "metrics", "bytes_1"] }
fjall = { version = "3.1.6", features = ["lz4", "metrics", "bytes_1"] }
tracing-log = "0.2.0"
tokio-util = "0.7.18"
indicatif = "0.18.4"
indicatif = "0.18.6"
[profile.release]
strip = true
+3 -3
View File
@@ -69,9 +69,9 @@ tokio-util.workspace = true
whichlang = "0.1.1"
deunicode = "1.6.2"
scopeguard = "1.2.0"
cron = "0.15"
quick-xml = { version = "0.40.0", features = ["serialize"] }
hickory-resolver = "0.26.0-alpha.1"
cron = "0.17"
quick-xml = { version = "0.41.0", features = ["serialize"] }
hickory-resolver = "0.26.1"
memmap2 = "0.9.10"
outlook-pst = { git = "https://github.com/rustmailer/outlook-pst-rs.git", branch = "main" }
compressed-rtf = "1.0.1"
+143 -30
View File
@@ -16,9 +16,8 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
use hickory_resolver::name_server::TokioConnectionProvider;
use hickory_resolver::net::runtime::TokioRuntimeProvider;
use hickory_resolver::proto::rr::RData;
use hickory_resolver::proto::rr::RecordType;
use hickory_resolver::TokioResolver;
use quick_xml::de::from_str;
use reqwest::Client;
@@ -108,28 +107,29 @@ async fn fetch_xml(client: &Client, url: &str) -> Option<MailConfig> {
}
async fn lookup_srv(domain: &str) -> Option<MailConfig> {
let resolver = TokioResolver::builder(TokioConnectionProvider::default())
let resolver = TokioResolver::builder(TokioRuntimeProvider::default())
.ok()?
.build();
.build()
.ok()?;
let imap_srv = format!("_imaps._tcp.{}.", domain);
let imap_lookup = resolver.lookup(imap_srv, RecordType::SRV).await.ok()?;
let imap_record = imap_lookup.iter().next()?;
let (imap_host, imap_port) = match imap_record {
let imap_lookup = resolver.srv_lookup(imap_srv).await.ok()?;
let imap_record = imap_lookup.answers().first()?;
let (imap_host, imap_port) = match &imap_record.data {
RData::SRV(srv) => {
let host = srv.target().to_string().trim_end_matches('.').to_string();
(host, srv.port())
let host = srv.target.to_string().trim_end_matches('.').to_string();
(host, srv.port)
}
_ => return None,
};
let smtp_srv = format!("_submission._tcp.{}.", domain);
let smtp_lookup = resolver.lookup(smtp_srv, RecordType::SRV).await.ok()?;
let smtp_record = smtp_lookup.iter().next()?;
let (smtp_host, smtp_port) = match smtp_record {
let smtp_lookup = resolver.srv_lookup(smtp_srv).await.ok()?;
let smtp_record = smtp_lookup.answers().first()?;
let (smtp_host, smtp_port) = match &smtp_record.data {
RData::SRV(srv) => {
let host = srv.target().to_string().trim_end_matches('.').to_string();
(host, srv.port())
let host = srv.target.to_string().trim_end_matches('.').to_string();
(host, srv.port)
}
_ => return None,
};
@@ -177,13 +177,19 @@ pub async fn fetch(domain: &str) -> BichonResult<MailConfig> {
.map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?;
// ── ISP autoconfig (HTTPS, then HTTP) ──────────────────────────
if let Some(config) =
fetch_xml(&client, &format!("https://autoconfig.{domain}/mail/config-v1.1.xml")).await
if let Some(config) = fetch_xml(
&client,
&format!("https://autoconfig.{domain}/mail/config-v1.1.xml"),
)
.await
{
return Ok(config);
}
if let Some(config) =
fetch_xml(&client, &format!("http://autoconfig.{domain}/mail/config-v1.1.xml")).await
if let Some(config) = fetch_xml(
&client,
&format!("http://autoconfig.{domain}/mail/config-v1.1.xml"),
)
.await
{
return Ok(config);
}
@@ -212,8 +218,11 @@ pub async fn fetch(domain: &str) -> BichonResult<MailConfig> {
}
// ── Thunderbird central ISPDB ──────────────────────────────────
if let Some(config) =
fetch_xml(&client, &format!("https://autoconfig.thunderbird.net/v1.1/{domain}")).await
if let Some(config) = fetch_xml(
&client,
&format!("https://autoconfig.thunderbird.net/v1.1/{domain}"),
)
.await
{
return Ok(config);
}
@@ -245,20 +254,29 @@ async fn fetch_for_mx(client: &Client, domain: &str) -> Option<MailConfig> {
}
// Try ISPDB for the MX domain
if let Some(config) =
fetch_xml(client, &format!("https://autoconfig.thunderbird.net/v1.1/{mx_domain}")).await
if let Some(config) = fetch_xml(
client,
&format!("https://autoconfig.thunderbird.net/v1.1/{mx_domain}"),
)
.await
{
return Some(config);
}
// Try ISP autoconfig for the MX domain (HTTPS then HTTP)
if let Some(config) =
fetch_xml(client, &format!("https://autoconfig.{mx_domain}/mail/config-v1.1.xml")).await
if let Some(config) = fetch_xml(
client,
&format!("https://autoconfig.{mx_domain}/mail/config-v1.1.xml"),
)
.await
{
return Some(config);
}
if let Some(config) =
fetch_xml(client, &format!("http://autoconfig.{mx_domain}/mail/config-v1.1.xml")).await
if let Some(config) = fetch_xml(
client,
&format!("http://autoconfig.{mx_domain}/mail/config-v1.1.xml"),
)
.await
{
return Some(config);
}
@@ -268,12 +286,16 @@ async fn fetch_for_mx(client: &Client, domain: &str) -> Option<MailConfig> {
/// DNS MX lookup → extract the second-level domain of the first MX hostname.
async fn lookup_mx_domain(domain: &str) -> Option<String> {
let resolver = TokioResolver::builder(TokioConnectionProvider::default())
let resolver = TokioResolver::builder(TokioRuntimeProvider::default())
.ok()?
.build();
.build()
.ok()?;
let lookup = resolver.mx_lookup(domain).await.ok()?;
let record = lookup.iter().next()?;
let mx_host = record.to_string().trim_end_matches('.').to_string();
let record = lookup.answers().first()?;
let mx_host = match &record.data {
RData::MX(mx) => mx.exchange.to_string().trim_end_matches('.').to_string(),
_ => return None,
};
// Extract a reasonable base domain from the MX hostname.
// E.g., "aspmx.l.google.com" → "google.com"
@@ -336,4 +358,95 @@ mod tests {
}
}
}
#[test]
fn test_parse_autoconfig_xml() {
let xml = r#"<?xml version="1.0" encoding="UTF-8"?>
<clientConfig version="1.1">
<emailProvider id="example.com">
<domain>example.com</domain>
<incomingServer type="imap">
<hostname>imap.example.com</hostname>
<port>993</port>
<socketType>SSL</socketType>
<username>%EMAILADDRESS%</username>
<authentication>password-cleartext</authentication>
</incomingServer>
<outgoingServer type="smtp">
<hostname>smtp.example.com</hostname>
<port>587</port>
<socketType>STARTTLS</socketType>
<username>%EMAILADDRESS%</username>
</outgoingServer>
</emailProvider>
</clientConfig>"#;
let config = parse_autoconfig_xml(xml).expect("should parse valid XML");
assert_eq!(config.incoming.len(), 1);
assert_eq!(config.incoming[0].protocol, "imap");
assert_eq!(config.incoming[0].hostname, "imap.example.com");
assert_eq!(config.incoming[0].port, 993);
assert_eq!(config.incoming[0].socket_type, "SSL");
assert_eq!(config.incoming[0].username, "%EMAILADDRESS%");
assert_eq!(config.incoming[0].authentication, "password-cleartext");
assert_eq!(config.outgoing.len(), 1);
assert_eq!(config.outgoing[0].protocol, "smtp");
assert_eq!(config.outgoing[0].hostname, "smtp.example.com");
assert_eq!(config.outgoing[0].port, 587);
assert_eq!(config.outgoing[0].socket_type, "STARTTLS");
assert_eq!(config.outgoing[0].username, "%EMAILADDRESS%");
}
#[test]
fn test_parse_autoconfig_xml_invalid() {
assert!(parse_autoconfig_xml("not xml").is_none());
assert!(parse_autoconfig_xml("<clientConfig></clientConfig>").is_none());
}
#[test]
fn test_extract_base_domain() {
assert_eq!(
extract_base_domain("aspmx.l.google.com"),
Some("google.com".to_string())
);
assert_eq!(
extract_base_domain("company.mail.protection.outlook.com"),
Some("outlook.com".to_string())
);
assert_eq!(
extract_base_domain("mx.example.com"),
Some("example.com".to_string())
);
assert_eq!(
extract_base_domain("example.com"),
Some("example.com".to_string())
);
assert_eq!(extract_base_domain("localhost"), None);
}
#[tokio::test]
async fn test_lookup_srv_gmail() {
// Gmail should have SRV records for IMAPS and SMTP submission
let config = lookup_srv("gmail.com").await;
assert!(config.is_some(), "Gmail should have SRV records");
let config = config.unwrap();
assert_eq!(config.incoming.len(), 1);
assert_eq!(config.incoming[0].protocol, "imap");
assert_eq!(config.incoming[0].socket_type, "SSL");
assert!(!config.incoming[0].hostname.is_empty());
assert!(config.incoming[0].port > 0);
assert_eq!(config.outgoing.len(), 1);
assert_eq!(config.outgoing[0].protocol, "smtp");
assert_eq!(config.outgoing[0].socket_type, "STARTTLS");
assert!(!config.outgoing[0].hostname.is_empty());
assert!(config.outgoing[0].port > 0);
}
#[tokio::test]
async fn test_lookup_srv_nonexistent() {
// A domain without SRV records should return None
let config = lookup_srv("this-domain-definitely-does-not-exist-12345.com").await;
assert!(config.is_none());
}
}