📧 fix: mail module cleanup - remove dead code, simplify error handling

swadhinbiswas committed 3 months ago
e4f7f83
1 parent 7c023f8
commit e4f7f83
5 files changed
+31 -37
▼crates/justapi-core/src/mail/otp.rs
+1-6
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
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
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
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
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
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
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
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
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
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