diff --git a/backend/ee-repo-ref.txt b/backend/ee-repo-ref.txt index 91d0c51cf7..f6c4f387b4 100644 --- a/backend/ee-repo-ref.txt +++ b/backend/ee-repo-ref.txt @@ -1 +1 @@ -181fa0c206d7f84a289b4396a7f7764bc815d284 +f0df8b82c4c089d384423ed64b8504506084820d diff --git a/backend/windmill-api-settings/src/lib.rs b/backend/windmill-api-settings/src/lib.rs index 92621d526c..7c2453d848 100644 --- a/backend/windmill-api-settings/src/lib.rs +++ b/backend/windmill-api-settings/src/lib.rs @@ -52,7 +52,7 @@ use windmill_common::secret_backend::{ use windmill_common::{ auth::is_super_admin_email, ee_oss::{get_license_plan, LicensePlan}, - email_oss::send_email_plain_text, + email_oss::{send_email_plain_text, SMTP_ENABLED}, error::{self, pg_error_message, JsonResult, Result}, get_database_url, global_settings::{ @@ -237,10 +237,19 @@ pub async fn test_email( Json(test_email): Json, ) -> error::Result { require_super_admin(&db, &authed.email).await?; + if !SMTP_ENABLED { + return Err(error::Error::Generic( + axum::http::StatusCode::NOT_IMPLEMENTED, + "This Windmill build was compiled without SMTP support, so no email can be sent." + .to_string(), + )); + } let smtp = test_email.smtp; let to = test_email.to; - let client_timeout = Duration::from_secs(3); + // A connection attempt covers TCP, the TLS handshake, EHLO and authentication against a remote + // provider; a tighter budget times out before the server ever states why it refused. + let client_timeout = Duration::from_secs(20); send_email_plain_text( "Test email from Windmill", "Test email content", @@ -248,7 +257,15 @@ pub async fn test_email( smtp, Some(client_timeout), ) - .await?; + .await + // The SMTP layer already phrases its failures for an instance admin; the anyhow wrapper it + // comes back in would bury that behind "Internal: ... @". + .map_err(|e| match e { + error::Error::Anyhow { error, .. } => { + error::Error::Generic(axum::http::StatusCode::BAD_REQUEST, format!("{error:#}")) + } + e => e, + })?; Ok("Sent test email".to_string()) } diff --git a/backend/windmill-common/src/email_oss.rs b/backend/windmill-common/src/email_oss.rs index 2813ebe458..38d634699b 100644 --- a/backend/windmill-common/src/email_oss.rs +++ b/backend/windmill-common/src/email_oss.rs @@ -5,6 +5,11 @@ pub use crate::email_ee::*; #[cfg(not(feature = "private"))] use crate::server::Smtp; +/// Every send below is a no-op in this build, so callers that report success to a user (the +/// instance-settings SMTP test) have to say so instead of claiming the email went out. +#[cfg(not(feature = "private"))] +pub const SMTP_ENABLED: bool = false; + #[cfg(not(feature = "private"))] pub async fn send_email( _subject: &str, diff --git a/frontend/src/lib/components/instanceSettings/SmtpSettings.svelte b/frontend/src/lib/components/instanceSettings/SmtpSettings.svelte index f7607c5d6c..f87dce7ed6 100644 --- a/frontend/src/lib/components/instanceSettings/SmtpSettings.svelte +++ b/frontend/src/lib/components/instanceSettings/SmtpSettings.svelte @@ -12,7 +12,7 @@ @@ -171,6 +190,7 @@ unifiedSize="md" variant="accent" onclick={testSmtpSettings} + loading={testing} disabled={!testEmail || !isSmtpSettingsValid($values['smtp_settings']) || disabled} btnClasses="text-xs" startIcon={{ icon: Mail }} @@ -178,6 +198,11 @@ Send test email + {#if testError} + + {testError} + + {/if}