From e11c885d3412fa418524584e9d73de62e53ec01a Mon Sep 17 00:00:00 2001 From: yupix Date: Mon, 18 May 2026 06:00:49 +0000 Subject: [PATCH 1/9] =?UTF-8?q?feat(backend):=20SMTP=E8=A8=AD=E5=AE=9A?= =?UTF-8?q?=E3=81=AE=E3=83=95=E3=82=A3=E3=83=BC=E3=83=AB=E3=83=89=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/backend/src/settings.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/backend/src/settings.rs b/apps/backend/src/settings.rs index 1cd28bb..5b43243 100644 --- a/apps/backend/src/settings.rs +++ b/apps/backend/src/settings.rs @@ -8,6 +8,11 @@ pub struct Settings { pub sentry_dsn: Option, #[serde(default = "default_allow_origin")] pub allow_origin: String, + pub smtp_server: String, + pub smtp_port: u16, + pub smtp_username: String, + pub smtp_password: String, + pub smtp_from: String, } fn default_allow_origin() -> String { From 7cd2a698909240e9cd7fb9a1be80422fca7615e7 Mon Sep 17 00:00:00 2001 From: yupix Date: Mon, 18 May 2026 06:01:36 +0000 Subject: [PATCH 2/9] =?UTF-8?q?feat(backend):=20SMTP=E9=80=81=E4=BF=A1?= =?UTF-8?q?=E7=94=A8=E3=81=ABlettre=E7=B3=BB=E3=81=AE=E3=82=AF=E3=83=AC?= =?UTF-8?q?=E3=83=BC=E3=83=88=E3=82=92=E4=BE=9D=E5=AD=98=E9=96=A2=E4=BF=82?= =?UTF-8?q?=E3=81=AB=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/backend/Cargo.lock | 535 ++++++++++++++++++++++++++++++++++------ apps/backend/Cargo.toml | 2 + 2 files changed, 468 insertions(+), 69 deletions(-) diff --git a/apps/backend/Cargo.lock b/apps/backend/Cargo.lock index 6ca10c8..f9acedc 100644 --- a/apps/backend/Cargo.lock +++ b/apps/backend/Cargo.lock @@ -8,7 +8,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a" dependencies = [ - "bitflags", + "bitflags 2.11.1", "bytes", "futures-core", "futures-sink", @@ -29,7 +29,7 @@ dependencies = [ "actix-rt", "actix-service", "actix-utils", - "bitflags", + "bitflags 2.11.1", "bytes", "bytestring", "derive_more", @@ -145,7 +145,7 @@ dependencies = [ "serde_urlencoded", "smallvec", "socket2 0.6.3", - "time", + "time 0.3.47", "tracing", "url", ] @@ -208,7 +208,7 @@ checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ "getrandom 0.2.17", "once_cell", - "version_check", + "version_check 0.9.5", ] [[package]] @@ -221,7 +221,7 @@ dependencies = [ "const-random", "getrandom 0.3.4", "once_cell", - "version_check", + "version_check 0.9.5", "zerocopy", ] @@ -366,7 +366,7 @@ dependencies = [ "arrow-schema", "arrow-select", "atoi", - "base64", + "base64 0.22.1", "chrono", "half", "lexical-core", @@ -450,6 +450,12 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "ascii_utils" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71938f30533e4d95a6d17aa530939da3842c2ab6f4f84b9dae68447e4129f74a" + [[package]] name = "async-lock" version = "3.4.2" @@ -509,6 +515,15 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +[[package]] +name = "autocfg" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" +dependencies = [ + "autocfg 1.5.0", +] + [[package]] name = "autocfg" version = "1.5.0" @@ -598,7 +613,7 @@ dependencies = [ "aes-gcm", "async-trait", "axum", - "base64", + "base64 0.22.1", "bytes", "chrono", "cookie", @@ -617,7 +632,7 @@ dependencies = [ "tower-layer", "tower-service", "tracing", - "uuid", + "uuid 1.23.1", ] [[package]] @@ -642,10 +657,12 @@ dependencies = [ "axum-valid", "axum_session", "axum_session_redispool", - "base64", + "base64 0.22.1", "config", "dotenvy", "hmac 0.13.0", + "lettre 0.11.22", + "lettre_email", "rand 0.10.1", "redis", "redis_pool", @@ -666,7 +683,7 @@ dependencies = [ "utoipa", "utoipa-axum", "utoipa-scalar", - "uuid", + "uuid 1.23.1", "validator", ] @@ -685,6 +702,25 @@ dependencies = [ "windows-link", ] +[[package]] +name = "base64" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" +dependencies = [ + "byteorder", + "safemem", +] + +[[package]] +name = "base64" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" +dependencies = [ + "byteorder", +] + [[package]] name = "base64" version = "0.22.1" @@ -703,7 +739,7 @@ version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d6867f1565b3aad85681f1015055b087fcfd840d6aeee6eee7f2da317603695" dependencies = [ - "autocfg", + "autocfg 1.5.0", "libm", "num-bigint", "num-integer", @@ -711,6 +747,12 @@ dependencies = [ "serde", ] +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "bitflags" version = "2.11.1" @@ -881,8 +923,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" dependencies = [ "iana-time-zone", + "js-sys", "num-traits", "serde", + "wasm-bindgen", "windows-link", ] @@ -896,6 +940,15 @@ dependencies = [ "inout", ] +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "cmov" version = "0.5.3" @@ -1002,12 +1055,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" dependencies = [ "aes-gcm", - "base64", + "base64 0.22.1", "percent-encoding", "rand 0.8.6", "subtle", - "time", - "version_check", + "time 0.3.47", + "version_check 0.9.5", ] [[package]] @@ -1174,7 +1227,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" dependencies = [ "serde", - "uuid", + "uuid 1.23.1", ] [[package]] @@ -1261,7 +1314,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" dependencies = [ - "bitflags", + "bitflags 2.11.1", "objc2", ] @@ -1300,6 +1353,101 @@ dependencies = [ "serde", ] +[[package]] +name = "email" +version = "0.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91549a51bb0241165f13d57fc4c72cef063b4088fb078b019ecbf464a45f22e4" +dependencies = [ + "base64 0.9.3", + "chrono", + "encoding", + "lazy_static", + "rand 0.4.6", + "time 0.1.45", + "version_check 0.1.5", +] + +[[package]] +name = "email-encoding" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9298e6504d9b9e780ed3f7dfd43a61be8cd0e09eb07f7706a945b0072b6670b6" +dependencies = [ + "base64 0.22.1", + "memchr", +] + +[[package]] +name = "email_address" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e079f19b08ca6239f47f8ba8509c11cf3ea30095831f7fed61441475edd8c449" + +[[package]] +name = "encoding" +version = "0.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec" +dependencies = [ + "encoding-index-japanese", + "encoding-index-korean", + "encoding-index-simpchinese", + "encoding-index-singlebyte", + "encoding-index-tradchinese", +] + +[[package]] +name = "encoding-index-japanese" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-korean" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dc33fb8e6bcba213fe2f14275f0963fd16f0a02c878e3095ecfdf5bee529d81" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-simpchinese" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d87a7194909b9118fc707194baa434a4e3b0fb6a5a757c73c3adb07aa25031f7" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-singlebyte" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3351d5acffb224af9ca265f435b859c7c01537c0849754d3db3fdf2bfe2ae84a" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-tradchinese" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding_index_tests" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" + [[package]] name = "encoding_rs" version = "0.8.35" @@ -1368,6 +1516,15 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "fast_chemail" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "495a39d30d624c2caabe6312bfead73e7717692b44e0b32df168c275a2e8e9e4" +dependencies = [ + "ascii_utils", +] + [[package]] name = "fastrand" version = "2.4.1" @@ -1449,6 +1606,12 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + [[package]] name = "funty" version = "2.0.0" @@ -1561,7 +1724,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", - "version_check", + "version_check 0.9.5", ] [[package]] @@ -1572,7 +1735,7 @@ checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.11.1+wasi-snapshot-preview1", ] [[package]] @@ -1884,7 +2047,7 @@ version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "futures-channel", "futures-util", @@ -2152,6 +2315,58 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" +[[package]] +name = "lettre" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86ed8677138975b573ab4949c35613931a4addeadd0a8a6aa0327e2a979660de" +dependencies = [ + "fast_chemail", + "log", +] + +[[package]] +name = "lettre" +version = "0.11.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0da65617f6cb926332d039cb578aad56178da86e128db6a1b09f4c94fa5b3349" +dependencies = [ + "async-trait", + "base64 0.22.1", + "email-encoding", + "email_address", + "fastrand", + "futures-io", + "futures-util", + "hostname", + "httpdate", + "idna", + "mime", + "nom", + "percent-encoding", + "quoted_printable", + "rustls", + "socket2 0.6.3", + "tokio", + "tokio-rustls", + "url", + "webpki-roots 1.0.7", +] + +[[package]] +name = "lettre_email" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd02480f8dcf48798e62113974d6ccca2129a51d241fa20f1ea349c8a42559d5" +dependencies = [ + "base64 0.10.1", + "email", + "lettre 0.9.6", + "mime", + "time 0.1.45", + "uuid 0.7.4", +] + [[package]] name = "lexical-core" version = "1.0.6" @@ -2227,7 +2442,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" dependencies = [ - "bitflags", + "bitflags 2.11.1", "libc", "plain", "redox_syscall 0.7.5", @@ -2324,7 +2539,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" dependencies = [ - "autocfg", + "autocfg 1.5.0", ] [[package]] @@ -2350,7 +2565,7 @@ checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" dependencies = [ "libc", "log", - "wasi", + "wasi 0.11.1+wasi-snapshot-preview1", "windows-sys 0.61.2", ] @@ -2377,7 +2592,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags", + "bitflags 2.11.1", "cfg-if", "cfg_aliases", "libc", @@ -2390,12 +2605,21 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ - "bitflags", + "bitflags 2.11.1", "cfg-if", "cfg_aliases", "libc", ] +[[package]] +name = "nom" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405" +dependencies = [ + "memchr", +] + [[package]] name = "nonempty" version = "0.7.0" @@ -2467,7 +2691,7 @@ version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" dependencies = [ - "autocfg", + "autocfg 1.5.0", "num-integer", "num-traits", ] @@ -2478,7 +2702,7 @@ version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ - "autocfg", + "autocfg 1.5.0", "libm", ] @@ -2497,7 +2721,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c" dependencies = [ - "bitflags", + "bitflags 2.11.1", "objc2", "objc2-foundation", ] @@ -2518,7 +2742,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ - "bitflags", + "bitflags 2.11.1", "dispatch2", "objc2", ] @@ -2529,7 +2753,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" dependencies = [ - "bitflags", + "bitflags 2.11.1", "dispatch2", "objc2", "objc2-core-foundation", @@ -2562,7 +2786,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d" dependencies = [ - "bitflags", + "bitflags 2.11.1", "objc2", "objc2-core-foundation", "objc2-core-graphics", @@ -2580,7 +2804,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ - "bitflags", + "bitflags 2.11.1", "block2", "libc", "objc2", @@ -2593,7 +2817,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" dependencies = [ - "bitflags", + "bitflags 2.11.1", "objc2", "objc2-core-foundation", ] @@ -2604,7 +2828,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" dependencies = [ - "bitflags", + "bitflags 2.11.1", "objc2", "objc2-core-foundation", "objc2-foundation", @@ -2616,7 +2840,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" dependencies = [ - "bitflags", + "bitflags 2.11.1", "block2", "objc2", "objc2-cloud-kit", @@ -2668,7 +2892,7 @@ version = "0.10.79" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf0b434746ee2832f4f0baf10137e1cabb18cbe6912c69e2e33263c45250f542" dependencies = [ - "bitflags", + "bitflags 2.11.1", "cfg-if", "foreign-types", "libc", @@ -3056,7 +3280,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.117", - "version_check", + "version_check 0.9.5", "yansi", ] @@ -3089,6 +3313,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "quoted_printable" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "478e0585659a122aa407eb7e3c0e1fa51b1d8a870038bd29f0cf4a8551eea972" + [[package]] name = "r-efi" version = "5.3.0" @@ -3107,6 +3337,38 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" +[[package]] +name = "rand" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" +dependencies = [ + "fuchsia-cprng", + "libc", + "rand_core 0.3.1", + "rdrand", + "winapi", +] + +[[package]] +name = "rand" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" +dependencies = [ + "autocfg 0.1.8", + "libc", + "rand_chacha 0.1.1", + "rand_core 0.4.2", + "rand_hc", + "rand_isaac", + "rand_jitter", + "rand_os", + "rand_pcg", + "rand_xorshift", + "winapi", +] + [[package]] name = "rand" version = "0.8.6" @@ -3139,6 +3401,16 @@ dependencies = [ "rand_core 0.10.1", ] +[[package]] +name = "rand_chacha" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" +dependencies = [ + "autocfg 0.1.8", + "rand_core 0.3.1", +] + [[package]] name = "rand_chacha" version = "0.3.1" @@ -3159,6 +3431,21 @@ dependencies = [ "rand_core 0.9.5", ] +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + [[package]] name = "rand_core" version = "0.6.4" @@ -3183,6 +3470,77 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" +[[package]] +name = "rand_hc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rand_isaac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rand_jitter" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" +dependencies = [ + "libc", + "rand_core 0.4.2", + "winapi", +] + +[[package]] +name = "rand_os" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" +dependencies = [ + "cloudabi", + "fuchsia-cprng", + "libc", + "rand_core 0.4.2", + "rdrand", + "winapi", +] + +[[package]] +name = "rand_pcg" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" +dependencies = [ + "autocfg 0.1.8", + "rand_core 0.4.2", +] + +[[package]] +name = "rand_xorshift" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", +] + [[package]] name = "redis" version = "1.2.1" @@ -3229,7 +3587,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags", + "bitflags 2.11.1", ] [[package]] @@ -3238,7 +3596,7 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4666a1a60d8412eab19d94f6d13dcc9cea0a5ef4fdf6a5db306537413c661b1b" dependencies = [ - "bitflags", + "bitflags 2.11.1", ] [[package]] @@ -3291,7 +3649,7 @@ version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62e0021ea2c22aed41653bc7e1419abb2c97e038ff2c33d0e1309e49a97deec0" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "futures-channel", "futures-core", @@ -3353,7 +3711,7 @@ dependencies = [ "rkyv_derive", "seahash", "tinyvec", - "uuid", + "uuid 1.23.1", ] [[package]] @@ -3373,7 +3731,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4147b952f3f819eca0e99527022f7d6a8d05f111aeb0a62960c74eb283bec8fc" dependencies = [ - "bitflags", + "bitflags 2.11.1", "once_cell", "serde", "serde_derive", @@ -3449,7 +3807,7 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags", + "bitflags 2.11.1", "errno", "libc", "linux-raw-sys", @@ -3462,6 +3820,7 @@ version = "0.23.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" dependencies = [ + "log", "once_cell", "ring", "rustls-pki-types", @@ -3502,6 +3861,12 @@ version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" +[[package]] +name = "safemem" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" + [[package]] name = "schannel" version = "0.1.29" @@ -3559,10 +3924,10 @@ dependencies = [ "sqlx", "strum", "thiserror 2.0.18", - "time", + "time 0.3.47", "tracing", "url", - "uuid", + "uuid 1.23.1", ] [[package]] @@ -3604,8 +3969,8 @@ dependencies = [ "rust_decimal", "sea-query-derive", "serde_json", - "time", - "uuid", + "time 0.3.47", + "uuid 1.23.1", ] [[package]] @@ -3669,7 +4034,7 @@ version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "bitflags", + "bitflags 2.11.1", "core-foundation", "core-foundation-sys", "libc", @@ -3806,7 +4171,7 @@ version = "0.48.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c51ec9620a4d398dcdf7ee90effbf8d8691cfa24e91978bfa8565cac039d4980" dependencies = [ - "bitflags", + "bitflags 2.11.1", "sentry-backtrace", "sentry-core", "tracing-core", @@ -3825,9 +4190,9 @@ dependencies = [ "serde", "serde_json", "thiserror 2.0.18", - "time", + "time 0.3.47", "url", - "uuid", + "uuid 1.23.1", ] [[package]] @@ -4070,7 +4435,7 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "chrono", "crc", @@ -4095,12 +4460,12 @@ dependencies = [ "sha2 0.10.9", "smallvec", "thiserror 2.0.18", - "time", + "time 0.3.47", "tokio", "tokio-stream", "tracing", "url", - "uuid", + "uuid 1.23.1", "webpki-roots 0.26.11", ] @@ -4149,8 +4514,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526" dependencies = [ "atoi", - "base64", - "bitflags", + "base64 0.22.1", + "bitflags 2.11.1", "byteorder", "bytes", "chrono", @@ -4182,9 +4547,9 @@ dependencies = [ "sqlx-core", "stringprep", "thiserror 2.0.18", - "time", + "time 0.3.47", "tracing", - "uuid", + "uuid 1.23.1", "whoami", ] @@ -4195,8 +4560,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46" dependencies = [ "atoi", - "base64", - "bitflags", + "base64 0.22.1", + "bitflags 2.11.1", "byteorder", "chrono", "crc", @@ -4223,9 +4588,9 @@ dependencies = [ "sqlx-core", "stringprep", "thiserror 2.0.18", - "time", + "time 0.3.47", "tracing", - "uuid", + "uuid 1.23.1", "whoami", ] @@ -4250,10 +4615,10 @@ dependencies = [ "serde_urlencoded", "sqlx-core", "thiserror 2.0.18", - "time", + "time 0.3.47", "tracing", "url", - "uuid", + "uuid 1.23.1", ] [[package]] @@ -4422,6 +4787,17 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "time" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" +dependencies = [ + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi", +] + [[package]] name = "time" version = "0.3.47" @@ -4624,7 +5000,7 @@ version = "0.6.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68d6fdd9f81c2819c9a8b0e0cd91660e7746a8e6ea2ba7c6b2b057985f6bcb51" dependencies = [ - "bitflags", + "bitflags 2.11.1", "bytes", "futures-util", "http 1.4.0", @@ -4804,7 +5180,7 @@ version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dea7109cdcd5864d4eeb1b58a1648dc9bf520360d7af16ec26d0a9354bafcfc0" dependencies = [ - "base64", + "base64 0.22.1", "der 0.8.0", "log", "native-tls", @@ -4821,7 +5197,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e994ba84b0bd1b1b0cf92878b7ef898a5c1760108fe7b6010327e274917a808c" dependencies = [ - "base64", + "base64 0.22.1", "http 1.4.0", "httparse", "log", @@ -4886,7 +5262,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.117", - "uuid", + "uuid 1.23.1", ] [[package]] @@ -4901,6 +5277,15 @@ dependencies = [ "utoipa", ] +[[package]] +name = "uuid" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a" +dependencies = [ + "rand 0.6.5", +] + [[package]] name = "uuid" version = "1.23.1" @@ -4955,6 +5340,12 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "version_check" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" + [[package]] name = "version_check" version = "0.9.5" @@ -4970,6 +5361,12 @@ dependencies = [ "try-lock", ] +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" @@ -5084,7 +5481,7 @@ version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ - "bitflags", + "bitflags 2.11.1", "hashbrown 0.15.5", "indexmap", "semver", @@ -5439,7 +5836,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", - "bitflags", + "bitflags 2.11.1", "indexmap", "log", "serde", diff --git a/apps/backend/Cargo.toml b/apps/backend/Cargo.toml index 3b9ed6e..daa38f2 100644 --- a/apps/backend/Cargo.toml +++ b/apps/backend/Cargo.toml @@ -44,3 +44,5 @@ rand = "0.10" subtle = "2.4" strum = { version = "0.28.0", features = ["derive"] } strum_macros = "0.28" +lettre = { version = "0.11", default-features = false, features = ["builder", "hostname", "smtp-transport","tokio1", "tokio1-rustls-tls"] } +lettre_email = "0.9" \ No newline at end of file From c82e676be0ec575a157011c325e4a0b8b1fc760d Mon Sep 17 00:00:00 2001 From: yupix Date: Mon, 18 May 2026 06:05:01 +0000 Subject: [PATCH 3/9] =?UTF-8?q?feat(backend):=20SMTP=E3=82=AF=E3=83=A9?= =?UTF-8?q?=E3=82=A4=E3=82=A2=E3=83=B3=E3=83=88=E3=81=AE=E8=BF=BD=E5=8A=A0?= =?UTF-8?q?=E3=81=A8=E8=A8=AD=E5=AE=9A=E3=83=95=E3=82=A3=E3=83=BC=E3=83=AB?= =?UTF-8?q?=E3=83=89=E3=81=AE=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/backend/src/lib.rs | 3 +- apps/backend/src/settings.rs | 2 +- apps/backend/src/utils/mod.rs | 1 + apps/backend/src/utils/smtp.rs | 92 ++++++++++++++++++++++++++++++++++ 4 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 apps/backend/src/utils/smtp.rs diff --git a/apps/backend/src/lib.rs b/apps/backend/src/lib.rs index cd858b6..52ae936 100644 --- a/apps/backend/src/lib.rs +++ b/apps/backend/src/lib.rs @@ -1,4 +1,4 @@ -use crate::{settings::Settings, utils::redis::RedisConnection}; +use crate::{settings::Settings, utils::{redis::RedisConnection, smtp::SmtpClient}}; use sea_orm::DatabaseConnection; pub mod dto; @@ -17,4 +17,5 @@ pub struct AppState { pub settings: Settings, pub db: DatabaseConnection, pub redis_client: RedisConnection, + pub smtp_client: SmtpClient } diff --git a/apps/backend/src/settings.rs b/apps/backend/src/settings.rs index 5b43243..720d1dc 100644 --- a/apps/backend/src/settings.rs +++ b/apps/backend/src/settings.rs @@ -8,7 +8,7 @@ pub struct Settings { pub sentry_dsn: Option, #[serde(default = "default_allow_origin")] pub allow_origin: String, - pub smtp_server: String, + pub smtp_host: String, pub smtp_port: u16, pub smtp_username: String, pub smtp_password: String, diff --git a/apps/backend/src/utils/mod.rs b/apps/backend/src/utils/mod.rs index ecfb340..99be336 100644 --- a/apps/backend/src/utils/mod.rs +++ b/apps/backend/src/utils/mod.rs @@ -1,2 +1,3 @@ pub mod auth; pub mod redis; +pub mod smtp; diff --git a/apps/backend/src/utils/smtp.rs b/apps/backend/src/utils/smtp.rs new file mode 100644 index 0000000..34810ce --- /dev/null +++ b/apps/backend/src/utils/smtp.rs @@ -0,0 +1,92 @@ +/// SMTPクライアントを提供するモジュール + +use lettre::message::{Mailbox, Message, MultiPart, SinglePart}; +use lettre::{AsyncSmtpTransport, AsyncTransport, transport::smtp::authentication::Credentials}; +use lettre::Tokio1Executor; + +/// SMTPクライアントの構造体 +#[derive(Clone, Debug)] +pub struct SmtpClient { + mailer: AsyncSmtpTransport, +} + +/// SmtpClientの実装 +impl SmtpClient { + /// 新しいSMTPクライアントを作成する関数 + /// + /// # Arguments + /// * `smtp_server` - SMTPサーバーのアドレス + /// * `smtp_port` - SMTPサーバーのポート番号 + /// * `username` - SMTPサーバーの認証に使用するユーザー名 + /// * `password` - SMTPサーバーの認証に使用するパスワード + /// + /// # Examples + /// + /// ``` + /// let smtp_client = SmtpClient::new("smtp.example.com", 587, "user", "pass").unwrap(); + /// ``` + pub fn new( + smtp_server: &str, + smtp_port: u16, + username: &str, + password: &str + ) -> Result { + let creds = Credentials::new(username.to_string(), password.to_string()); + + let mailer = AsyncSmtpTransport::::starttls_relay(smtp_server)? + .port(smtp_port) + .credentials(creds) + .build(); + + Ok(SmtpClient { mailer }) + } + + /// メールを送信する関数 + /// + /// # Arguments + /// * `from` - 送信元のメールアドレス + /// * `to` - 送信先のメールアドレス + /// * `subject` - メールの件名 + /// * `body_text` - メールのテキスト形式の本文 + /// * `body_html` - メールのHTML形式の本文(オプション) + /// + /// # Examples + /// + /// ``` + ///client.send_email( + /// "sender@example.com", + /// "receiver@example.com", + /// "Hello from Async Rust!", + /// "This is a test email sent asynchronously.", + /// Some("

This is a test email sent asynchronously.

"), + ///).await?; + /// ``` + /// + pub async fn send_email( + &self, + from: &str, + to: &str, + subject: &str, + body_text: &str, + body_html: Option<&str>, + ) -> Result<(), Box> { + + let builder = Message::builder() + .from(from.parse::()?) + .to(to.parse::()?) + .subject(subject); + + let email = match body_html { + Some(html) => builder.multipart( + MultiPart::alternative() + .singlepart(SinglePart::plain(body_text.to_string())) + .singlepart(SinglePart::html(html.to_string())), + )?, + None => builder.singlepart(SinglePart::plain(body_text.to_string()))?, + }; + + self.mailer.send(email).await?; + + Ok(()) + } +} \ No newline at end of file From dff13b200a126e635bb4c4ec62bb554bffa1ad4e Mon Sep 17 00:00:00 2001 From: yupix Date: Mon, 18 May 2026 06:05:21 +0000 Subject: [PATCH 4/9] =?UTF-8?q?feat(backend):=20SMTP=E3=82=AF=E3=83=A9?= =?UTF-8?q?=E3=82=A4=E3=82=A2=E3=83=B3=E3=83=88=E3=82=92AppState=E3=81=AB?= =?UTF-8?q?=E6=B8=A1=E3=81=99=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/backend/src/main.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/backend/src/main.rs b/apps/backend/src/main.rs index 8679b38..a77663a 100644 --- a/apps/backend/src/main.rs +++ b/apps/backend/src/main.rs @@ -1,4 +1,4 @@ -use backend::{AppState, server::run}; +use backend::{AppState, server::run, utils::smtp::SmtpClient}; #[tokio::main] async fn main() -> Result<(), Box> { @@ -19,12 +19,19 @@ async fn main() -> Result<(), Box> { .sync(&db) .await?; + let smtp_client = SmtpClient::new( + &settings.smtp_host, + settings.smtp_port, + &settings.smtp_username, + &settings.smtp_password, + )?; let redis_client = backend::utils::redis::RedisConnection::new(&settings.redis_url); redis_client.ping().await?; let state = AppState { settings, db, redis_client, + smtp_client, }; run(state).await?; From 394182c94ddb219c6cfea876ff921bacdc8f7e11 Mon Sep 17 00:00:00 2001 From: yupix Date: Mon, 18 May 2026 06:09:01 +0000 Subject: [PATCH 5/9] =?UTF-8?q?chore(backend):=20.env.example=E3=81=ABSMTP?= =?UTF-8?q?=E9=96=A2=E4=BF=82=E3=81=AE=E4=BE=8B=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/backend/.env.example | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/backend/.env.example b/apps/backend/.env.example index e927dd0..b2afe8a 100644 --- a/apps/backend/.env.example +++ b/apps/backend/.env.example @@ -1,3 +1,8 @@ database_url=postgresql://username:password@host:port/db_name redis_url=redis://127.0.0.1:6379 sentry_dsn= +smtp_host=smtp.example.com +smtp_port=587 +smtp_username=your_smtp_username +smtp_password=your_smtp_password +smtp_from=no-reply@example.com From e355257acc8a4de181dd4731e3fbdf5c75012d21 Mon Sep 17 00:00:00 2001 From: yupix Date: Mon, 18 May 2026 06:22:31 +0000 Subject: [PATCH 6/9] =?UTF-8?q?fix(backend):=20doctest=E3=81=8C=E8=90=BD?= =?UTF-8?q?=E3=81=A1=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/backend/src/utils/smtp.rs | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/apps/backend/src/utils/smtp.rs b/apps/backend/src/utils/smtp.rs index 34810ce..3ca8db2 100644 --- a/apps/backend/src/utils/smtp.rs +++ b/apps/backend/src/utils/smtp.rs @@ -22,7 +22,9 @@ impl SmtpClient { /// /// # Examples /// - /// ``` + /// ```no_run + /// use backend::utils::smtp::SmtpClient; + /// /// let smtp_client = SmtpClient::new("smtp.example.com", 587, "user", "pass").unwrap(); /// ``` pub fn new( @@ -52,16 +54,22 @@ impl SmtpClient { /// /// # Examples /// + /// ```no_run + /// use backend::utils::smtp::SmtpClient; + /// + /// # #[tokio::main] + /// # async fn main() -> Result<(), Box> { + /// let client = SmtpClient::new("smtp.example.com", 587, "user", "pass")?; + /// client.send_email( + /// "sender@example.com", + /// "receiver@example.com", + /// "Hello from Async Rust!", + /// "This is a test email sent asynchronously.", + /// Some("

This is a test email sent asynchronously.

"), + /// ).await?; + /// # Ok(()) + /// # } /// ``` - ///client.send_email( - /// "sender@example.com", - /// "receiver@example.com", - /// "Hello from Async Rust!", - /// "This is a test email sent asynchronously.", - /// Some("

This is a test email sent asynchronously.

"), - ///).await?; - /// ``` - /// pub async fn send_email( &self, from: &str, From 922adb1e065be0145165a40371a4498e11b04b02 Mon Sep 17 00:00:00 2001 From: yupix Date: Mon, 18 May 2026 06:25:51 +0000 Subject: [PATCH 7/9] =?UTF-8?q?feat(backend):=20SMTP=E9=80=81=E4=BF=A1?= =?UTF-8?q?=E5=87=A6=E7=90=86=E3=81=AB30=E7=A7=92=E3=81=AE=E3=82=BF?= =?UTF-8?q?=E3=82=A4=E3=83=A0=E3=82=A2=E3=82=A6=E3=83=88=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/backend/src/utils/smtp.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/backend/src/utils/smtp.rs b/apps/backend/src/utils/smtp.rs index 3ca8db2..5f9154d 100644 --- a/apps/backend/src/utils/smtp.rs +++ b/apps/backend/src/utils/smtp.rs @@ -1,8 +1,11 @@ +use std::time::Duration; + /// SMTPクライアントを提供するモジュール use lettre::message::{Mailbox, Message, MultiPart, SinglePart}; use lettre::{AsyncSmtpTransport, AsyncTransport, transport::smtp::authentication::Credentials}; use lettre::Tokio1Executor; +use tokio::time::timeout; /// SMTPクライアントの構造体 #[derive(Clone, Debug)] @@ -93,7 +96,10 @@ impl SmtpClient { None => builder.singlepart(SinglePart::plain(body_text.to_string()))?, }; - self.mailer.send(email).await?; + // 送信処理にタイムアウトを30秒に設定 + let _ = timeout(Duration::from_secs(30), self.mailer.send(email)) + .await + .map_err(|_| "SMTP send timeout")?; Ok(()) } From f3f7cc24b7ab6f5f4bd87f6f917e60cf4f723100 Mon Sep 17 00:00:00 2001 From: yupix Date: Mon, 18 May 2026 06:37:48 +0000 Subject: [PATCH 8/9] =?UTF-8?q?fix(backend):=20SMTP=E3=82=AF=E3=83=A9?= =?UTF-8?q?=E3=82=A4=E3=82=A2=E3=83=B3=E3=83=88=E3=81=AE=E5=88=9D=E6=9C=9F?= =?UTF-8?q?=E5=8C=96=E3=82=A8=E3=83=A9=E3=83=BC=E3=83=8F=E3=83=B3=E3=83=89?= =?UTF-8?q?=E3=83=AA=E3=83=B3=E3=82=B0=E3=82=92=E6=94=B9=E5=96=84=E3=81=97?= =?UTF-8?q?=E3=80=81=E4=B8=8D=E8=A6=81=E3=81=AA=E4=BE=9D=E5=AD=98=E9=96=A2?= =?UTF-8?q?=E4=BF=82=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/backend/Cargo.lock | 480 +++++---------------------------- apps/backend/Cargo.toml | 1 - apps/backend/src/lib.rs | 7 +- apps/backend/src/main.rs | 7 +- apps/backend/src/utils/auth.rs | 5 +- apps/backend/src/utils/smtp.rs | 50 ++-- 6 files changed, 114 insertions(+), 436 deletions(-) diff --git a/apps/backend/Cargo.lock b/apps/backend/Cargo.lock index f9acedc..25ff67d 100644 --- a/apps/backend/Cargo.lock +++ b/apps/backend/Cargo.lock @@ -8,7 +8,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a" dependencies = [ - "bitflags 2.11.1", + "bitflags", "bytes", "futures-core", "futures-sink", @@ -29,7 +29,7 @@ dependencies = [ "actix-rt", "actix-service", "actix-utils", - "bitflags 2.11.1", + "bitflags", "bytes", "bytestring", "derive_more", @@ -145,7 +145,7 @@ dependencies = [ "serde_urlencoded", "smallvec", "socket2 0.6.3", - "time 0.3.47", + "time", "tracing", "url", ] @@ -208,7 +208,7 @@ checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ "getrandom 0.2.17", "once_cell", - "version_check 0.9.5", + "version_check", ] [[package]] @@ -221,7 +221,7 @@ dependencies = [ "const-random", "getrandom 0.3.4", "once_cell", - "version_check 0.9.5", + "version_check", "zerocopy", ] @@ -366,7 +366,7 @@ dependencies = [ "arrow-schema", "arrow-select", "atoi", - "base64 0.22.1", + "base64", "chrono", "half", "lexical-core", @@ -450,12 +450,6 @@ dependencies = [ "regex-syntax", ] -[[package]] -name = "ascii_utils" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71938f30533e4d95a6d17aa530939da3842c2ab6f4f84b9dae68447e4129f74a" - [[package]] name = "async-lock" version = "3.4.2" @@ -515,15 +509,6 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" -[[package]] -name = "autocfg" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" -dependencies = [ - "autocfg 1.5.0", -] - [[package]] name = "autocfg" version = "1.5.0" @@ -613,7 +598,7 @@ dependencies = [ "aes-gcm", "async-trait", "axum", - "base64 0.22.1", + "base64", "bytes", "chrono", "cookie", @@ -632,7 +617,7 @@ dependencies = [ "tower-layer", "tower-service", "tracing", - "uuid 1.23.1", + "uuid", ] [[package]] @@ -657,12 +642,11 @@ dependencies = [ "axum-valid", "axum_session", "axum_session_redispool", - "base64 0.22.1", + "base64", "config", "dotenvy", "hmac 0.13.0", - "lettre 0.11.22", - "lettre_email", + "lettre", "rand 0.10.1", "redis", "redis_pool", @@ -683,7 +667,7 @@ dependencies = [ "utoipa", "utoipa-axum", "utoipa-scalar", - "uuid 1.23.1", + "uuid", "validator", ] @@ -702,25 +686,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "base64" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" -dependencies = [ - "byteorder", - "safemem", -] - -[[package]] -name = "base64" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" -dependencies = [ - "byteorder", -] - [[package]] name = "base64" version = "0.22.1" @@ -739,7 +704,7 @@ version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d6867f1565b3aad85681f1015055b087fcfd840d6aeee6eee7f2da317603695" dependencies = [ - "autocfg 1.5.0", + "autocfg", "libm", "num-bigint", "num-integer", @@ -747,12 +712,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - [[package]] name = "bitflags" version = "2.11.1" @@ -923,10 +882,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" dependencies = [ "iana-time-zone", - "js-sys", "num-traits", "serde", - "wasm-bindgen", "windows-link", ] @@ -940,15 +897,6 @@ dependencies = [ "inout", ] -[[package]] -name = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "cmov" version = "0.5.3" @@ -1055,12 +1003,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" dependencies = [ "aes-gcm", - "base64 0.22.1", + "base64", "percent-encoding", "rand 0.8.6", "subtle", - "time 0.3.47", - "version_check 0.9.5", + "time", + "version_check", ] [[package]] @@ -1227,7 +1175,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" dependencies = [ "serde", - "uuid 1.23.1", + "uuid", ] [[package]] @@ -1314,7 +1262,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" dependencies = [ - "bitflags 2.11.1", + "bitflags", "objc2", ] @@ -1353,28 +1301,13 @@ dependencies = [ "serde", ] -[[package]] -name = "email" -version = "0.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91549a51bb0241165f13d57fc4c72cef063b4088fb078b019ecbf464a45f22e4" -dependencies = [ - "base64 0.9.3", - "chrono", - "encoding", - "lazy_static", - "rand 0.4.6", - "time 0.1.45", - "version_check 0.1.5", -] - [[package]] name = "email-encoding" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9298e6504d9b9e780ed3f7dfd43a61be8cd0e09eb07f7706a945b0072b6670b6" dependencies = [ - "base64 0.22.1", + "base64", "memchr", ] @@ -1384,70 +1317,6 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e079f19b08ca6239f47f8ba8509c11cf3ea30095831f7fed61441475edd8c449" -[[package]] -name = "encoding" -version = "0.2.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec" -dependencies = [ - "encoding-index-japanese", - "encoding-index-korean", - "encoding-index-simpchinese", - "encoding-index-singlebyte", - "encoding-index-tradchinese", -] - -[[package]] -name = "encoding-index-japanese" -version = "1.20141219.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91" -dependencies = [ - "encoding_index_tests", -] - -[[package]] -name = "encoding-index-korean" -version = "1.20141219.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dc33fb8e6bcba213fe2f14275f0963fd16f0a02c878e3095ecfdf5bee529d81" -dependencies = [ - "encoding_index_tests", -] - -[[package]] -name = "encoding-index-simpchinese" -version = "1.20141219.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d87a7194909b9118fc707194baa434a4e3b0fb6a5a757c73c3adb07aa25031f7" -dependencies = [ - "encoding_index_tests", -] - -[[package]] -name = "encoding-index-singlebyte" -version = "1.20141219.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3351d5acffb224af9ca265f435b859c7c01537c0849754d3db3fdf2bfe2ae84a" -dependencies = [ - "encoding_index_tests", -] - -[[package]] -name = "encoding-index-tradchinese" -version = "1.20141219.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18" -dependencies = [ - "encoding_index_tests", -] - -[[package]] -name = "encoding_index_tests" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" - [[package]] name = "encoding_rs" version = "0.8.35" @@ -1516,15 +1385,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "fast_chemail" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "495a39d30d624c2caabe6312bfead73e7717692b44e0b32df168c275a2e8e9e4" -dependencies = [ - "ascii_utils", -] - [[package]] name = "fastrand" version = "2.4.1" @@ -1606,12 +1466,6 @@ dependencies = [ "thiserror 1.0.69", ] -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" - [[package]] name = "funty" version = "2.0.0" @@ -1724,7 +1578,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", - "version_check 0.9.5", + "version_check", ] [[package]] @@ -1735,7 +1589,7 @@ checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", "libc", - "wasi 0.11.1+wasi-snapshot-preview1", + "wasi", ] [[package]] @@ -2047,7 +1901,7 @@ version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ - "base64 0.22.1", + "base64", "bytes", "futures-channel", "futures-util", @@ -2315,16 +2169,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" -[[package]] -name = "lettre" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86ed8677138975b573ab4949c35613931a4addeadd0a8a6aa0327e2a979660de" -dependencies = [ - "fast_chemail", - "log", -] - [[package]] name = "lettre" version = "0.11.22" @@ -2332,7 +2176,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0da65617f6cb926332d039cb578aad56178da86e128db6a1b09f4c94fa5b3349" dependencies = [ "async-trait", - "base64 0.22.1", + "base64", "email-encoding", "email_address", "fastrand", @@ -2353,20 +2197,6 @@ dependencies = [ "webpki-roots 1.0.7", ] -[[package]] -name = "lettre_email" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd02480f8dcf48798e62113974d6ccca2129a51d241fa20f1ea349c8a42559d5" -dependencies = [ - "base64 0.10.1", - "email", - "lettre 0.9.6", - "mime", - "time 0.1.45", - "uuid 0.7.4", -] - [[package]] name = "lexical-core" version = "1.0.6" @@ -2442,7 +2272,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" dependencies = [ - "bitflags 2.11.1", + "bitflags", "libc", "plain", "redox_syscall 0.7.5", @@ -2539,7 +2369,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" dependencies = [ - "autocfg 1.5.0", + "autocfg", ] [[package]] @@ -2565,7 +2395,7 @@ checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" dependencies = [ "libc", "log", - "wasi 0.11.1+wasi-snapshot-preview1", + "wasi", "windows-sys 0.61.2", ] @@ -2592,7 +2422,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.11.1", + "bitflags", "cfg-if", "cfg_aliases", "libc", @@ -2605,7 +2435,7 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ - "bitflags 2.11.1", + "bitflags", "cfg-if", "cfg_aliases", "libc", @@ -2691,7 +2521,7 @@ version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" dependencies = [ - "autocfg 1.5.0", + "autocfg", "num-integer", "num-traits", ] @@ -2702,7 +2532,7 @@ version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ - "autocfg 1.5.0", + "autocfg", "libm", ] @@ -2721,7 +2551,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c" dependencies = [ - "bitflags 2.11.1", + "bitflags", "objc2", "objc2-foundation", ] @@ -2742,7 +2572,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ - "bitflags 2.11.1", + "bitflags", "dispatch2", "objc2", ] @@ -2753,7 +2583,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" dependencies = [ - "bitflags 2.11.1", + "bitflags", "dispatch2", "objc2", "objc2-core-foundation", @@ -2786,7 +2616,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d" dependencies = [ - "bitflags 2.11.1", + "bitflags", "objc2", "objc2-core-foundation", "objc2-core-graphics", @@ -2804,7 +2634,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ - "bitflags 2.11.1", + "bitflags", "block2", "libc", "objc2", @@ -2817,7 +2647,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" dependencies = [ - "bitflags 2.11.1", + "bitflags", "objc2", "objc2-core-foundation", ] @@ -2828,7 +2658,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" dependencies = [ - "bitflags 2.11.1", + "bitflags", "objc2", "objc2-core-foundation", "objc2-foundation", @@ -2840,7 +2670,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" dependencies = [ - "bitflags 2.11.1", + "bitflags", "block2", "objc2", "objc2-cloud-kit", @@ -2892,7 +2722,7 @@ version = "0.10.79" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf0b434746ee2832f4f0baf10137e1cabb18cbe6912c69e2e33263c45250f542" dependencies = [ - "bitflags 2.11.1", + "bitflags", "cfg-if", "foreign-types", "libc", @@ -3280,7 +3110,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.117", - "version_check 0.9.5", + "version_check", "yansi", ] @@ -3337,38 +3167,6 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" -[[package]] -name = "rand" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" -dependencies = [ - "fuchsia-cprng", - "libc", - "rand_core 0.3.1", - "rdrand", - "winapi", -] - -[[package]] -name = "rand" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" -dependencies = [ - "autocfg 0.1.8", - "libc", - "rand_chacha 0.1.1", - "rand_core 0.4.2", - "rand_hc", - "rand_isaac", - "rand_jitter", - "rand_os", - "rand_pcg", - "rand_xorshift", - "winapi", -] - [[package]] name = "rand" version = "0.8.6" @@ -3401,16 +3199,6 @@ dependencies = [ "rand_core 0.10.1", ] -[[package]] -name = "rand_chacha" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" -dependencies = [ - "autocfg 0.1.8", - "rand_core 0.3.1", -] - [[package]] name = "rand_chacha" version = "0.3.1" @@ -3431,21 +3219,6 @@ dependencies = [ "rand_core 0.9.5", ] -[[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -dependencies = [ - "rand_core 0.4.2", -] - -[[package]] -name = "rand_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" - [[package]] name = "rand_core" version = "0.6.4" @@ -3470,77 +3243,6 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" -[[package]] -name = "rand_hc" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_isaac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_jitter" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" -dependencies = [ - "libc", - "rand_core 0.4.2", - "winapi", -] - -[[package]] -name = "rand_os" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" -dependencies = [ - "cloudabi", - "fuchsia-cprng", - "libc", - "rand_core 0.4.2", - "rdrand", - "winapi", -] - -[[package]] -name = "rand_pcg" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" -dependencies = [ - "autocfg 0.1.8", - "rand_core 0.4.2", -] - -[[package]] -name = "rand_xorshift" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rdrand" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -dependencies = [ - "rand_core 0.3.1", -] - [[package]] name = "redis" version = "1.2.1" @@ -3587,7 +3289,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.11.1", + "bitflags", ] [[package]] @@ -3596,7 +3298,7 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4666a1a60d8412eab19d94f6d13dcc9cea0a5ef4fdf6a5db306537413c661b1b" dependencies = [ - "bitflags 2.11.1", + "bitflags", ] [[package]] @@ -3649,7 +3351,7 @@ version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62e0021ea2c22aed41653bc7e1419abb2c97e038ff2c33d0e1309e49a97deec0" dependencies = [ - "base64 0.22.1", + "base64", "bytes", "futures-channel", "futures-core", @@ -3711,7 +3413,7 @@ dependencies = [ "rkyv_derive", "seahash", "tinyvec", - "uuid 1.23.1", + "uuid", ] [[package]] @@ -3731,7 +3433,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4147b952f3f819eca0e99527022f7d6a8d05f111aeb0a62960c74eb283bec8fc" dependencies = [ - "bitflags 2.11.1", + "bitflags", "once_cell", "serde", "serde_derive", @@ -3807,7 +3509,7 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.11.1", + "bitflags", "errno", "libc", "linux-raw-sys", @@ -3861,12 +3563,6 @@ version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" -[[package]] -name = "safemem" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" - [[package]] name = "schannel" version = "0.1.29" @@ -3924,10 +3620,10 @@ dependencies = [ "sqlx", "strum", "thiserror 2.0.18", - "time 0.3.47", + "time", "tracing", "url", - "uuid 1.23.1", + "uuid", ] [[package]] @@ -3969,8 +3665,8 @@ dependencies = [ "rust_decimal", "sea-query-derive", "serde_json", - "time 0.3.47", - "uuid 1.23.1", + "time", + "uuid", ] [[package]] @@ -4034,7 +3730,7 @@ version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "bitflags 2.11.1", + "bitflags", "core-foundation", "core-foundation-sys", "libc", @@ -4171,7 +3867,7 @@ version = "0.48.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c51ec9620a4d398dcdf7ee90effbf8d8691cfa24e91978bfa8565cac039d4980" dependencies = [ - "bitflags 2.11.1", + "bitflags", "sentry-backtrace", "sentry-core", "tracing-core", @@ -4190,9 +3886,9 @@ dependencies = [ "serde", "serde_json", "thiserror 2.0.18", - "time 0.3.47", + "time", "url", - "uuid 1.23.1", + "uuid", ] [[package]] @@ -4435,7 +4131,7 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6" dependencies = [ - "base64 0.22.1", + "base64", "bytes", "chrono", "crc", @@ -4460,12 +4156,12 @@ dependencies = [ "sha2 0.10.9", "smallvec", "thiserror 2.0.18", - "time 0.3.47", + "time", "tokio", "tokio-stream", "tracing", "url", - "uuid 1.23.1", + "uuid", "webpki-roots 0.26.11", ] @@ -4514,8 +4210,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526" dependencies = [ "atoi", - "base64 0.22.1", - "bitflags 2.11.1", + "base64", + "bitflags", "byteorder", "bytes", "chrono", @@ -4547,9 +4243,9 @@ dependencies = [ "sqlx-core", "stringprep", "thiserror 2.0.18", - "time 0.3.47", + "time", "tracing", - "uuid 1.23.1", + "uuid", "whoami", ] @@ -4560,8 +4256,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46" dependencies = [ "atoi", - "base64 0.22.1", - "bitflags 2.11.1", + "base64", + "bitflags", "byteorder", "chrono", "crc", @@ -4588,9 +4284,9 @@ dependencies = [ "sqlx-core", "stringprep", "thiserror 2.0.18", - "time 0.3.47", + "time", "tracing", - "uuid 1.23.1", + "uuid", "whoami", ] @@ -4615,10 +4311,10 @@ dependencies = [ "serde_urlencoded", "sqlx-core", "thiserror 2.0.18", - "time 0.3.47", + "time", "tracing", "url", - "uuid 1.23.1", + "uuid", ] [[package]] @@ -4787,17 +4483,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "time" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi", -] - [[package]] name = "time" version = "0.3.47" @@ -5000,7 +4685,7 @@ version = "0.6.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68d6fdd9f81c2819c9a8b0e0cd91660e7746a8e6ea2ba7c6b2b057985f6bcb51" dependencies = [ - "bitflags 2.11.1", + "bitflags", "bytes", "futures-util", "http 1.4.0", @@ -5180,7 +4865,7 @@ version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dea7109cdcd5864d4eeb1b58a1648dc9bf520360d7af16ec26d0a9354bafcfc0" dependencies = [ - "base64 0.22.1", + "base64", "der 0.8.0", "log", "native-tls", @@ -5197,7 +4882,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e994ba84b0bd1b1b0cf92878b7ef898a5c1760108fe7b6010327e274917a808c" dependencies = [ - "base64 0.22.1", + "base64", "http 1.4.0", "httparse", "log", @@ -5262,7 +4947,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.117", - "uuid 1.23.1", + "uuid", ] [[package]] @@ -5277,15 +4962,6 @@ dependencies = [ "utoipa", ] -[[package]] -name = "uuid" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a" -dependencies = [ - "rand 0.6.5", -] - [[package]] name = "uuid" version = "1.23.1" @@ -5340,12 +5016,6 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" -[[package]] -name = "version_check" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" - [[package]] name = "version_check" version = "0.9.5" @@ -5361,12 +5031,6 @@ dependencies = [ "try-lock", ] -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" @@ -5481,7 +5145,7 @@ version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ - "bitflags 2.11.1", + "bitflags", "hashbrown 0.15.5", "indexmap", "semver", @@ -5836,7 +5500,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", - "bitflags 2.11.1", + "bitflags", "indexmap", "log", "serde", diff --git a/apps/backend/Cargo.toml b/apps/backend/Cargo.toml index daa38f2..5da8cf6 100644 --- a/apps/backend/Cargo.toml +++ b/apps/backend/Cargo.toml @@ -45,4 +45,3 @@ subtle = "2.4" strum = { version = "0.28.0", features = ["derive"] } strum_macros = "0.28" lettre = { version = "0.11", default-features = false, features = ["builder", "hostname", "smtp-transport","tokio1", "tokio1-rustls-tls"] } -lettre_email = "0.9" \ No newline at end of file diff --git a/apps/backend/src/lib.rs b/apps/backend/src/lib.rs index 52ae936..9daecef 100644 --- a/apps/backend/src/lib.rs +++ b/apps/backend/src/lib.rs @@ -1,4 +1,7 @@ -use crate::{settings::Settings, utils::{redis::RedisConnection, smtp::SmtpClient}}; +use crate::{ + settings::Settings, + utils::{redis::RedisConnection, smtp::SmtpClient}, +}; use sea_orm::DatabaseConnection; pub mod dto; @@ -17,5 +20,5 @@ pub struct AppState { pub settings: Settings, pub db: DatabaseConnection, pub redis_client: RedisConnection, - pub smtp_client: SmtpClient + pub smtp_client: SmtpClient, } diff --git a/apps/backend/src/main.rs b/apps/backend/src/main.rs index a77663a..b763c21 100644 --- a/apps/backend/src/main.rs +++ b/apps/backend/src/main.rs @@ -24,7 +24,12 @@ async fn main() -> Result<(), Box> { settings.smtp_port, &settings.smtp_username, &settings.smtp_password, - )?; + ) + .map_err(|err| { + std::io::Error::other(format!( + "SMTP client initialization failed. If email is required in this environment, check smtp_host/smtp_port/smtp_username/smtp_password. Underlying error: {err}" + )) + })?; let redis_client = backend::utils::redis::RedisConnection::new(&settings.redis_url); redis_client.ping().await?; let state = AppState { diff --git a/apps/backend/src/utils/auth.rs b/apps/backend/src/utils/auth.rs index f628caa..78fe0d1 100644 --- a/apps/backend/src/utils/auth.rs +++ b/apps/backend/src/utils/auth.rs @@ -1,6 +1,9 @@ use argon2::{ Argon2, - password_hash::{PasswordHash, PasswordHasher, PasswordVerifier, SaltString, rand_core::{OsRng, RngCore}}, + password_hash::{ + PasswordHash, PasswordHasher, PasswordVerifier, SaltString, + rand_core::{OsRng, RngCore}, + }, }; use axum::{ diff --git a/apps/backend/src/utils/smtp.rs b/apps/backend/src/utils/smtp.rs index 5f9154d..d2ea4b8 100644 --- a/apps/backend/src/utils/smtp.rs +++ b/apps/backend/src/utils/smtp.rs @@ -1,14 +1,16 @@ -use std::time::Duration; - -/// SMTPクライアントを提供するモジュール +//! SMTPクライアントを提供するモジュール +use lettre::Tokio1Executor; use lettre::message::{Mailbox, Message, MultiPart, SinglePart}; use lettre::{AsyncSmtpTransport, AsyncTransport, transport::smtp::authentication::Credentials}; -use lettre::Tokio1Executor; +use std::time::Duration; use tokio::time::timeout; +/// SMTP送信タイムアウト(秒) +const SMTP_SEND_TIMEOUT_SECS: u64 = 30; + /// SMTPクライアントの構造体 -#[derive(Clone, Debug)] +#[derive(Clone)] pub struct SmtpClient { mailer: AsyncSmtpTransport, } @@ -16,47 +18,47 @@ pub struct SmtpClient { /// SmtpClientの実装 impl SmtpClient { /// 新しいSMTPクライアントを作成する関数 - /// + /// /// # Arguments /// * `smtp_server` - SMTPサーバーのアドレス /// * `smtp_port` - SMTPサーバーのポート番号 /// * `username` - SMTPサーバーの認証に使用するユーザー名 /// * `password` - SMTPサーバーの認証に使用するパスワード - /// + /// /// # Examples - /// + /// /// ```no_run /// use backend::utils::smtp::SmtpClient; /// /// let smtp_client = SmtpClient::new("smtp.example.com", 587, "user", "pass").unwrap(); /// ``` pub fn new( - smtp_server: &str, - smtp_port: u16, - username: &str, - password: &str + smtp_server: &str, + smtp_port: u16, + username: &str, + password: &str, ) -> Result { let creds = Credentials::new(username.to_string(), password.to_string()); - + let mailer = AsyncSmtpTransport::::starttls_relay(smtp_server)? .port(smtp_port) .credentials(creds) .build(); - + Ok(SmtpClient { mailer }) } /// メールを送信する関数 - /// + /// /// # Arguments /// * `from` - 送信元のメールアドレス /// * `to` - 送信先のメールアドレス /// * `subject` - メールの件名 /// * `body_text` - メールのテキスト形式の本文 /// * `body_html` - メールのHTML形式の本文(オプション) - /// + /// /// # Examples - /// + /// /// ```no_run /// use backend::utils::smtp::SmtpClient; /// @@ -81,7 +83,6 @@ impl SmtpClient { body_text: &str, body_html: Option<&str>, ) -> Result<(), Box> { - let builder = Message::builder() .from(from.parse::()?) .to(to.parse::()?) @@ -97,10 +98,13 @@ impl SmtpClient { }; // 送信処理にタイムアウトを30秒に設定 - let _ = timeout(Duration::from_secs(30), self.mailer.send(email)) - .await - .map_err(|_| "SMTP send timeout")?; - + timeout( + Duration::from_secs(SMTP_SEND_TIMEOUT_SECS), + self.mailer.send(email), + ) + .await + .map_err(|_| "SMTP send timeout")??; + Ok(()) } -} \ No newline at end of file +} From 833e21fdb3a3896278614855c4bfe55fc63e6e61 Mon Sep 17 00:00:00 2001 From: yupix Date: Mon, 18 May 2026 08:24:02 +0000 Subject: [PATCH 9/9] refactor(backend): Remove Debug derive from Settings struct for cleaner code --- apps/backend/src/settings.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/backend/src/settings.rs b/apps/backend/src/settings.rs index 720d1dc..a1ec837 100644 --- a/apps/backend/src/settings.rs +++ b/apps/backend/src/settings.rs @@ -1,7 +1,7 @@ use config::{Config, Environment}; use serde::Deserialize; -#[derive(Clone, Debug, Deserialize)] +#[derive(Clone, Deserialize)] pub struct Settings { pub database_url: String, pub redis_url: String,