75 lines
2.2 KiB
Go
75 lines
2.2 KiB
Go
package email
|
|
|
|
import (
|
|
"fmt"
|
|
"net/smtp"
|
|
|
|
"git.dustin.coffee/hobokenchicken/dumpsterChat/internal/config"
|
|
)
|
|
|
|
type Mailer struct {
|
|
cfg config.SMTPConfig
|
|
}
|
|
|
|
func NewMailer(cfg config.SMTPConfig) *Mailer {
|
|
return &Mailer{cfg: cfg}
|
|
}
|
|
|
|
func (m *Mailer) Send(to, subject, body string) error {
|
|
if m.cfg.Host == "" || m.cfg.Port == "" {
|
|
return fmt.Errorf("SMTP is not configured")
|
|
}
|
|
|
|
auth := smtp.PlainAuth("", m.cfg.Username, m.cfg.Password, m.cfg.Host)
|
|
|
|
msg := []byte("To: " + to + "\r\n" +
|
|
"Subject: " + subject + "\r\n" +
|
|
"Content-Type: text/html; charset=UTF-8\r\n" +
|
|
"\r\n" +
|
|
body + "\r\n")
|
|
|
|
addr := m.cfg.Host + ":" + m.cfg.Port
|
|
|
|
// Some servers (like STARTTLS on 587) require standard Dial, then StartTLS
|
|
// We'll use smtp.SendMail which does STARTTLS automatically if the server supports it
|
|
err := smtp.SendMail(addr, auth, m.cfg.Username, []string{to}, msg)
|
|
if err != nil {
|
|
// If standard SendMail fails due to TLS issues, fallback to manual TLS/STARTTLS if needed
|
|
// But smtp.SendMail is usually sufficient for standard STARTTLS on port 587.
|
|
return fmt.Errorf("failed to send email: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (m *Mailer) SendVerificationEmail(to, username, token, appURL string) error {
|
|
subject := "Verify your dumpsterChat email"
|
|
link := fmt.Sprintf("%s/verify-email?token=%s", appURL, token)
|
|
body := fmt.Sprintf(`
|
|
<h1>Welcome to dumpsterChat, %s!</h1>
|
|
<p>Please verify your email address by clicking the link below:</p>
|
|
<p><a href="%s">%s</a></p>
|
|
<p>If you did not sign up for this account, you can safely ignore this email.</p>
|
|
`, username, link, link)
|
|
|
|
return m.Send(to, subject, body)
|
|
}
|
|
|
|
func (m *Mailer) SendPasswordResetEmail(to, username, token, appURL string) error {
|
|
subject := "Reset your dumpsterChat password"
|
|
link := fmt.Sprintf("%s/reset-password?token=%s", appURL, token)
|
|
body := fmt.Sprintf(`
|
|
<h1>Password Reset Request</h1>
|
|
<p>Hi %s,</p>
|
|
<p>We received a request to reset your password. Click the link below to set a new password:</p>
|
|
<p><a href="%s">%s</a></p>
|
|
<p>If you did not request this, please ignore this email.</p>
|
|
`, username, link, link)
|
|
|
|
return m.Send(to, subject, body)
|
|
}
|
|
|
|
func (m *Mailer) SendAnnouncement(to, subject, body string) error {
|
|
return m.Send(to, subject, body)
|
|
}
|