mirror of
https://github.com/LemmyNet/lemmy.git
synced 2025-03-13 23:12:40 +00:00
* Use connection url for configure email (fixes #5472) * clippy
This commit is contained in:
parent
a6507c169d
commit
1e02dea397
5 changed files with 19 additions and 63 deletions
|
@ -70,16 +70,10 @@
|
|||
}
|
||||
# Email sending configuration. All options except login/password are mandatory
|
||||
email: {
|
||||
# Hostname and port of the smtp server
|
||||
smtp_server: "localhost:25"
|
||||
# Login name for smtp server
|
||||
smtp_login: "string"
|
||||
# Password to login to the smtp server
|
||||
smtp_password: "string"
|
||||
# https://docs.rs/lettre/0.11.14/lettre/transport/smtp/struct.AsyncSmtpTransport.html#method.from_url
|
||||
connection: "smtps://user:pass@hostname:port"
|
||||
# Address to send emails from, eg "noreply@your-instance.com"
|
||||
smtp_from_address: "noreply@example.com"
|
||||
# Whether or not smtp connections should use tls. Can be none, tls, or starttls
|
||||
tls_type: "none"
|
||||
}
|
||||
# Parameters for automatic configuration of new instance (only used at first start)
|
||||
setup: {
|
||||
|
|
|
@ -79,6 +79,7 @@ lettre = { version = "0.11.12", default-features = false, features = [
|
|||
"builder",
|
||||
"smtp-transport",
|
||||
"tokio1-rustls-tls",
|
||||
"pool",
|
||||
], optional = true }
|
||||
markdown-it = { version = "0.6.1", optional = true }
|
||||
ts-rs = { workspace = true, optional = true }
|
||||
|
|
|
@ -5,13 +5,13 @@ use crate::{
|
|||
use html2text;
|
||||
use lettre::{
|
||||
message::{Mailbox, MultiPart},
|
||||
transport::smtp::{authentication::Credentials, extension::ClientId},
|
||||
transport::smtp::extension::ClientId,
|
||||
Address,
|
||||
AsyncTransport,
|
||||
Message,
|
||||
};
|
||||
use rosetta_i18n::{Language, LanguageId};
|
||||
use std::str::FromStr;
|
||||
use std::{str::FromStr, sync::OnceLock};
|
||||
use translations::Lang;
|
||||
use uuid::Uuid;
|
||||
|
||||
|
@ -28,21 +28,16 @@ pub async fn send_email(
|
|||
html: &str,
|
||||
settings: &Settings,
|
||||
) -> LemmyResult<()> {
|
||||
static MAILER: OnceLock<AsyncSmtpTransport> = OnceLock::new();
|
||||
let email_config = settings.email.clone().ok_or(LemmyErrorType::NoEmailSetup)?;
|
||||
let domain = settings.hostname.clone();
|
||||
|
||||
let (smtp_server, smtp_port) = {
|
||||
let email_and_port = email_config.smtp_server.split(':').collect::<Vec<&str>>();
|
||||
let email = *email_and_port
|
||||
.first()
|
||||
.ok_or(LemmyErrorType::EmailRequired)?;
|
||||
let port = email_and_port
|
||||
.get(1)
|
||||
.ok_or(LemmyErrorType::EmailSmtpServerNeedsAPort)?
|
||||
.parse::<u16>()?;
|
||||
|
||||
(email, port)
|
||||
};
|
||||
#[expect(clippy::expect_used)]
|
||||
let mailer = MAILER.get_or_init(|| {
|
||||
AsyncSmtpTransport::from_url(&email_config.connection)
|
||||
.expect("init email transport")
|
||||
.hello_name(ClientId::Domain(settings.hostname.clone()))
|
||||
.build()
|
||||
});
|
||||
|
||||
// use usize::MAX as the line wrap length, since lettre handles the wrapping for us
|
||||
let plain_text = html2text::from_read(html.as_bytes(), usize::MAX)?;
|
||||
|
@ -70,24 +65,6 @@ pub async fn send_email(
|
|||
))
|
||||
.with_lemmy_type(LemmyErrorType::EmailSendFailed)?;
|
||||
|
||||
// don't worry about 'dangeous'. it's just that leaving it at the default configuration
|
||||
// is bad.
|
||||
|
||||
// Set the TLS
|
||||
let mut builder = match email_config.tls_type.as_str() {
|
||||
"starttls" => AsyncSmtpTransport::starttls_relay(smtp_server)?.port(smtp_port),
|
||||
"tls" => AsyncSmtpTransport::relay(smtp_server)?.port(smtp_port),
|
||||
_ => AsyncSmtpTransport::builder_dangerous(smtp_server).port(smtp_port),
|
||||
};
|
||||
|
||||
// Set the creds if they exist
|
||||
let smtp_password = email_config.smtp_password();
|
||||
if let (Some(username), Some(password)) = (email_config.smtp_login, smtp_password) {
|
||||
builder = builder.credentials(Credentials::new(username, password));
|
||||
}
|
||||
|
||||
let mailer = builder.hello_name(ClientId::Domain(domain)).build();
|
||||
|
||||
mailer
|
||||
.send(email)
|
||||
.await
|
||||
|
|
|
@ -74,7 +74,6 @@ pub enum LemmyErrorType {
|
|||
ObjectNotLocal,
|
||||
NoEmailSetup,
|
||||
LocalSiteNotSetup,
|
||||
EmailSmtpServerNeedsAPort,
|
||||
InvalidEmailAddress(String),
|
||||
RateLimitError,
|
||||
InvalidName,
|
||||
|
|
|
@ -156,28 +156,13 @@ pub struct DatabaseConfig {
|
|||
#[derive(Debug, Deserialize, Serialize, Clone, Document, SmartDefault)]
|
||||
#[serde(default, deny_unknown_fields)]
|
||||
pub struct EmailConfig {
|
||||
/// Hostname and port of the smtp server
|
||||
#[doku(example = "localhost:25")]
|
||||
pub smtp_server: String,
|
||||
/// Login name for smtp server
|
||||
pub smtp_login: Option<String>,
|
||||
/// Password to login to the smtp server
|
||||
smtp_password: Option<String>,
|
||||
#[doku(example = "noreply@example.com")]
|
||||
/// https://docs.rs/lettre/0.11.14/lettre/transport/smtp/struct.AsyncSmtpTransport.html#method.from_url
|
||||
#[default("smtp://localhost:25")]
|
||||
#[doku(example = "smtps://user:pass@hostname:port")]
|
||||
pub(crate) connection: String,
|
||||
/// Address to send emails from, eg "noreply@your-instance.com"
|
||||
pub smtp_from_address: String,
|
||||
/// Whether or not smtp connections should use tls. Can be none, tls, or starttls
|
||||
#[default("none")]
|
||||
#[doku(example = "none")]
|
||||
pub tls_type: String,
|
||||
}
|
||||
|
||||
impl EmailConfig {
|
||||
pub fn smtp_password(&self) -> Option<String> {
|
||||
std::env::var("LEMMY_SMTP_PASSWORD")
|
||||
.ok()
|
||||
.or(self.smtp_password.clone())
|
||||
}
|
||||
#[doku(example = "noreply@example.com")]
|
||||
pub(crate) smtp_from_address: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, Default, Document)]
|
||||
|
|
Loading…
Reference in a new issue