📧 fix: mail module cleanup - remove dead code, simplify error handling
swadhinbiswas committed 3 months ago
58c2a3e
1 parent f50dab0
commit 58c2a3e
5 files changed
+31 -37
Showing 5 changed files+31-37
▼crates/justapi-core/src/mail/otp.rs
+1-6
| @@ -4,12 +4,7 @@ use super::verify::{VerificationEntry, VerificationStore}; | ||
4 | 4 | |
5 | 5 | impl VerificationStore { |
6 | 6 | /// Generate a numeric OTP (6 digits) and store it. |
7 | - pub async fn create_otp( | |
8 | - &self, | |
9 | - email: &str, | |
10 | - purpose: &str, | |
11 | - _ttl_secs: u64, | |
12 | - ) -> String { | |
7 | + pub async fn create_otp(&self, email: &str, purpose: &str, _ttl_secs: u64) -> String { | |
13 | 8 | use rand::Rng; |
14 | 9 | let otp: String = format!("{:06}", rand::thread_rng().gen_range(0..1_000_000)); |
15 | 10 | let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(); |
16 | 11 | |
▼crates/justapi-core/src/mail/queue.rs
+2-4
| @@ -1,6 +1,6 @@ | ||
1 | 1 | use tokio::sync::mpsc; |
2 | 2 | |
3 | -use super::{EmailMessage, smtp::SmtpSender}; | |
3 | +use super::{smtp::SmtpSender, EmailMessage}; | |
4 | 4 | |
5 | 5 | /// Background email delivery via a tokio mpsc channel. |
6 | 6 | pub struct EmailQueue { |
| @@ -30,9 +30,7 @@ impl EmailQueue { | ||
30 | 30 | |
31 | 31 | /// Enqueue an email for background delivery. |
32 | 32 | pub fn enqueue(&self, msg: EmailMessage) -> Result<(), anyhow::Error> { |
33 | - self.sender | |
34 | - .send(QueuedEmail { msg }) | |
35 | - .map_err(|_| anyhow::anyhow!("email queue is closed")) | |
33 | + self.sender.send(QueuedEmail { msg }).map_err(|_| anyhow::anyhow!("email queue is closed")) | |
36 | 34 | } |
37 | 35 | |
38 | 36 | /// Enqueue and return immediately. Errors are logged by the worker. |
39 | 37 | |
▼crates/justapi-core/src/mail/smtp.rs
+3-9
| @@ -93,12 +93,8 @@ impl SmtpSender { | ||
93 | 93 | |
94 | 94 | if has_both { |
95 | 95 | let alt = MultiPart::alternative() |
96 | - .singlepart(SinglePart::plain( | |
97 | - msg.text_body.as_ref().unwrap().clone(), | |
98 | - )) | |
99 | - .singlepart(SinglePart::html( | |
100 | - msg.html_body.as_ref().unwrap().clone(), | |
101 | - )); | |
96 | + .singlepart(SinglePart::plain(msg.text_body.as_ref().unwrap().clone())) | |
97 | + .singlepart(SinglePart::html(msg.html_body.as_ref().unwrap().clone())); | |
102 | 98 | multipart = multipart.multipart(alt); |
103 | 99 | } else if let Some(text) = &msg.text_body { |
104 | 100 | multipart = multipart.singlepart(SinglePart::plain(text.clone())); |
| @@ -111,9 +107,7 @@ impl SmtpSender { | ||
111 | 107 | .content_type |
112 | 108 | .parse() |
113 | 109 | .unwrap_or_else(|_| ContentType::parse("application/octet-stream").unwrap()); |
114 | - let part = SinglePart::builder() | |
115 | - .header(ct) | |
116 | - .body(att.data.clone()); | |
110 | + let part = SinglePart::builder().header(ct).body(att.data.clone()); | |
117 | 111 | multipart = multipart.singlepart(part); |
118 | 112 | } |
119 | 113 | |
120 | 114 | |
▼crates/justapi-core/src/mail/verify.rs
+2-12
| @@ -24,12 +24,7 @@ impl VerificationStore { | ||
24 | 24 | } |
25 | 25 | |
26 | 26 | /// Generate a new verification token and store it. |
27 | - pub async fn create_token( | |
28 | - &self, | |
29 | - email: &str, | |
30 | - purpose: &str, | |
31 | - _ttl_secs: u64, | |
32 | - ) -> String { | |
27 | + pub async fn create_token(&self, email: &str, purpose: &str, _ttl_secs: u64) -> String { | |
33 | 28 | use rand::Rng; |
34 | 29 | let token: String = rand::thread_rng() |
35 | 30 | .sample_iter(&rand::distributions::Alphanumeric) |
| @@ -55,12 +50,7 @@ impl VerificationStore { | ||
55 | 50 | |
56 | 51 | /// Verify a token: returns the email if valid, None otherwise. |
57 | 52 | /// Consumes the token (one-time use). |
58 | - pub async fn verify( | |
59 | - &self, | |
60 | - token: &str, | |
61 | - purpose: &str, | |
62 | - max_age_secs: u64, | |
63 | - ) -> Option<String> { | |
53 | + pub async fn verify(&self, token: &str, purpose: &str, max_age_secs: u64) -> Option<String> { | |
64 | 54 | let mut store = self.tokens.write().await; |
65 | 55 | let mut entry = match store.get(token) { |
66 | 56 | Some(e) => e.clone(), |
67 | 57 | |
▼crates/justapi-py/src/mail.rs
+23-6
| @@ -2,8 +2,8 @@ use pyo3::exceptions::PyValueError; | ||
2 | 2 | use pyo3::prelude::*; |
3 | 3 | use pyo3::types::PyDict; |
4 | 4 | |
5 | -use justapi_core::mail::SmtpConfig; | |
6 | 5 | use justapi_core::mail::smtp::SmtpSender as CoreSmtpSender; |
6 | +use justapi_core::mail::SmtpConfig; | |
7 | 7 | |
8 | 8 | use crate::message_builder; |
9 | 9 | |
| @@ -63,13 +63,23 @@ impl PyMailer { | ||
63 | 63 | py: Python<'_>, |
64 | 64 | ) -> PyResult<()> { |
65 | 65 | let msg = message_builder::build_message( |
66 | - to, subject, body, html, cc, bcc, reply_to, attachments, py, | |
66 | + to, | |
67 | + subject, | |
68 | + body, | |
69 | + html, | |
70 | + cc, | |
71 | + bcc, | |
72 | + reply_to, | |
73 | + attachments, | |
74 | + py, | |
67 | 75 | )?; |
68 | 76 | let sender = self.sender.clone(); |
69 | 77 | let rt = tokio::runtime::Runtime::new() |
70 | 78 | .map_err(|e| PyValueError::new_err(format!("Failed to create runtime: {e}")))?; |
71 | 79 | rt.block_on(async { |
72 | - sender.send(&msg).await | |
80 | + sender | |
81 | + .send(&msg) | |
82 | + .await | |
73 | 83 | .map_err(|e| PyValueError::new_err(format!("Failed to send email: {e}"))) |
74 | 84 | }) |
75 | 85 | } |
| @@ -89,12 +99,19 @@ impl PyMailer { | ||
89 | 99 | py: Python<'py>, |
90 | 100 | ) -> PyResult<Bound<'py, PyAny>> { |
91 | 101 | let msg = message_builder::build_message( |
92 | - to, subject, body, html, cc, bcc, reply_to, attachments, py, | |
102 | + to, | |
103 | + subject, | |
104 | + body, | |
105 | + html, | |
106 | + cc, | |
107 | + bcc, | |
108 | + reply_to, | |
109 | + attachments, | |
110 | + py, | |
93 | 111 | )?; |
94 | 112 | let sender = self.sender.clone(); |
95 | 113 | let fut = async move { |
96 | - sender.send(&msg).await | |
97 | - .map_err(|e| anyhow::anyhow!("Failed to send email: {e}")) | |
114 | + sender.send(&msg).await.map_err(|e| anyhow::anyhow!("Failed to send email: {e}")) | |
98 | 115 | }; |
99 | 116 | pyo3_async_runtimes::tokio::future_into_py(py, async move { |
100 | 117 | fut.await.map_err(|e| PyValueError::new_err(e.to_string())) |
101 | 118 | |