diff --git a/ci/prepare_build_environment.ps1 b/ci/prepare_build_environment.ps1 index 7235782df0a4..3c7fc7781fb4 100644 --- a/ci/prepare_build_environment.ps1 +++ b/ci/prepare_build_environment.ps1 @@ -1 +1 @@ -choco install --yes protoc +choco install --yes protoc \ No newline at end of file diff --git a/ci/prepare_build_environment.sh b/ci/prepare_build_environment.sh index cdcf2f637eeb..34d5fab7b74f 100755 --- a/ci/prepare_build_environment.sh +++ b/ci/prepare_build_environment.sh @@ -24,3 +24,11 @@ if [[ "$OSTYPE" == "linux"* ]]; then install_protobuf_centos fi fi + + +install_mailtutan() { + # For local smtp test. + cargo install mailtutan +} + +install_mailtutan \ No newline at end of file diff --git a/ee/tabby-webserver/Cargo.toml b/ee/tabby-webserver/Cargo.toml index 9219c4ca95d8..0bbc4aef0c16 100644 --- a/ee/tabby-webserver/Cargo.toml +++ b/ee/tabby-webserver/Cargo.toml @@ -49,4 +49,4 @@ validator = { version = "0.16.1", features = ["derive"] } [dev-dependencies] assert_matches = "1.5.0" tokio = { workspace = true, features = ["macros"] } -tabby-db = { path = "../../ee/tabby-db", features = ["testutils"] } +tabby-db = { path = "../../ee/tabby-db", features = ["testutils"] } \ No newline at end of file diff --git a/ee/tabby-webserver/src/service/email.rs b/ee/tabby-webserver/src/service/email.rs index 87343295a683..2b4b23905b0c 100644 --- a/ee/tabby-webserver/src/service/email.rs +++ b/ee/tabby-webserver/src/service/email.rs @@ -77,12 +77,15 @@ impl EmailServiceImpl { auth_method: AuthMethod, ) -> Result<()> { let mut smtp_server = self.smtp_server.write().await; - *smtp_server = Some( - make_smtp_builder(host, port as u16, encryption)? + + let mut builder = make_smtp_builder(host, port as u16, encryption)?; + let mechanism = auth_mechanism(auth_method); + if !mechanism.is_empty() { + builder = builder .credentials(Credentials::new(username, password)) - .authentication(auth_mechanism(auth_method)) - .build(), - ); + .authentication(mechanism); + } + *smtp_server = Some(builder.build()); *self.from.write().await = from_address.into(); Ok(()) } @@ -109,22 +112,16 @@ impl EmailServiceImpl { .body(message) .map_err(anyhow::Error::msg)?; - let handle = tokio::task::spawn(async move { - let Some(smtp_server) = &*(smtp_server.read().await) else { - // Not enabled. - return; - }; - println!("send done {:?}", smtp_server); - println!("send done {:?}", &msg); + if let Some(smtp_server) = &*(smtp_server.read().await) { + // Not enabled. match smtp_server.send(msg).await.map_err(anyhow::Error::msg) { Ok(_) => {} Err(err) => { warn!("Failed to send mail due to {}", err); } }; - }); - - Ok(handle) + } + Ok(tokio::spawn(async move {})) } } @@ -230,9 +227,10 @@ fn to_address(email: String) -> Result
{ #[cfg(test)] mod tests { - use tokio::process::{Child, Command}; + use std::time::Duration; - use crate::schema::email; + use serde::Deserialize; + use tokio::process::{Child, Command}; use super::*; @@ -247,7 +245,7 @@ mod tests { smtp_server: "smtp://example.com".into(), smtp_port: 578, encryption: Encryption::SslTls, - auth_method: AuthMethod::Plain, + auth_method: AuthMethod::None, smtp_password: Some("123456".to_owned()), }; service.update_email_setting(update_input).await.unwrap(); @@ -259,27 +257,38 @@ mod tests { fn default_email_setting() -> EmailSetting { EmailSetting { - smtp_username: "fake_smtp".into(), + smtp_username: "tabby".into(), smtp_server: "127.0.0.1".into(), smtp_port: 1025, - from_address: "fake_smtp@localhost".into(), + from_address: "tabby@localhost".into(), encryption: Encryption::None, auth_method: AuthMethod::None, } } - struct ChildGuard(Child); - impl Drop for ChildGuard { - fn drop(&mut self) { - let _ = self.0.start_kill(); - } + async fn start_smtp_server() -> Child { + let mut cmd = Command::new("mailtutan"); + cmd.kill_on_drop(true); + + let child = cmd + .spawn() + .expect("You need to run `cargo install mailtutan` before running this test"); + tokio::time::sleep(Duration::from_secs(1)).await; + child } - async fn start_smtp_server(setting: EmailSetting, smtp_password: String) -> ChildGuard { - let mut cmd = Command::new("mailtutan"); - cmd.arg("--smtp-port").arg(setting.smtp_port.to_string()); + #[derive(Deserialize)] + struct Mail { + sender: String, + } - ChildGuard(cmd.spawn().expect("Failed to start server")) + async fn read_mails() -> Vec