diff --git a/cmd/handlers.go b/cmd/handlers.go
index 37584015d..d7aac6ab6 100644
--- a/cmd/handlers.go
+++ b/cmd/handlers.go
@@ -68,6 +68,7 @@ func initHTTPHandlers(e *echo.Echo, app *App) {
g.GET("/api/settings", handleGetSettings)
g.PUT("/api/settings", handleUpdateSettings)
+ g.POST("/api/settings/smtp/test", handleTestSMTPSettings)
g.POST("/api/admin/reload", handleReloadApp)
g.GET("/api/logs", handleGetLogs)
diff --git a/cmd/settings.go b/cmd/settings.go
index 55c98cbc4..5f86a290a 100644
--- a/cmd/settings.go
+++ b/cmd/settings.go
@@ -1,6 +1,8 @@
package main
import (
+ "bytes"
+ "io/ioutil"
"net/http"
"regexp"
"strings"
@@ -8,6 +10,11 @@ import (
"time"
"github.com/gofrs/uuid"
+ "github.com/knadh/koanf"
+ "github.com/knadh/koanf/parsers/json"
+ "github.com/knadh/koanf/providers/rawbytes"
+ "github.com/knadh/listmonk/internal/messenger"
+ "github.com/knadh/listmonk/internal/messenger/email"
"github.com/knadh/listmonk/models"
"github.com/labstack/echo/v4"
)
@@ -193,3 +200,62 @@ func handleGetLogs(c echo.Context) error {
app := c.Get("app").(*App)
return c.JSON(http.StatusOK, okResp{app.bufLog.Lines()})
}
+
+// handleTestSMTPSettings returns the log entries stored in the log buffer.
+func handleTestSMTPSettings(c echo.Context) error {
+ app := c.Get("app").(*App)
+
+ // Copy the raw JSON post body.
+ reqBody, err := ioutil.ReadAll(c.Request().Body)
+ if err != nil {
+ app.log.Printf("error reading SMTP test: %v", err)
+ return echo.NewHTTPError(http.StatusBadRequest, app.i18n.Ts("globals.messages.internalError"))
+ }
+
+ // Load the JSON into koanf to parse SMTP settings properly including timestrings.
+ ko := koanf.New(".")
+ if err := ko.Load(rawbytes.Provider(reqBody), json.Parser()); err != nil {
+ app.log.Printf("error unmarshalling SMTP test request: %v", err)
+ return echo.NewHTTPError(http.StatusBadRequest, app.i18n.Ts("globals.messages.internalError"))
+ }
+
+ req := email.Server{}
+ if err := ko.UnmarshalWithConf("", &req, koanf.UnmarshalConf{Tag: "json"}); err != nil {
+ app.log.Printf("error scanning SMTP test request: %v", err)
+ return echo.NewHTTPError(http.StatusBadRequest, app.i18n.Ts("globals.messages.internalError"))
+ }
+
+ to := ko.String("email")
+ if to == "" {
+ return echo.NewHTTPError(http.StatusBadRequest, app.i18n.Ts("globals.messages.missingFields", "name", "email"))
+ }
+
+ // Initialize a new SMTP pool.
+ req.MaxConns = 1
+ req.IdleTimeout = time.Second * 2
+ req.PoolWaitTimeout = time.Second * 2
+ msgr, err := email.New(req)
+ if err != nil {
+ return echo.NewHTTPError(http.StatusBadRequest,
+ app.i18n.Ts("globals.messages.errorCreating", "name", "SMTP", "error", err.Error()))
+ }
+
+ var b bytes.Buffer
+ if err := app.notifTpls.tpls.ExecuteTemplate(&b, "smtp-test", nil); err != nil {
+ app.log.Printf("error compiling notification template '%s': %v", "smtp-test", err)
+ return err
+ }
+
+ m := messenger.Message{}
+ m.ContentType = app.notifTpls.contentType
+ m.From = app.constants.FromEmail
+ m.To = []string{to}
+ m.Subject = app.i18n.T("settings.smtp.testConnection")
+ m.Body = b.Bytes()
+ if err := msgr.Push(m); err != nil {
+ app.log.Printf("error sending SMTP test (%s): %v", m.Subject, err)
+ return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
+ }
+
+ return c.JSON(http.StatusOK, okResp{app.bufLog.Lines()})
+}
diff --git a/frontend/src/api/index.js b/frontend/src/api/index.js
index 0fab3572e..99a20471c 100644
--- a/frontend/src/api/index.js
+++ b/frontend/src/api/index.js
@@ -277,6 +277,9 @@ export const getSettings = async () => http.get('/api/settings',
export const updateSettings = async (data) => http.put('/api/settings', data,
{ loading: models.settings });
+export const testSMTP = async (data) => http.post('/api/settings/smtp/test', data,
+ { loading: models.settings, disableToast: true });
+
export const getLogs = async () => http.get('/api/logs',
{ loading: models.logs, camelCase: false });
diff --git a/frontend/src/utils.js b/frontend/src/utils.js
index 5bb3b61ea..f7d97ff7f 100644
--- a/frontend/src/utils.js
+++ b/frontend/src/utils.js
@@ -141,12 +141,14 @@ export default class Utils {
});
};
- prompt = (msg, inputAttrs, onConfirm, onCancel) => {
+ prompt = (msg, inputAttrs, onConfirm, onCancel, params) => {
+ const p = params || {};
+
Dialog.prompt({
scroll: 'keep',
message: this.escapeHTML(msg),
- confirmText: this.i18n.t('globals.buttons.ok'),
- cancelText: this.i18n.t('globals.buttons.cancel'),
+ confirmText: p.confirmText || this.i18n.t('globals.buttons.ok'),
+ cancelText: p.cancelText || this.i18n.t('globals.buttons.cancel'),
inputAttrs: {
type: 'string',
maxlength: 200,
diff --git a/frontend/src/views/settings/smtp.vue b/frontend/src/views/settings/smtp.vue
index 39cca4f3c..7128ff106 100644
--- a/frontend/src/views/settings/smtp.vue
+++ b/frontend/src/views/settings/smtp.vue
@@ -134,29 +134,63 @@
-
-
-
-
-
- {{ $t('settings.smtp.testConnection') }}
-
-
-
@@ -168,6 +202,7 @@
diff --git a/go.mod b/go.mod
index e91a8eeb4..3c373457d 100644
--- a/go.mod
+++ b/go.mod
@@ -15,7 +15,7 @@ require (
github.com/knadh/go-pop3 v0.3.0
github.com/knadh/goyesql/v2 v2.1.2
github.com/knadh/koanf v1.2.3
- github.com/knadh/smtppool v0.4.0
+ github.com/knadh/smtppool v1.0.0
github.com/knadh/stuffbin v1.1.0
github.com/labstack/echo/v4 v4.6.1
github.com/labstack/gommon v0.3.1 // indirect
diff --git a/go.sum b/go.sum
index 494ae9a0d..6b5b3f461 100644
--- a/go.sum
+++ b/go.sum
@@ -84,6 +84,8 @@ github.com/knadh/koanf v1.2.3 h1:2Rkr0YhhYk+4QEOm800Q3Pu0Wi87svTxM6uuEb4WhYw=
github.com/knadh/koanf v1.2.3/go.mod h1:xpPTwMhsA/aaQLAilyCCqfpEiY1gpa160AiCuWHJUjY=
github.com/knadh/smtppool v0.4.0 h1:335iXPwZ6katJVhauV4O6e8uPvvPmO6YLrfDQhb6UvE=
github.com/knadh/smtppool v0.4.0/go.mod h1:3DJHouXAgPDBz0kC50HukOsdapYSwIEfJGwuip46oCA=
+github.com/knadh/smtppool v1.0.0 h1:1c8A7+nD8WdMMzvd3yY5aoY9QBgyGTA+Iq1IdlgKGJw=
+github.com/knadh/smtppool v1.0.0/go.mod h1:3DJHouXAgPDBz0kC50HukOsdapYSwIEfJGwuip46oCA=
github.com/knadh/stuffbin v1.1.0 h1:f5S5BHzZALjuJEgTIOMC9NidEnBJM7Ze6Lu1GHR/lwU=
github.com/knadh/stuffbin v1.1.0/go.mod h1:yVCFaWaKPubSNibBsTAJ939q2ABHudJQxRWZWV5yh+4=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
diff --git a/i18n/cs-cz.json b/i18n/cs-cz.json
index 14352e3bc..e23456cb0 100644
--- a/i18n/cs-cz.json
+++ b/i18n/cs-cz.json
@@ -452,7 +452,10 @@
"settings.smtp.name": "SMTP",
"settings.smtp.retries": "Opakování",
"settings.smtp.retriesHelp": "Počet opakovaných pokusů, když zpráva selže.",
+ "settings.smtp.sendTest": "Send e-mail",
"settings.smtp.setCustomHeaders": "Nastavit vlastní záhlaví",
+ "settings.smtp.testConnection": "Test connection",
+ "settings.smtp.toEmail": "To e-mail",
"settings.title": "Nastavení",
"settings.updateAvailable": "Nová aktualizace {version} je k dispozici.",
"subscribers.advancedQuery": "Rozšířené",
diff --git a/i18n/de.json b/i18n/de.json
index cd13c5c84..a3015824e 100644
--- a/i18n/de.json
+++ b/i18n/de.json
@@ -452,7 +452,10 @@
"settings.smtp.name": "SMTP",
"settings.smtp.retries": "Wiederholungen",
"settings.smtp.retriesHelp": "Maximale Anzahl an Wiederholungen, wenn eine Machricht fehlschlägt.",
+ "settings.smtp.sendTest": "Send e-mail",
"settings.smtp.setCustomHeaders": "Benutzerdefinierten Header verwenden",
+ "settings.smtp.testConnection": "Test connection",
+ "settings.smtp.toEmail": "To e-mail",
"settings.title": "Einstellungen",
"settings.updateAvailable": "Ein neues Update auf {version} ist verfügbar.",
"subscribers.advancedQuery": "Erweitert",
diff --git a/i18n/en.json b/i18n/en.json
index 52cebfc4f..89906c1fa 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -452,8 +452,10 @@
"settings.smtp.name": "SMTP",
"settings.smtp.retries": "Retries",
"settings.smtp.retriesHelp": "Number of times to retry when a message fails.",
+ "settings.smtp.sendTest": "Send e-mail",
"settings.smtp.setCustomHeaders": "Set custom headers",
"settings.smtp.testConnection": "Test connection",
+ "settings.smtp.toEmail": "To e-mail",
"settings.title": "Settings",
"settings.updateAvailable": "A new update {version} is available.",
"subscribers.advancedQuery": "Advanced",
diff --git a/i18n/es.json b/i18n/es.json
index 0a7dbc180..f5b575153 100644
--- a/i18n/es.json
+++ b/i18n/es.json
@@ -452,7 +452,10 @@
"settings.smtp.name": "SMTP",
"settings.smtp.retries": "Reintentos",
"settings.smtp.retriesHelp": "Número de reintentos cuando un mensaje falla.",
+ "settings.smtp.sendTest": "Send e-mail",
"settings.smtp.setCustomHeaders": "Configurar encabezados personalizados.",
+ "settings.smtp.testConnection": "Test connection",
+ "settings.smtp.toEmail": "To e-mail",
"settings.title": "Configuraciones",
"settings.updateAvailable": "Una actualización {version} está disponible.",
"subscribers.advancedQuery": "Avanzado",
diff --git a/i18n/fi.json b/i18n/fi.json
index 4e1f6f912..7ef0c2238 100644
--- a/i18n/fi.json
+++ b/i18n/fi.json
@@ -452,7 +452,10 @@
"settings.smtp.name": "SMTP",
"settings.smtp.retries": "Retries",
"settings.smtp.retriesHelp": "Number of times to retry when a message fails.",
+ "settings.smtp.sendTest": "Send e-mail",
"settings.smtp.setCustomHeaders": "Set custom headers",
+ "settings.smtp.testConnection": "Test connection",
+ "settings.smtp.toEmail": "To e-mail",
"settings.title": "Settings",
"settings.updateAvailable": "A new update {version} is available.",
"subscribers.advancedQuery": "Advanced",
diff --git a/i18n/fr.json b/i18n/fr.json
index fde35acc9..b72b22eee 100644
--- a/i18n/fr.json
+++ b/i18n/fr.json
@@ -452,7 +452,10 @@
"settings.smtp.name": "SMTP",
"settings.smtp.retries": "Tentatives de renvoi",
"settings.smtp.retriesHelp": "Nombre de tentatives de renvoi d'un message en cas d'échec",
+ "settings.smtp.sendTest": "Send e-mail",
"settings.smtp.setCustomHeaders": "Définir des en-têtes personnalisés",
+ "settings.smtp.testConnection": "Test connection",
+ "settings.smtp.toEmail": "To e-mail",
"settings.title": "Paramètres",
"settings.updateAvailable": "Une nouvelle version ({version}) est disponible.",
"subscribers.advancedQuery": "Requête avancée",
diff --git a/i18n/hu.json b/i18n/hu.json
index cc4fe4ca2..dcf66e643 100644
--- a/i18n/hu.json
+++ b/i18n/hu.json
@@ -452,7 +452,10 @@
"settings.smtp.name": "SMTP",
"settings.smtp.retries": "Újrapróbálkozások",
"settings.smtp.retriesHelp": "Az újrapróbálkozások száma, ha az üzenet sikertelen.",
+ "settings.smtp.sendTest": "Send e-mail",
"settings.smtp.setCustomHeaders": "Egyéni fejlécek beállítása",
+ "settings.smtp.testConnection": "Test connection",
+ "settings.smtp.toEmail": "To e-mail",
"settings.title": "Beállítások",
"settings.updateAvailable": "Új frissítés {version} elérhető.",
"subscribers.advancedQuery": "További beállítások",
diff --git a/i18n/it.json b/i18n/it.json
index 4f7a79e1a..071af2d5c 100644
--- a/i18n/it.json
+++ b/i18n/it.json
@@ -452,7 +452,10 @@
"settings.smtp.name": "SMTP",
"settings.smtp.retries": "Tentativi",
"settings.smtp.retriesHelp": "Numero di tentativi in caso di errore invio messaggio.",
+ "settings.smtp.sendTest": "Send e-mail",
"settings.smtp.setCustomHeaders": "Definisci intestazioni personalizzate",
+ "settings.smtp.testConnection": "Test connection",
+ "settings.smtp.toEmail": "To e-mail",
"settings.title": "Impostazioni",
"settings.updateAvailable": "È a disposizione una nuova versione {version}.",
"subscribers.advancedQuery": "Avanzate",
diff --git a/i18n/jp.json b/i18n/jp.json
index af9564169..c4e957d66 100644
--- a/i18n/jp.json
+++ b/i18n/jp.json
@@ -452,7 +452,10 @@
"settings.smtp.name": "SMTP",
"settings.smtp.retries": "再トライ",
"settings.smtp.retriesHelp": "メッセージ送信失敗時の再試行数",
+ "settings.smtp.sendTest": "Send e-mail",
"settings.smtp.setCustomHeaders": "カスタムヘッダー設定",
+ "settings.smtp.testConnection": "Test connection",
+ "settings.smtp.toEmail": "To e-mail",
"settings.title": "設定",
"settings.updateAvailable": "新しい {バージョン} の更新が可能です。",
"subscribers.advancedQuery": "アドバンスド",
diff --git a/i18n/ml.json b/i18n/ml.json
index f669c3835..0d26cabae 100644
--- a/i18n/ml.json
+++ b/i18n/ml.json
@@ -452,7 +452,10 @@
"settings.smtp.name": "എസ്. എം. ടീ. പി",
"settings.smtp.retries": "പുനഃശ്രമങ്ങൾ",
"settings.smtp.retriesHelp": "സന്ദേശമയ്ക്കുന്നത് പരാജയപ്പെട്ടാൽ എത്ര തവണ വീണ്ടും ശ്രമിക്കണം.",
+ "settings.smtp.sendTest": "Send e-mail",
"settings.smtp.setCustomHeaders": "ഇഷ്ടാനുസൃത തലക്കെട്ടുകൾ നൽകുക",
+ "settings.smtp.testConnection": "Test connection",
+ "settings.smtp.toEmail": "To e-mail",
"settings.title": "ക്രമീകരണങ്ങൾ",
"settings.updateAvailable": "A new update {version} is available.",
"subscribers.advancedQuery": "വിപുലമായത്",
diff --git a/i18n/nl.json b/i18n/nl.json
index c4128ddec..1006ce675 100644
--- a/i18n/nl.json
+++ b/i18n/nl.json
@@ -452,7 +452,10 @@
"settings.smtp.name": "SMTP",
"settings.smtp.retries": "Nieuwe pogingen",
"settings.smtp.retriesHelp": "Aantal keer om opnieuw te proberen als een bericht mislukt.",
+ "settings.smtp.sendTest": "Send e-mail",
"settings.smtp.setCustomHeaders": "Stel custom headers in",
+ "settings.smtp.testConnection": "Test connection",
+ "settings.smtp.toEmail": "To e-mail",
"settings.title": "Instellingen",
"settings.updateAvailable": "Een nieuwe update {version} is beschikbaar.",
"subscribers.advancedQuery": "Geavanceerd",
diff --git a/i18n/pl.json b/i18n/pl.json
index 1d3c834f1..4f3f2b96e 100644
--- a/i18n/pl.json
+++ b/i18n/pl.json
@@ -452,7 +452,10 @@
"settings.smtp.name": "SMTP",
"settings.smtp.retries": "Ponowne próby",
"settings.smtp.retriesHelp": "Liczba ponownych prób przy niepowodzeniu",
+ "settings.smtp.sendTest": "Send e-mail",
"settings.smtp.setCustomHeaders": "Ustaw niestandardowe nagłówki",
+ "settings.smtp.testConnection": "Test connection",
+ "settings.smtp.toEmail": "To e-mail",
"settings.title": "Ustawienia",
"settings.updateAvailable": "Nowa wersja {version} jest dostępna.",
"subscribers.advancedQuery": "Zaawansowane",
diff --git a/i18n/pt-BR.json b/i18n/pt-BR.json
index 9c93d0612..3392cce00 100644
--- a/i18n/pt-BR.json
+++ b/i18n/pt-BR.json
@@ -452,7 +452,10 @@
"settings.smtp.name": "SMTP",
"settings.smtp.retries": "Tentativas",
"settings.smtp.retriesHelp": "Número de tentativas quando uma mensagem falhar.",
+ "settings.smtp.sendTest": "Send e-mail",
"settings.smtp.setCustomHeaders": "Definir cabeçalhos personalizados",
+ "settings.smtp.testConnection": "Test connection",
+ "settings.smtp.toEmail": "To e-mail",
"settings.title": "Configurações",
"settings.updateAvailable": "Atualização: a nova versão {version} já está disponível.",
"subscribers.advancedQuery": "Avançado",
diff --git a/i18n/pt.json b/i18n/pt.json
index ea7dd5277..39df5465b 100644
--- a/i18n/pt.json
+++ b/i18n/pt.json
@@ -452,7 +452,10 @@
"settings.smtp.name": "SMTP",
"settings.smtp.retries": "Tentativas",
"settings.smtp.retriesHelp": "Número de vezes para tentar novamente quando uma mensagem falha.",
+ "settings.smtp.sendTest": "Send e-mail",
"settings.smtp.setCustomHeaders": "Colocar headers customizados",
+ "settings.smtp.testConnection": "Test connection",
+ "settings.smtp.toEmail": "To e-mail",
"settings.title": "Definições",
"settings.updateAvailable": "A new update {version} is available.",
"subscribers.advancedQuery": "Avançado",
diff --git a/i18n/ro.json b/i18n/ro.json
index 41d371c79..29e2e3452 100644
--- a/i18n/ro.json
+++ b/i18n/ro.json
@@ -452,7 +452,10 @@
"settings.smtp.name": "SMTP",
"settings.smtp.retries": "Reîncercări",
"settings.smtp.retriesHelp": "De câte ori trebuie să reîncercați când un mesaj eșuează.",
+ "settings.smtp.sendTest": "Send e-mail",
"settings.smtp.setCustomHeaders": "Setează anteturi personalizate",
+ "settings.smtp.testConnection": "Test connection",
+ "settings.smtp.toEmail": "To e-mail",
"settings.title": "Setări",
"settings.updateAvailable": "Este disponibilă o nouă actualizare {versiune}.",
"subscribers.advancedQuery": "Avansat",
diff --git a/i18n/ru.json b/i18n/ru.json
index 3616f093d..857408853 100644
--- a/i18n/ru.json
+++ b/i18n/ru.json
@@ -452,7 +452,10 @@
"settings.smtp.name": "SMTP",
"settings.smtp.retries": "Повторные попытки",
"settings.smtp.retriesHelp": "Количество повторных попыток после ошибки отправки сообщения.",
+ "settings.smtp.sendTest": "Send e-mail",
"settings.smtp.setCustomHeaders": "Установка настраиваемых заголовков",
+ "settings.smtp.testConnection": "Test connection",
+ "settings.smtp.toEmail": "To e-mail",
"settings.title": "Параметры",
"settings.updateAvailable": "Доступна новая версия: {version}.",
"subscribers.advancedQuery": "Дополнительно",
diff --git a/i18n/tr.json b/i18n/tr.json
index aa6710152..259280243 100644
--- a/i18n/tr.json
+++ b/i18n/tr.json
@@ -452,7 +452,10 @@
"settings.smtp.name": "SMTP",
"settings.smtp.retries": "Tekrarlama",
"settings.smtp.retriesHelp": "Mesaj hata verdiğinde tekrar deneme sayısı.",
+ "settings.smtp.sendTest": "Send e-mail",
"settings.smtp.setCustomHeaders": "Özel başlık tanımla",
+ "settings.smtp.testConnection": "Test connection",
+ "settings.smtp.toEmail": "To e-mail",
"settings.title": "Ayarlar",
"settings.updateAvailable": "Yeni bir güncel sürüm {version} mevcuttur.",
"subscribers.advancedQuery": "İleri düzey",
diff --git a/i18n/vi.json b/i18n/vi.json
index fc20d740f..fa60c65b2 100644
--- a/i18n/vi.json
+++ b/i18n/vi.json
@@ -452,7 +452,10 @@
"settings.smtp.name": "SMTP",
"settings.smtp.retries": "Thử lại",
"settings.smtp.retriesHelp": "Số lần thử lại khi có thông báo không thành công.",
+ "settings.smtp.sendTest": "Send e-mail",
"settings.smtp.setCustomHeaders": "Đặt tiêu đề tùy chỉnh",
+ "settings.smtp.testConnection": "Test connection",
+ "settings.smtp.toEmail": "To e-mail",
"settings.title": "Cài đặt",
"settings.updateAvailable": "Đã có bản cập nhật mới {version}.",
"subscribers.advancedQuery": "Trình độ cao",
diff --git a/static/email-templates/import-status.html b/static/email-templates/import-status.html
index 0531205f3..39748cca0 100644
--- a/static/email-templates/import-status.html
+++ b/static/email-templates/import-status.html
@@ -16,4 +16,4 @@ {{ L.Ts "email.status.importTitle" }}
{{ template "footer" }}
-{{ end }}
\ No newline at end of file
+{{ end }}
diff --git a/static/email-templates/smtp-test.html b/static/email-templates/smtp-test.html
new file mode 100644
index 000000000..61cfb385f
--- /dev/null
+++ b/static/email-templates/smtp-test.html
@@ -0,0 +1,5 @@
+{{ define "smtp-test" }}
+{{ template "header" . }}
+{{ L.Ts "settings.smtp.testConnection" }}
+{{ template "footer" }}
+{{ end }}