This is the main dovel repository, it has the Go code to run dovel SMTP server.
- package main
- import (
- "crypto/tls"
- "encoding/json"
- "log/slog"
- "os"
- "path"
- "time"
- "github.com/emersion/go-smtp"
- )
- var (
- cfg = Config{}
- configPath string
- v Vault
- )
- func main() {
- if os.Getenv("DEBUG") != "" {
- hand := slog.NewTextHandler(
- os.Stdout,
- &slog.HandlerOptions{Level: slog.LevelDebug},
- )
- slog.SetDefault(slog.New(hand))
- }
- var err error
- configPath, err = os.UserConfigDir()
- if err != nil {
- slog.Warn(err.Error(), "details", "using ~/.config/dovel/config.json")
- configPath = "~/.config"
- }
- configPath = path.Join(configPath, "dovel")
- configFile, err := os.Open(path.Join(configPath, "config.json"))
- if err != nil {
- panic(err)
- }
- json.NewDecoder(configFile).Decode(&cfg)
- slog.Debug("config loaded", "config", cfg)
- if cfg.VaultFile != "" {
- slog.Info("loading users", "file", cfg.VaultFile)
- v, err = NewStore(cfg.VaultFile)
- if err != nil {
- slog.Warn("failed to load users", "error", err.Error())
- }
- }
- s := smtp.NewServer(backend{})
- s.Addr = ":" + cfg.Port
- s.Domain = cfg.Domain
- s.ReadTimeout = time.Duration(cfg.ReadTimeout) * time.Second
- s.WriteTimeout = time.Duration(cfg.WriteTimeout) * time.Second
- s.MaxMessageBytes = cfg.MaxMessageBytes
- s.MaxRecipients = cfg.MaxRecipients
- s.AllowInsecureAuth = cfg.AllowInsecureAuth
- if cfg.Certificate != "" {
- slog.Debug("loading certs", "cert", cfg.Certificate, "key", cfg.PrivateKey)
- c, err := tls.LoadX509KeyPair(cfg.Certificate, cfg.PrivateKey)
- if err != nil {
- panic(err)
- }
- s.TLSConfig = &tls.Config{Certificates: []tls.Certificate{c}}
- }
- err = s.ListenAndServe()
- if err != nil {
- panic(err)
- }
- }