Add login rename and password reset flow
This commit is contained in:
parent
b625c95c29
commit
e7611b2d49
4 changed files with 362 additions and 28 deletions
|
|
@ -1,13 +1,100 @@
|
|||
package backend
|
||||
|
||||
// SMTP wird AUSSCHLIESSLICH fuers manuelle Weiterleiten einzelner Mails aus dem
|
||||
// Viewer benutzt (Cfg.ForwardSMTP). Der Postfach-Umzug laeuft NIE ueber SMTP,
|
||||
// sondern ueber IMAP APPEND (05-imap-target.go) -- sonst gingen Datum, Flags
|
||||
// und Ordnerstruktur verloren.
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/smtp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// SMTP wird AUSSCHLIESSLICH fuers manuelle Weiterleiten einzelner Mails und
|
||||
// App-Benachrichtigungen wie Passwort-Reset benutzt. Der Postfach-Umzug laeuft
|
||||
// NIE ueber SMTP, sondern ueber IMAP APPEND (05-imap-target.go).
|
||||
|
||||
func SendPlainMail(to []string, subject, body string) error {
|
||||
cfg := Cfg.ForwardSMTP
|
||||
if strings.TrimSpace(cfg.Host) == "" || cfg.Port == 0 || strings.TrimSpace(cfg.From) == "" {
|
||||
return fmt.Errorf("forward_smtp ist nicht vollstaendig konfiguriert")
|
||||
}
|
||||
from := cfg.From
|
||||
if strings.TrimSpace(cfg.User) != "" {
|
||||
from = cfg.User
|
||||
}
|
||||
message := []byte("From: " + cfg.From + "\r\n" +
|
||||
"To: " + strings.Join(to, ", ") + "\r\n" +
|
||||
"Subject: " + subject + "\r\n" +
|
||||
"Content-Type: text/plain; charset=utf-8\r\n" +
|
||||
"\r\n" + body)
|
||||
addr := net.JoinHostPort(cfg.Host, fmt.Sprint(cfg.Port))
|
||||
auth := smtp.Auth(nil)
|
||||
if cfg.User != "" || cfg.Pass != "" {
|
||||
auth = smtp.PlainAuth("", cfg.User, cfg.Pass, cfg.Host)
|
||||
}
|
||||
if cfg.Port == 465 {
|
||||
return sendTLS(addr, cfg.Host, auth, from, to, message)
|
||||
}
|
||||
return sendStartTLS(addr, cfg.Host, auth, from, to, message)
|
||||
}
|
||||
|
||||
func sendStartTLS(addr, host string, auth smtp.Auth, from string, to []string, message []byte) error {
|
||||
c, err := smtp.Dial(addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer c.Close()
|
||||
if ok, _ := c.Extension("STARTTLS"); ok {
|
||||
if err := c.StartTLS(&tls.Config{ServerName: host, MinVersion: tls.VersionTLS12}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return smtpClientSend(c, auth, from, to, message)
|
||||
}
|
||||
|
||||
func sendTLS(addr, host string, auth smtp.Auth, from string, to []string, message []byte) error {
|
||||
conn, err := tls.Dial("tcp", addr, &tls.Config{ServerName: host, MinVersion: tls.VersionTLS12})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c, err := smtp.NewClient(conn, host)
|
||||
if err != nil {
|
||||
_ = conn.Close()
|
||||
return err
|
||||
}
|
||||
defer c.Close()
|
||||
return smtpClientSend(c, auth, from, to, message)
|
||||
}
|
||||
|
||||
func smtpClientSend(c *smtp.Client, auth smtp.Auth, from string, to []string, message []byte) error {
|
||||
if auth != nil {
|
||||
if err := c.Auth(auth); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := c.Mail(from); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, rcpt := range to {
|
||||
if err := c.Rcpt(rcpt); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
w, err := c.Data()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write(message); err != nil {
|
||||
_ = w.Close()
|
||||
return err
|
||||
}
|
||||
if err := w.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
return c.Quit()
|
||||
}
|
||||
|
||||
// ForwardMessage leitet den mbox-Rohtext an einen Empfaenger weiter.
|
||||
func ForwardMessage(rawMessage []byte, to []string, extraNote string) error {
|
||||
// TODO Codex: net/smtp (stdlib) mit STARTTLS + AUTH gegen Cfg.ForwardSMTP.
|
||||
// Original als Anhang oder inline weiterleiten, From = Cfg.ForwardSMTP.From.
|
||||
return nil
|
||||
body := extraNote + "\n\n" + string(rawMessage)
|
||||
return SendPlainMail(to, "Weitergeleitete Nachricht aus Mail-Graveyard", body)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue