diff --git a/interface/src/app/settings/ApplicationSettings.tsx b/interface/src/app/settings/ApplicationSettings.tsx index 15cd5770b..53ef9841f 100644 --- a/interface/src/app/settings/ApplicationSettings.tsx +++ b/interface/src/app/settings/ApplicationSettings.tsx @@ -430,7 +430,15 @@ const ApplicationSettings = () => { label={LL.SECURITY(0)} value={data.email_security} variant="outlined" - onChange={updateFormValue} + onChange={(event) => + updateFormValue({ + target: { + name: 'email_security', + type: 'number', + value: event.target.value + } + } as React.ChangeEvent) + } margin="normal" select > diff --git a/mock-api/restServer.ts b/mock-api/restServer.ts index 7f9de376a..919620cb9 100644 --- a/mock-api/restServer.ts +++ b/mock-api/restServer.ts @@ -65,7 +65,16 @@ let settings = { modbus_max_clients: 10, modbus_timeout: 10000, developer_mode: true, - disable_reset: false + disable_reset: false, + email_enabled: false, + email_security: 2, + email_server: 'smtp.gmail.com', + email_port: 587, + email_login: 'test@emsesp.org', + email_pass: 'password', + email_sender: 'test@emsesp.org', + email_recp: 'test@emsesp.org', + email_subject: 'ems-esp notification' }; // EMS-ESP System Settings diff --git a/src/core/system.cpp b/src/core/system.cpp index a4e595dd3..2c900e5da 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -147,7 +147,7 @@ bool System::command_sendmail(const char * value, const int8_t) { port, security == EMAIL_SECURITY::SSL ? " (SSL)" : security == EMAIL_SECURITY::STARTTLS ? " (STARTTLS)" - : "", + : " (plain)", value); bool success = false; @@ -158,7 +158,11 @@ bool System::command_sendmail(const char * value, const int8_t) { auto * r_client = new ReadyClient(*ssl_client); auto * smtp = new SMTPClient(*r_client); - ssl_client->setClient(basic_client); + // enableSSL is baked in at setClient() time (same as HTTP fetch). Default true + // would send a TLS Client Hello on connect — which a plain port-25 server + // logs as "SMTP syntax error" / NUL characters. + const bool implicit_ssl = (security == EMAIL_SECURITY::SSL); + ssl_client->setClient(basic_client, implicit_ssl); ssl_client->setInsecure(); ssl_client->setBufferSizes(16384, 1024); basic_client->setTimeout(5000); // socket-level read timeout @@ -168,7 +172,6 @@ bool System::command_sendmail(const char * value, const int8_t) { : security == EMAIL_SECURITY::SSL ? readymail_protocol_ssl : readymail_protocol_tls); - // smtp->connect(server, port, sendmailCallback); smtp->connect(server, port); if (!smtp->isConnected()) { @@ -180,15 +183,17 @@ bool System::command_sendmail(const char * value, const int8_t) { return false; } - // LOG_INFO("authenticate %s:%s", login.c_str(), pass.c_str()); - smtp->authenticate(login, pass, readymail_auth_password); - if (!smtp->isAuthenticated()) { - LOG_ERROR("send email authentication error"); - delete smtp; - delete r_client; - delete ssl_client; - delete basic_client; - return false; + // internal/open relays often have no AUTH; empty login means skip it + if (!login.isEmpty()) { + smtp->authenticate(login, pass, readymail_auth_password); + if (!smtp->isAuthenticated()) { + LOG_ERROR("send email authentication error"); + delete smtp; + delete r_client; + delete ssl_client; + delete basic_client; + return false; + } } JsonDocument doc(PSRAM_DOC); String body = value; diff --git a/src/web/WebSettingsService.cpp b/src/web/WebSettingsService.cpp index f4489a0da..e46d1e093 100644 --- a/src/web/WebSettingsService.cpp +++ b/src/web/WebSettingsService.cpp @@ -316,8 +316,9 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) { settings.weblog_level = root["weblog_level"] | EMSESP_DEFAULT_WEBLOG_LEVEL; settings.weblog_compact = root["weblog_compact"] | EMSESP_DEFAULT_WEBLOG_COMPACT; - settings.email_enabled = root["email_enabled"] | FACTORY_EMAIL_ENABLE; - settings.email_security = root["email_security"] | FACTORY_EMAIL_SECURITY; + settings.email_enabled = root["email_enabled"] | FACTORY_EMAIL_ENABLE; + // Off is 0, so `| FACTORY_EMAIL_SECURITY` would replace it with STARTTLS (2) + settings.email_security = root["email_security"].isNull() ? FACTORY_EMAIL_SECURITY : root["email_security"].as(); settings.email_server = root["email_server"] | FACTORY_EMAIL_SERVER; settings.email_port = root["email_port"] | FACTORY_EMAIL_PORT; settings.email_login = root["email_login"] | FACTORY_EMAIL_LOGIN;