mirror of
https://github.com/rustmailer/rustmailer.git
synced 2026-08-24 00:00:29 +00:00
feat(outlook): implement retrieve_outlook_raw_email to fetch and save EML via Graph API
This commit is contained in:
Generated
+59
-59
@@ -324,7 +324,7 @@ dependencies = [
|
||||
"async-channel 2.3.1",
|
||||
"async-compression",
|
||||
"base64 0.22.1",
|
||||
"bytes 1.7.2",
|
||||
"bytes 1.10.1",
|
||||
"chrono",
|
||||
"futures",
|
||||
"imap-proto",
|
||||
@@ -370,12 +370,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "async-nats"
|
||||
version = "0.44.2"
|
||||
version = "0.45.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f834a80c3ab6109b9c8f5ca6661a578cf31e088e831b6ce07c6b23cca04f6742"
|
||||
checksum = "86dde77d8a733a9dbaf865a9eb65c72e09c88f3d14d3dd0d2aecf511920ee4fe"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"bytes 1.7.2",
|
||||
"bytes 1.10.1",
|
||||
"futures-util",
|
||||
"memchr",
|
||||
"nkeys",
|
||||
@@ -488,7 +488,7 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3dc5ca11ac66da7ba331bd707c8d6bca90a559c107aada6ee6abf1d4d5dbc2c"
|
||||
dependencies = [
|
||||
"bytes 1.7.2",
|
||||
"bytes 1.10.1",
|
||||
"futures",
|
||||
"regex",
|
||||
"serde",
|
||||
@@ -790,9 +790,9 @@ checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.7.2"
|
||||
version = "1.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3"
|
||||
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
@@ -1072,9 +1072,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.49"
|
||||
version = "4.5.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4512b90fa68d3a9932cea5184017c5d200f5921df706d45e853537dea51508f"
|
||||
checksum = "4c26d721170e0295f191a69bd9a1f93efcdb0aff38684b61ab5750468972e5f5"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
@@ -1082,9 +1082,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.49"
|
||||
version = "4.5.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0025e98baa12e766c67ba13ff4695a887a1eba19569aad00a472546795bd6730"
|
||||
checksum = "75835f0c7bf681bfd05abe44e965760fea999a5286c6eb2d59883634fd02011a"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
@@ -1713,7 +1713,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a11dd7f04a6a6d2aea0153c6e31f5ea7af8b2efdf52cdaeea7a9a592c7fefef9"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"bytes 1.7.2",
|
||||
"bytes 1.10.1",
|
||||
"domain-macros",
|
||||
"futures-util",
|
||||
"hashbrown 0.14.5",
|
||||
@@ -2396,7 +2396,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205"
|
||||
dependencies = [
|
||||
"atomic-waker",
|
||||
"bytes 1.7.2",
|
||||
"bytes 1.10.1",
|
||||
"fnv",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
@@ -2483,7 +2483,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "322106e6bd0cba2d5ead589ddb8150a13d7c4217cf80d7c4f682ca994ccc6aa9"
|
||||
dependencies = [
|
||||
"base64 0.21.7",
|
||||
"bytes 1.7.2",
|
||||
"bytes 1.10.1",
|
||||
"headers-core",
|
||||
"http 1.3.1",
|
||||
"httpdate",
|
||||
@@ -2544,7 +2544,7 @@ checksum = "f8a6fe56c0038198998a6f217ca4e7ef3a5e51f46163bd6dd60b5c71ca6c6502"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bitflags 2.6.0",
|
||||
"bytes 1.7.2",
|
||||
"bytes 1.10.1",
|
||||
"cfg-if",
|
||||
"data-encoding",
|
||||
"enum-as-inner 0.6.1",
|
||||
@@ -2676,7 +2676,7 @@ version = "0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1"
|
||||
dependencies = [
|
||||
"bytes 1.7.2",
|
||||
"bytes 1.10.1",
|
||||
"fnv",
|
||||
"itoa",
|
||||
]
|
||||
@@ -2687,7 +2687,7 @@ version = "1.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565"
|
||||
dependencies = [
|
||||
"bytes 1.7.2",
|
||||
"bytes 1.10.1",
|
||||
"fnv",
|
||||
"itoa",
|
||||
]
|
||||
@@ -2698,7 +2698,7 @@ version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
|
||||
dependencies = [
|
||||
"bytes 1.7.2",
|
||||
"bytes 1.10.1",
|
||||
"http 1.3.1",
|
||||
]
|
||||
|
||||
@@ -2708,7 +2708,7 @@ version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f"
|
||||
dependencies = [
|
||||
"bytes 1.7.2",
|
||||
"bytes 1.10.1",
|
||||
"futures-util",
|
||||
"http 1.3.1",
|
||||
"http-body",
|
||||
@@ -2769,7 +2769,7 @@ version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80"
|
||||
dependencies = [
|
||||
"bytes 1.7.2",
|
||||
"bytes 1.10.1",
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
"h2",
|
||||
@@ -2810,7 +2810,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"bytes 1.7.2",
|
||||
"bytes 1.10.1",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
@@ -3083,7 +3083,7 @@ version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22fa7ee6be451ea0b1912b962c91c8380835e97cf1584a77e18264e908448dcb"
|
||||
dependencies = [
|
||||
"bytes 1.7.2",
|
||||
"bytes 1.10.1",
|
||||
"log",
|
||||
"nom 7.1.3",
|
||||
"smallvec",
|
||||
@@ -3575,7 +3575,7 @@ dependencies = [
|
||||
"smtp-proto",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
"webpki-roots 1.0.3",
|
||||
"webpki-roots 1.0.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3788,7 +3788,7 @@ version = "3.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b"
|
||||
dependencies = [
|
||||
"bytes 1.7.2",
|
||||
"bytes 1.10.1",
|
||||
"encoding_rs",
|
||||
"futures-util",
|
||||
"http 1.3.1",
|
||||
@@ -4167,7 +4167,7 @@ version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "126c3ca37c9c44cec575247f43a3e4374d8927684f129d2beeb0d2cef262fe12"
|
||||
dependencies = [
|
||||
"bytes 1.7.2",
|
||||
"bytes 1.10.1",
|
||||
"serde",
|
||||
"smallvec",
|
||||
]
|
||||
@@ -4564,7 +4564,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f977080932c87287147dca052951c3e2696f8759863f6b4e4c0c9ffe7a4cc8b"
|
||||
dependencies = [
|
||||
"async-compression",
|
||||
"bytes 1.7.2",
|
||||
"bytes 1.10.1",
|
||||
"futures-util",
|
||||
"headers",
|
||||
"hex",
|
||||
@@ -4622,7 +4622,7 @@ dependencies = [
|
||||
"async-compression",
|
||||
"async-stream",
|
||||
"base64 0.22.1",
|
||||
"bytes 1.7.2",
|
||||
"bytes 1.10.1",
|
||||
"fastrand 2.1.1",
|
||||
"futures-util",
|
||||
"http 1.3.1",
|
||||
@@ -4642,7 +4642,7 @@ dependencies = [
|
||||
"tokio-rustls",
|
||||
"tokio-stream",
|
||||
"tower-service",
|
||||
"webpki-roots 1.0.3",
|
||||
"webpki-roots 1.0.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4666,7 +4666,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ccbcc395bf4dd03df1da32da351b6b6732e4074ce27ddec315650e52a2be44c"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"bytes 1.7.2",
|
||||
"bytes 1.10.1",
|
||||
"derive_more",
|
||||
"email_address",
|
||||
"futures-util",
|
||||
@@ -4805,9 +4805,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.101"
|
||||
version = "1.0.103"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
|
||||
checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@@ -4852,7 +4852,7 @@ version = "0.13.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5"
|
||||
dependencies = [
|
||||
"bytes 1.7.2",
|
||||
"bytes 1.10.1",
|
||||
"prost-derive",
|
||||
]
|
||||
|
||||
@@ -4862,7 +4862,7 @@ version = "0.13.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c1318b19085f08681016926435853bbf7858f9c082d0999b80550ff5d9abe15"
|
||||
dependencies = [
|
||||
"bytes 1.7.2",
|
||||
"bytes 1.10.1",
|
||||
"heck 0.5.0",
|
||||
"itertools 0.13.0",
|
||||
"log",
|
||||
@@ -5067,7 +5067,7 @@ version = "0.11.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c7c5fdde3cdae7203427dc4f0a68fe0ed09833edc525a03456b153b79828684"
|
||||
dependencies = [
|
||||
"bytes 1.7.2",
|
||||
"bytes 1.10.1",
|
||||
"pin-project-lite",
|
||||
"quinn-proto",
|
||||
"quinn-udp",
|
||||
@@ -5085,7 +5085,7 @@ version = "0.11.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fadfaed2cd7f389d0161bb73eeb07b7b78f8691047a6f3e73caaeae55310a4a6"
|
||||
dependencies = [
|
||||
"bytes 1.7.2",
|
||||
"bytes 1.10.1",
|
||||
"rand 0.8.5",
|
||||
"ring",
|
||||
"rustc-hash",
|
||||
@@ -5435,7 +5435,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"bytes 1.7.2",
|
||||
"bytes 1.10.1",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
@@ -5469,7 +5469,7 @@ dependencies = [
|
||||
"wasm-bindgen-futures",
|
||||
"wasm-streams",
|
||||
"web-sys",
|
||||
"webpki-roots 1.0.3",
|
||||
"webpki-roots 1.0.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5564,9 +5564,9 @@ checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97"
|
||||
|
||||
[[package]]
|
||||
name = "rust-embed"
|
||||
version = "8.8.0"
|
||||
version = "8.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb44e1917075637ee8c7bcb865cf8830e3a92b5b1189e44e3a0ab5a0d5be314b"
|
||||
checksum = "947d7f3fad52b283d261c4c99a084937e2fe492248cb9a68a8435a861b8798ca"
|
||||
dependencies = [
|
||||
"rust-embed-impl",
|
||||
"rust-embed-utils",
|
||||
@@ -5575,9 +5575,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rust-embed-impl"
|
||||
version = "8.8.0"
|
||||
version = "8.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "382499b49db77a7c19abd2a574f85ada7e9dbe125d5d1160fa5cad7c4cf71fc9"
|
||||
checksum = "5fa2c8c9e8711e10f9c4fd2d64317ef13feaab820a4c51541f1a8c8e2e851ab2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -5588,9 +5588,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rust-embed-utils"
|
||||
version = "8.8.0"
|
||||
version = "8.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21fcbee55c2458836bcdbfffb6ec9ba74bbc23ca7aa6816015a3dd2c4d8fc185"
|
||||
checksum = "60b161f275cb337fe0a44d924a5f4df0ed69c2c39519858f931ce61c779d3475"
|
||||
dependencies = [
|
||||
"sha2 0.10.9",
|
||||
"walkdir",
|
||||
@@ -5658,9 +5658,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.23.33"
|
||||
version = "0.23.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "751e04a496ca00bb97a5e043158d23d66b5aabf2e1d5aa2a0aaebb1aafe6f82c"
|
||||
checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f"
|
||||
dependencies = [
|
||||
"aws-lc-rs",
|
||||
"log",
|
||||
@@ -5709,9 +5709,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pki-types"
|
||||
version = "1.12.0"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79"
|
||||
checksum = "94182ad936a0c91c324cd46c6511b9510ed16af436d7b5bab34beab0afd55f7a"
|
||||
dependencies = [
|
||||
"zeroize",
|
||||
]
|
||||
@@ -5740,7 +5740,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustmailer"
|
||||
version = "1.5.3"
|
||||
version = "1.6.0"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"async-imap",
|
||||
@@ -5748,6 +5748,7 @@ dependencies = [
|
||||
"autoconfig",
|
||||
"base64 0.22.1",
|
||||
"bb8",
|
||||
"bytes 1.10.1",
|
||||
"cacache",
|
||||
"chrono",
|
||||
"clap",
|
||||
@@ -5816,7 +5817,7 @@ dependencies = [
|
||||
"urlencoding",
|
||||
"utf7-imap",
|
||||
"vrl",
|
||||
"webpki-roots 1.0.3",
|
||||
"webpki-roots 1.0.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6911,7 +6912,7 @@ version = "1.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408"
|
||||
dependencies = [
|
||||
"bytes 1.7.2",
|
||||
"bytes 1.10.1",
|
||||
"libc",
|
||||
"mio",
|
||||
"parking_lot 0.12.3",
|
||||
@@ -6983,7 +6984,7 @@ version = "0.7.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6b9590b93e6fcc1739458317cccd391ad3955e2bde8913edf6f95f9e65a8f034"
|
||||
dependencies = [
|
||||
"bytes 1.7.2",
|
||||
"bytes 1.10.1",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"pin-project-lite",
|
||||
@@ -6997,7 +6998,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f591660438b3038dd04d16c938271c79e7e06260ad2ea2885a4861bfb238605d"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"bytes 1.7.2",
|
||||
"bytes 1.10.1",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"http 1.3.1",
|
||||
@@ -7078,7 +7079,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"bytes 1.7.2",
|
||||
"bytes 1.10.1",
|
||||
"futures-util",
|
||||
"http 1.3.1",
|
||||
"http-body",
|
||||
@@ -7507,16 +7508,16 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "vrl"
|
||||
version = "0.27.0"
|
||||
version = "0.28.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "374906b686967832d85e5ce8f43581924e8382787e538c61c1e2158e09fc6518"
|
||||
checksum = "a00427df1a5af971424054933850c6aa6ed13c6e1c6fc35e9f373d3ab5d071f8"
|
||||
dependencies = [
|
||||
"aes 0.8.4",
|
||||
"aes-siv",
|
||||
"base16",
|
||||
"base62",
|
||||
"base64-simd",
|
||||
"bytes 1.7.2",
|
||||
"bytes 1.10.1",
|
||||
"cbc",
|
||||
"cfb-mode",
|
||||
"cfg-if",
|
||||
@@ -7526,7 +7527,6 @@ dependencies = [
|
||||
"chrono-tz",
|
||||
"ciborium",
|
||||
"cidr",
|
||||
"clap",
|
||||
"codespan-reporting",
|
||||
"community-id",
|
||||
"convert_case",
|
||||
@@ -7808,9 +7808,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "1.0.3"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32b130c0d2d49f8b6889abc456e795e82525204f27c42cf767cf0d7734e089b8"
|
||||
checksum = "b2878ef029c47c6e8cf779119f20fcf52bde7ad42a731b2a304bc221df17571e"
|
||||
dependencies = [
|
||||
"rustls-pki-types",
|
||||
]
|
||||
|
||||
+10
-9
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "rustmailer"
|
||||
version = "1.5.3"
|
||||
version = "1.6.0"
|
||||
edition = "2021"
|
||||
|
||||
[[bin]]
|
||||
@@ -20,7 +20,7 @@ codegen-units = 1
|
||||
|
||||
[dependencies]
|
||||
chrono = "0.4.42"
|
||||
clap = { version = "4.5.49", features = ["derive", "env"] }
|
||||
clap = { version = "4.5.51", features = ["derive", "env"] }
|
||||
mimalloc = "0.1.48"
|
||||
native_db = "0.8.2"
|
||||
redb = "2.6.2"
|
||||
@@ -83,7 +83,7 @@ oauth2 = { version = "5.0.0", default-features = false, features = [
|
||||
url = { version = "2.5.7", features = ["serde"] }
|
||||
sysinfo = "0.37.2"
|
||||
num_cpus = "1.17.0"
|
||||
proc-macro2 = "1.0.101"
|
||||
proc-macro2 = "1.0.103"
|
||||
cacache = { version = "13.1.0", default-features = false, features = [
|
||||
"tokio-runtime",
|
||||
"mmap",
|
||||
@@ -94,9 +94,9 @@ async-imap = { version = "0.11.1", default-features = false, features = [
|
||||
"runtime-tokio",
|
||||
"compress",
|
||||
] }
|
||||
webpki-roots = "1.0.3"
|
||||
rustls = { version = "0.23.33", default-features = false, features = ["ring"] }
|
||||
rustls-pki-types = "1.12.0"
|
||||
webpki-roots = "1.0.4"
|
||||
rustls = { version = "0.23.35", default-features = false, features = ["ring"] }
|
||||
rustls-pki-types = "1.13.0"
|
||||
tokio-io-timeout = "1.2.1"
|
||||
bb8 = "0.9.0"
|
||||
# Note: Keep prost and prost-types at the same version to avoid potential conflicts.
|
||||
@@ -105,7 +105,7 @@ prost = "0.13.5"
|
||||
prost-types = "0.13.5"
|
||||
semver = "1.0.27"
|
||||
governor = "0.10.1"
|
||||
async-nats = { version = "0.44.2" }
|
||||
async-nats = { version = "0.45.0" }
|
||||
lru = "0.16.2"
|
||||
mime_guess = "2.0.5"
|
||||
pulldown-cmark = "0.13.0"
|
||||
@@ -118,11 +118,11 @@ time = { version = "0.3.44", features = [
|
||||
"local-offset",
|
||||
] }
|
||||
time-tz = "2.0.0"
|
||||
rust-embed = "8.8.0"
|
||||
rust-embed = "8.9.0"
|
||||
murmur3 = "0.5.2"
|
||||
autoconfig = "0.4.0"
|
||||
urlencoding = "2.1.3"
|
||||
vrl = "0.27.0"
|
||||
vrl = "0.28.0"
|
||||
dashmap = "6.1.0"
|
||||
prometheus = "0.14.0"
|
||||
# Statically links OpenSSL by compiling from source, avoiding system library dependencies
|
||||
@@ -130,6 +130,7 @@ openssl-sys = { version = "0.9.110", optional = true, features = ["vendored"] }
|
||||
image = "0.25.8"
|
||||
gethostname = "1.1.0"
|
||||
glob = "0.3.3"
|
||||
bytes = "1.10.1"
|
||||
[build-dependencies]
|
||||
poem-grpc-build = "0.5.7"
|
||||
|
||||
|
||||
+1
-1
@@ -18,8 +18,8 @@ use crate::{
|
||||
messages::{FullMessage, MessageList, MessageMeta, PartBody},
|
||||
},
|
||||
},
|
||||
common::http::HttpClient,
|
||||
error::{code::ErrorCode, RustMailerResult},
|
||||
hook::http::HttpClient,
|
||||
mailbox::{create::CreateMailboxRequest, rename::MailboxUpdateRequest},
|
||||
message::append::ReplyDraft,
|
||||
oauth2::token::OAuth2AccessToken,
|
||||
|
||||
+14
-1
@@ -1,3 +1,4 @@
|
||||
use bytes::Bytes;
|
||||
use serde_json::json;
|
||||
|
||||
use crate::{
|
||||
@@ -5,8 +6,8 @@ use crate::{
|
||||
cache::vendor::outlook::model::{
|
||||
MailFolder, MailFoldersResponse, Message, MessageListResponse,
|
||||
},
|
||||
common::http::HttpClient,
|
||||
error::{code::ErrorCode, RustMailerResult},
|
||||
hook::http::HttpClient,
|
||||
message::append::ReplyDraft,
|
||||
oauth2::token::OAuth2AccessToken,
|
||||
},
|
||||
@@ -230,6 +231,18 @@ impl OutlookClient {
|
||||
Ok(message)
|
||||
}
|
||||
|
||||
pub async fn get_raw_message(
|
||||
account_id: u64,
|
||||
use_proxy: Option<u64>,
|
||||
id: &str,
|
||||
) -> RustMailerResult<Bytes> {
|
||||
let url = format!("https://graph.microsoft.com/v1.0/me/messages/{id}/$value");
|
||||
let client = HttpClient::new(use_proxy).await?;
|
||||
let access_token = Self::get_access_token(account_id).await?;
|
||||
let value = client.get_bytes(url.as_str(), &access_token).await?;
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
pub async fn get_attachment(
|
||||
account_id: u64,
|
||||
use_proxy: Option<u64>,
|
||||
|
||||
+6
-13
@@ -7,24 +7,17 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
modules::{
|
||||
account::migration::AccountModel,
|
||||
cache::vendor::outlook::{
|
||||
account::migration::AccountModel, cache::vendor::outlook::{
|
||||
model::DeltaResponse,
|
||||
sync::{client::OutlookClient, envelope::OutlookEnvelope, folders::OutlookFolder},
|
||||
},
|
||||
database::{
|
||||
}, common::http::HttpClient, database::{
|
||||
async_find_impl, batch_delete_impl, filter_by_secondary_key_impl, manager::DB_MANAGER,
|
||||
upsert_impl,
|
||||
},
|
||||
error::{code::ErrorCode, RustMailerResult},
|
||||
hook::{
|
||||
channel::{Event, EVENT_CHANNEL},
|
||||
events::{payload::EmailAddedToFolder, EventPayload, EventType, RustMailerEvent},
|
||||
http::HttpClient,
|
||||
}, error::{RustMailerResult, code::ErrorCode}, hook::{
|
||||
channel::{EVENT_CHANNEL, Event},
|
||||
events::{EventPayload, EventType, RustMailerEvent, payload::EmailAddedToFolder},
|
||||
task::EventHookTask,
|
||||
},
|
||||
message::content::FullMessageContent,
|
||||
utils::mailbox_id,
|
||||
}, message::content::FullMessageContent, utils::mailbox_id
|
||||
},
|
||||
raise_error, utc_now,
|
||||
};
|
||||
|
||||
+36
-6
@@ -2,21 +2,18 @@
|
||||
// Licensed under RustMailer License Agreement v1.0
|
||||
// Unauthorized copying, modification, or distribution is prohibited.
|
||||
|
||||
use http::header::CONTENT_TYPE;
|
||||
use http::header::{ACCEPT, CONTENT_TYPE};
|
||||
use poem_grpc::{ClientConfig, CompressionEncoding};
|
||||
use reqwest::{header::AUTHORIZATION, Client};
|
||||
use std::{future::Future, pin::Pin, time::Duration};
|
||||
use std::{fs::File, future::Future, io::Write, pin::Pin, time::Duration};
|
||||
|
||||
use crate::{
|
||||
modules::{
|
||||
cache::vendor::outlook::model::{
|
||||
MailFolder, MailFoldersResponse, Message, MessageListResponse,
|
||||
},
|
||||
cache::vendor::outlook::model::{MailFolder, MailFoldersResponse, MessageListResponse},
|
||||
common::rustls::RustMailerTls,
|
||||
context::Initialize,
|
||||
error::{code::ErrorCode, RustMailerResult},
|
||||
grpc::service::rustmailer_grpc::{GetOAuth2TokensRequest, OAuth2ServiceClient},
|
||||
hook::http::HttpClient,
|
||||
},
|
||||
raise_error, rustmailer_version,
|
||||
};
|
||||
@@ -488,3 +485,36 @@ async fn create_reply_draft() {
|
||||
eprintln!("Error: {} - {:?}", res.status(), res.text().await.unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn get_raw_message() {
|
||||
let access_token = access_token().await;
|
||||
let url = format!(
|
||||
"https://graph.microsoft.com/v1.0/me/messages/{}/$value",
|
||||
"AQMkADAwATMwMAItNzE0OC1jZTEzLTAwAi0wMAoARgAAA_KUk7xWPSBEntPHShr61lgHAOo9V4GwHndCjf0x1uoIcwUAAAIBDAAAAOo9V4GwHndCjf0x1uoIcwUAAYiJVIEAAAA="
|
||||
);
|
||||
let client = reqwest::Client::builder()
|
||||
.user_agent(rustmailer_version!())
|
||||
.timeout(Duration::from_secs(10))
|
||||
.connect_timeout(Duration::from_secs(10))
|
||||
.proxy(reqwest::Proxy::all("http://127.0.0.1:22307").unwrap())
|
||||
.redirect(reqwest::redirect::Policy::none())
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let res = client
|
||||
.get(&url)
|
||||
.header(AUTHORIZATION, format!("Bearer {}", access_token))
|
||||
.header(ACCEPT, "application/octet-stream")
|
||||
.send()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
if res.status().is_success() {
|
||||
let bytes = res.bytes().await.unwrap();
|
||||
let mut file = File::create("e:\\message.eml").unwrap();
|
||||
file.write_all(&bytes).unwrap();
|
||||
} else {
|
||||
eprintln!("Error: {} - {:?}", res.status(), res.text().await.unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
// Licensed under RustMailer License Agreement v1.0
|
||||
// Unauthorized copying, modification, or distribution is prohibited.
|
||||
|
||||
use bytes::Bytes;
|
||||
use dashmap::DashMap;
|
||||
use http::header::{AUTHORIZATION, CONTENT_LENGTH, CONTENT_TYPE};
|
||||
use http::header::{ACCEPT, AUTHORIZATION, CONTENT_LENGTH, CONTENT_TYPE};
|
||||
use http::StatusCode;
|
||||
use serde::Serialize;
|
||||
use tracing::error;
|
||||
@@ -218,6 +219,84 @@ impl HttpClient {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_bytes(
|
||||
&self,
|
||||
url: &str,
|
||||
access_token: &str,
|
||||
) -> RustMailerResult<Bytes> {
|
||||
let mut attempt = 0;
|
||||
let max_attempts = 4;
|
||||
let mut delay_ms = 500;
|
||||
|
||||
loop {
|
||||
attempt += 1;
|
||||
let res_result = self
|
||||
.client
|
||||
.get(url)
|
||||
.header(AUTHORIZATION, format!("Bearer {}", access_token))
|
||||
.header(ACCEPT, "application/octet-stream")
|
||||
.send()
|
||||
.await;
|
||||
|
||||
match res_result {
|
||||
Ok(res) => {
|
||||
if res.status().is_success() {
|
||||
let bytes = res.bytes().await.map_err(|e| {
|
||||
raise_error!(
|
||||
format!("Failed to parse response: {:#?}", e),
|
||||
ErrorCode::InternalError
|
||||
)
|
||||
})?;
|
||||
return Ok(bytes);
|
||||
} else {
|
||||
let status = res.status();
|
||||
let text = res.text().await.unwrap_or_default();
|
||||
|
||||
if attempt < max_attempts && status.is_server_error() {
|
||||
tracing::warn!(
|
||||
"API call to {} returned server error {} on attempt {}. Retrying after {}ms...",
|
||||
url, status, attempt, delay_ms
|
||||
);
|
||||
tokio::time::sleep(std::time::Duration::from_millis(delay_ms)).await;
|
||||
delay_ms *= 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
return Err(raise_error!(
|
||||
format!(
|
||||
"API call to {} failed with status {}: {}",
|
||||
url, status, text
|
||||
),
|
||||
ErrorCode::ApiCallFailed
|
||||
));
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
if attempt < max_attempts {
|
||||
tracing::warn!(
|
||||
"Request to {} failed on attempt {}: {:#?}, retrying after {}ms",
|
||||
url,
|
||||
attempt,
|
||||
e,
|
||||
delay_ms
|
||||
);
|
||||
tokio::time::sleep(std::time::Duration::from_millis(delay_ms)).await;
|
||||
delay_ms *= 2;
|
||||
continue;
|
||||
} else {
|
||||
return Err(raise_error!(
|
||||
format!(
|
||||
"Request to {} failed after {} attempts: {:#?}",
|
||||
url, attempt, e
|
||||
),
|
||||
ErrorCode::ApiCallFailed
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Wrapper around the Gmail API `POST` request.
|
||||
pub async fn post<T: Serialize>(
|
||||
&self,
|
||||
@@ -4,10 +4,7 @@
|
||||
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::{
|
||||
modules::{error::code::ErrorCode, hook::http::HttpClient},
|
||||
raise_error, rustmailer_version,
|
||||
};
|
||||
use crate::{modules::{common::http::HttpClient, error::code::ErrorCode}, raise_error, rustmailer_version};
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_connect_timeout() {
|
||||
@@ -103,7 +100,7 @@ async fn test_connect_use_proxy() {
|
||||
let client = HttpClient::create(client);
|
||||
let url = "https://discord.com/api/webhooks/1397150752484622416/9yb6QJSJkszn-uiDge3No3ri9B2-shKMKOT1ruijnPbVtd_k9HAuqspn8C2cOXIqu4l5";
|
||||
let payload = json!({
|
||||
"avatar_url": "https://github.com/rustmailer.png",
|
||||
"avatar_url": "https://github.com/rustmailer.png",
|
||||
"content": "hello world",
|
||||
"embeds": [
|
||||
{
|
||||
@@ -145,7 +142,7 @@ async fn test_connect_use_proxy() {
|
||||
let result = client
|
||||
.send_json_request(None, HttpMethod::Post, url, &payload, None)
|
||||
.await;
|
||||
|
||||
|
||||
match result {
|
||||
Err(e) => {
|
||||
let err_str = e.to_string();
|
||||
@@ -23,6 +23,7 @@ use tracing::error;
|
||||
|
||||
pub mod auth;
|
||||
pub mod error;
|
||||
pub mod http;
|
||||
pub mod log;
|
||||
pub mod lru;
|
||||
pub mod paginated;
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
pub mod channel;
|
||||
pub mod entity;
|
||||
pub mod events;
|
||||
pub mod http;
|
||||
pub mod nats;
|
||||
pub mod payload;
|
||||
pub mod task;
|
||||
|
||||
@@ -5,11 +5,12 @@
|
||||
use std::collections::HashMap;
|
||||
use std::time::Instant;
|
||||
|
||||
use crate::modules::common::http::HttpClient;
|
||||
use crate::modules::error::code::ErrorCode;
|
||||
use crate::modules::error::RustMailerError;
|
||||
use crate::modules::hook::entity::EventHooks;
|
||||
use crate::modules::hook::vrl::payload::VrlScriptTestRequest;
|
||||
use crate::modules::hook::vrl::resolve_vrl_input;
|
||||
use crate::modules::hook::{entity::EventHooks, http::HttpClient};
|
||||
use crate::modules::metrics::{
|
||||
FAILURE, RUSTMAILER_EVENT_DISPATCH_DURATION_SECONDS_BY_TYPE_STATUS_AND_DESTINATION,
|
||||
RUSTMAILER_EVENT_DISPATCH_TOTAL_BY_TYPE_STATUS_AND_DESTINATION, SUCCESS,
|
||||
|
||||
@@ -6,7 +6,10 @@ use crate::{
|
||||
base64_decode_url_safe,
|
||||
modules::{
|
||||
account::{entity::MailerType, migration::AccountModel},
|
||||
cache::{disk::DISK_CACHE, vendor::gmail::sync::client::GmailClient},
|
||||
cache::{
|
||||
disk::DISK_CACHE,
|
||||
vendor::{gmail::sync::client::GmailClient, outlook::sync::client::OutlookClient},
|
||||
},
|
||||
context::executors::RUST_MAIL_CONTEXT,
|
||||
error::{code::ErrorCode, RustMailerResult},
|
||||
},
|
||||
@@ -35,7 +38,11 @@ fn gmail_raw_email_diskcache_key(account_id: u64, mid: &str) -> String {
|
||||
format!("gmail_raw_email_{}_{}", account_id, mid)
|
||||
}
|
||||
|
||||
pub async fn retrieve_raw_email(
|
||||
fn outlook_raw_email_diskcache_key(account_id: u64, mid: &str) -> String {
|
||||
format!("outlook_raw_email_{}_{}", account_id, mid)
|
||||
}
|
||||
|
||||
pub async fn retrieve_raw_email(
|
||||
account_id: u64,
|
||||
mailbox: Option<&str>,
|
||||
id: &str,
|
||||
@@ -58,7 +65,7 @@ pub async fn retrieve_raw_email(
|
||||
retrieve_imap_raw_email(account_id, mailbox, uid).await
|
||||
}
|
||||
MailerType::GmailApi => retrieve_gmail_raw_email(&account, id).await,
|
||||
MailerType::GraphApi => todo!(),
|
||||
MailerType::GraphApi => retrieve_outlook_raw_email(&account, id).await,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,3 +155,19 @@ async fn retrieve_gmail_raw_email(
|
||||
.await?
|
||||
.ok_or_else(|| raise_error!("Unexpected cache miss".into(), ErrorCode::InternalError))
|
||||
}
|
||||
|
||||
async fn retrieve_outlook_raw_email(
|
||||
account: &AccountModel,
|
||||
mid: &str,
|
||||
) -> RustMailerResult<cacache::Reader> {
|
||||
let cache_key = outlook_raw_email_diskcache_key(account.id, mid);
|
||||
if let Some(reader) = DISK_CACHE.get_cache(&cache_key).await? {
|
||||
return Ok(reader);
|
||||
}
|
||||
let data = OutlookClient::get_raw_message(account.id, account.use_proxy, mid).await?;
|
||||
DISK_CACHE.put_cache(&cache_key, &data, false).await?;
|
||||
DISK_CACHE
|
||||
.get_cache(&cache_key)
|
||||
.await?
|
||||
.ok_or_else(|| raise_error!("Unexpected cache miss".into(), ErrorCode::InternalError))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user