From b9c3de52048441943fa9aefde4e3d3183ee7cf91 Mon Sep 17 00:00:00 2001 From: Abhishek Shroff Date: Tue, 8 Jul 2025 21:55:30 +0530 Subject: [PATCH] [server][mail] Initialize --- server/internal/api/v1/auth/routes.go | 2 +- server/internal/command/command.go | 8 +++- server/internal/mail/mail.go | 64 ++++++++++++++++++-------- server/internal/mail/password_reset.go | 22 --------- server/internal/mail/welcome.go | 15 ------ 5 files changed, 54 insertions(+), 57 deletions(-) delete mode 100644 server/internal/mail/password_reset.go delete mode 100644 server/internal/mail/welcome.go diff --git a/server/internal/api/v1/auth/routes.go b/server/internal/api/v1/auth/routes.go index dd41eef6..9e49de2c 100644 --- a/server/internal/api/v1/auth/routes.go +++ b/server/internal/api/v1/auth/routes.go @@ -187,7 +187,7 @@ func handleRequestPasswordReset(c *gin.Context) { return err } } else { - // TODO: #jobs #mail + // TODO: #jobs #mail #error go func() { mail.SendPasswordResetEmail(user, token) }() diff --git a/server/internal/command/command.go b/server/internal/command/command.go index 6d4ecb34..78b1560e 100644 --- a/server/internal/command/command.go +++ b/server/internal/command/command.go @@ -137,9 +137,15 @@ func SetupCommand() { steve.RegisterWorker(client, &jobs.DeleteContentsWorker{}) } serve.Cfg = cfg.Server - mail.Cfg = cfg.Mail core.Cfg = cfg.Core + if err := mail.Initialize(cfg.Mail); err != nil { + if errors.Is(err, mail.EmailNotConfigured) { + log.Info().Msg("mail not configured") + } else { + log.Fatal().Err(err).Msg("failed to initialize mail") + } + } auth.Init(cfg.Auth, logger) if err := storage.Initialize(db.Get(context.Background()), cfg.Storage); err != nil { diff --git a/server/internal/mail/mail.go b/server/internal/mail/mail.go index 899ee76e..77182fca 100644 --- a/server/internal/mail/mail.go +++ b/server/internal/mail/mail.go @@ -1,32 +1,63 @@ package mail import ( + "errors" "io" "codeberg.org/shroff/phylum/server/internal/core" - "github.com/sirupsen/logrus" gomail "gopkg.in/mail.v2" ) -var Cfg Config -var d *gomail.Dialer +var initialized = false +var dialer *gomail.Dialer -type Recipient struct { - Name string - Email string -} +var instance string +var from FromConfig -func dialer() *gomail.Dialer { - if d == nil { - d = gomail.NewDialer(Cfg.SMTP.Host, Cfg.SMTP.Port, Cfg.SMTP.Username, Cfg.SMTP.Password) +var EmailNotConfigured = errors.New("email not configured") + +func Initialize(cfg Config) error { + if initialized { + return errors.New("already initialized") } - return d + initialized = true + if cfg.SMTP.Host == "" { + return EmailNotConfigured + } + + dialer = gomail.NewDialer(cfg.SMTP.Host, cfg.SMTP.Port, cfg.SMTP.Username, cfg.SMTP.Password) + from = cfg.From + instance = cfg.Instance + + return nil } -func send(e Email, rcpt core.User, params any) error { - d := dialer() +func SendWelcomeEmail(u core.User) error { + return send(emails["welcome"], u, nil) +} + +func SendPasswordResetEmail(u core.User, token string) error { + return send(emails["password_reset"], u, map[string]string{ + "token": token, + }) +} + +func send(e Email, rcpt core.User, params map[string]string) error { + if dialer == nil { + return EmailNotConfigured + } + if params == nil { + params = make(map[string]string) + } + params["name"] = rcpt.Name + params["email"] = rcpt.Email + params["instance"] = instance + if rcpt.Name == "" { + params["name"] = "there" + } + msg := gomail.NewMessage() - msg.SetAddressHeader("From", Cfg.From.Email, Cfg.From.Name) + msg.SetAddressHeader("From", from.Email, from.Name) msg.SetAddressHeader("To", rcpt.Email, rcpt.Name) msg.SetHeader("Subject", e.Subject) msg.SetBodyWriter("text/plain", func(w io.Writer) error { @@ -35,9 +66,6 @@ func send(e Email, rcpt core.User, params any) error { msg.AddAlternativeWriter("text/html", func(w io.Writer) error { return e.HTML.ExecuteTemplate(w, "base", params) }) - err := d.DialAndSend(msg) - if err != nil { - logrus.Warn(err) - } + err := dialer.DialAndSend(msg) return err } diff --git a/server/internal/mail/password_reset.go b/server/internal/mail/password_reset.go deleted file mode 100644 index b5f43df4..00000000 --- a/server/internal/mail/password_reset.go +++ /dev/null @@ -1,22 +0,0 @@ -package mail - -import "codeberg.org/shroff/phylum/server/internal/core" - -type ResetPasswordParams struct { - Name string - URL string -} - -func SendPasswordResetEmail(u core.User, token string) error { - email := emails["password_reset"] - params := map[string]string{ - "name": u.Name, - "email": u.Email, - "instance": Cfg.Instance, - "token": token, - } - if u.Name == "" { - params["name"] = "there" - } - return send(email, u, params) -} diff --git a/server/internal/mail/welcome.go b/server/internal/mail/welcome.go deleted file mode 100644 index c10aef03..00000000 --- a/server/internal/mail/welcome.go +++ /dev/null @@ -1,15 +0,0 @@ -package mail - -import "codeberg.org/shroff/phylum/server/internal/core" - -func SendWelcomeEmail(u core.User) error { - email := emails["welcome"] - params := map[string]string{ - "name": u.Name, - "instance": Cfg.Instance, - } - if u.Name == "" { - params["name"] = "there" - } - return send(email, u, params) -}