Diff
Logged in as anonymous

Differences From Artifact [478a14c8ba]:

To Artifact [75ec305fe3]:


66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
66
67
68
69
70
71
72

73
74
75
76
77
78
79







-







	/// validates all required configuration values.
	///
	/// # Arguments
	/// * `settings` - Parsed application configuration.
	///
	/// # Errors
	/// Returns an error if required configuration values are missing or invalid.
	/// server fails to start.
	pub fn new (settings: config::Config) -> Result<MailServer> {
		let api_key = settings.get_string("api_key")
			.context("[smtp2tg.toml] missing \"api_key\" parameter.\n")?;
		let mut recipients = HashMap::new();
		for (name, value) in settings.get_table("recipients")
			.context("[smtp2tg.toml] missing table \"recipients\".\n")?
		{
91
92
93
94
95
96
97


98
99


100
101
102
103
104

105
106

107
108
109
110
111
112
113
90
91
92
93
94
95
96
97
98


99
100

101
102
103

104
105

106
107
108
109
110
111
112
113







+
+
-
-
+
+
-



-
+

-
+







		let mut domains: HashSet<String> = HashSet::new();
		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 {
				bail!("Invalid domain in configuration: '{domain}'\n\
					Domains must be valid (e.g., 'example.com', 'localhost').\n\
				bail!("[smtp2tg.toml] can't check domains in \"domains\": {domain}");
			}
					Check 'domains' array in smtp2tg.toml.");
		}	}
		}
		if domains.is_empty() {
			bail!("No domains, need at least one: default `localhost` would do.");
		}
		let domains = domains.into_iter().map(|s| escape(&s))
		let re_domains = domains.iter().map(|s| escape(s))
			.collect::<Vec<String>>().join("|");
		let address = RegexBuilder::new(&format!("^[a-z0-9][a-z0-9.-]*(@({domains}))?$"))
		let address = RegexBuilder::new(&format!("^[a-z0-9][a-z0-9.-]*(@({re_domains}))?$"))
			.case_insensitive(true).build().stack()?;

		Ok(MailServer {
			data: vec!(),
			headers: None,
			tg,
			fields,
124
125
126
127
128
129
130
131
132


133
134
135
136
137
138
139
140
124
125
126
127
128
129
130


131
132

133
134
135
136
137
138
139







-
-
+
+
-







	/// # Returns
	/// * `Result<ChatPeerId>` - Telegram chat ID for the address, or default if
	///   not found.
	pub fn get_id (&self, name: &str) -> Result<&ChatPeerId> {
		if self.address.is_match(name) {
			Ok(self.tg.get(name).unwrap_or(&self.tg.default))
		} else {
			bail!("Doesn't look like address from one of our domains.");
		}
			bail!("Email address {name:?} is not from an allowed domain.");
	}	}
	}

	/// Attempt to deliver one message
	async fn relay_mail (&self) -> Result<()> {
		if let Some(headers) = &self.headers {
			let mail = mail_parser::MessageParser::new().parse(&self.data)
				.context("Failed to parse mail.")?;