Diff
Logged in as anonymous

Differences From Artifact [f88bbb65a7]:

To Artifact [88ec92aaa8]:


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;