This is the main dovel repository, it has the Go code to run dovel SMTP server.
Author: b (git@mail.blmayer.dev)
Date: Fri Jun 30 20:50:07 2023 -0300
Parent: d301a8d
Improved handlers
commit daa51d72677f74977289e7718976094d61417209
Author: b <git@mail.blmayer.dev>
Date: Fri Jun 30 20:50:07 2023 -0300
Improved handlers
diff --git a/cmd/dovel/backend.go b/cmd/dovel/backend.go
index cd42039..fdb0ea0 100644
--- a/cmd/dovel/backend.go
+++ b/cmd/dovel/backend.go
@@ -4,6 +4,7 @@ import (
"crypto"
"fmt"
"io"
+ "net/mail"
"strings"
"blmayer.dev/x/dovel/interfaces"
@@ -13,59 +14,73 @@ import (
// A Session is returned after EHLO.
type Session struct {
- User string
+ user string
handlers map[string]interfaces.Mailer
+ from string
+ to string
}
func (s Session) AuthPlain(username, password string) error {
println("connection sent", username, password)
+ // call vault
return nil
}
func (s Session) Mail(from string, opts *smtp.MailOptions) error {
println("Mail from:", from)
+ s.from = from
return nil
}
func (s Session) Rcpt(to string) error {
println("Rcpt to:", to)
+ s.to = to
return nil
}
func (s Session) Data(r io.Reader) error {
- content, err := io.ReadAll(r)
+ email, err := mail.ReadMessage(r)
if err != nil {
- println("read content", err.Error())
+ println("parse email", err.Error())
return err
}
- email, err := parsemail.Parse(strings.NewReader(string(content)))
+ from, err := mail.ParseAddress(s.from)
if err != nil {
- println("parse email", err.Error())
+ println("parse address", err.Error())
+ return err
+ }
+ fromDomain := strings.Split(from, "@")[1]
+ tos, err := mail.ParseAddressList(s.to)
+ if err != nil {
+ println("parse addresslist", err.Error())
return err
}
- // get user from to field
- mail := interfaces.ToEmail(email)
- mail.Raw = content
- for _, to := range mail.To {
- userDomain := strings.Split(to, "@")
- handler, ok := s.handlers[userDomain[1]]
- if !ok {
- println("no handler for domain", userDomain[1])
- return fmt.Errorf("no handler for domain %s", userDomain)
+ for _, to := range tos {
+ localdom := strings.Split(to.Address, "@")
+ if h, ok := s.handlers[localdom[1]]; ok {
+ err = h.Save(r)
+ } else {
+ if user == "" {
+ return fmt.Errorf("needs auth")
+ }
+ h, ok = s.handlers[fromDomain]
+ if !ok {
+ return fmt.Errorf("from is wrong")
+ }
+ err = h.Send(r)
}
- mail.To = []string{to}
- if err := handler.Save(mail); err != nil {
+ if err != nil {
println("handler error", err.Error())
- return fmt.Errorf("handler error %s", err.Error())
+ return
}
}
return nil
}
-func (s Session) Reset() {}
+func (s Session) Reset() { }
func (s Session) Logout() error {
println("logged out")