15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
-
-
-
-
-
+
+
+
+
+
|
collections::{
HashMap,
HashSet,
},
io::Error,
};
use anyhow::{
bail,
Context,
Result,
};
use async_std::{
sync::Arc,
task,
};
use mailin_embedded::{
Response,
response::{
INTERNAL_ERROR,
INVALID_CREDENTIALS,
NO_MAILBOX,
OK
},
};
use regex::{
Regex,
escape,
};
use stacked_errors::{
Result,
StackableErr,
bail,
};
use tgbot::types::ChatPeerId;
/// `SomeHeaders` object to store data through SMTP session
#[derive(Clone, Debug)]
struct SomeHeaders {
from: String,
|
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
-
+
-
+
|
.context("[smtp2tg.toml] missing \"default\" recipient.\n")?;
let tg = Arc::new(TelegramTransport::new(api_key, recipients, default)?);
let fields = HashSet::<String>::from_iter(settings.get_array("fields")
.expect("[smtp2tg.toml] \"fields\" should be an array")
.iter().map(|x| x.clone().into_string().expect("should be strings")));
let mut domains: HashSet<String> = HashSet::new();
let extra_domains = settings.get_array("domains").unwrap();
let extra_domains = settings.get_array("domains").stack()?;
for domain in extra_domains {
let domain = domain.to_string().to_lowercase();
if RE_DOMAIN.is_match(&domain) {
domains.insert(domain);
} else {
panic!("[smtp2tg.toml] can't check of domains in \"domains\": {domain}");
}
}
let domains = domains.into_iter().map(|s| escape(&s))
.collect::<Vec<String>>().join("|");
let address = Regex::new(&format!("^(?P<user>[a-z0-9][-a-z0-9])(@({domains}))$")).unwrap();
let address = Regex::new(&format!("^(?P<user>[a-z0-9][-a-z0-9])(@({domains}))$")).stack()?;
let relay = match settings.get_string("unknown")
.context("[smtp2tg.toml] can't get \"unknown\" policy.\n")?.as_str()
{
"relay" => true,
"deny" => false,
_ => {
bail!("[smtp2tg.toml] \"unknown\" should be either \"relay\" or \"deny\".\n");
|
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
|
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
|
-
+
|
let mut text_num = 0;
let mut file_num = 0;
// let's display first html or text part as body
let mut body: Cow<'_, str> = "".into();
/*
* actually I don't wanna parse that html stuff
if html_parts > 0 {
let text = mail.body_html(0).unwrap();
let text = mail.body_html(0).stack()?;
if text.len() < 4096 - header_size {
body = text;
html_num = 1;
}
};
*/
if body.is_empty() && text_parts > 0 {
|
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
|
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
|
-
+
-
+
-
+
|
reply.push("```".into());
// and let's collect all other attachment parts
let mut files_to_send = vec![];
/*
* let's just skip html parts for now, they just duplicate text?
while html_num < html_parts {
files_to_send.push(mail.html_part(html_num).unwrap());
files_to_send.push(mail.html_part(html_num).stack()?);
html_num += 1;
}
*/
while text_num < text_parts {
files_to_send.push(mail.text_part(text_num.try_into()?)
files_to_send.push(mail.text_part(text_num.try_into().stack()?)
.context("Failed to get text part from message.")?);
text_num += 1;
}
while file_num < attachments {
files_to_send.push(mail.attachment(file_num.try_into()?)
files_to_send.push(mail.attachment(file_num.try_into().stack()?)
.context("Failed to get file part from message.")?);
file_num += 1;
}
let msg = reply.join("\n");
for chat in rcpt {
if !files_to_send.is_empty() {
|
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
|
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
|
-
+
|
from: from.to_string(),
to: to.to_vec(),
});
OK
}
/// Save chunk(?) of data
fn data (&mut self, buf: &[u8]) -> Result<(), Error> {
fn data (&mut self, buf: &[u8]) -> std::result::Result<(), Error> {
self.data.append(buf.to_vec().as_mut());
Ok(())
}
/// Attempt to send email, return temporary error if that fails
fn data_end (&mut self) -> Response {
let mut result = OK;
|