use postmoogle as general purpose SMTP server and allow other apps or scripts to send emails through it

This commit is contained in:
Aine
2022-09-22 18:21:17 +03:00
parent c9c871287d
commit 070a6ffc76
11 changed files with 108 additions and 20 deletions

View File

@@ -65,3 +65,18 @@ func (b *Bot) allowSend(actorID id.UserID, targetRoomID id.RoomID) bool {
return !cfg.NoSend()
}
// AllowAuth check if SMTP login (mailbox) and password are valid
func (b *Bot) AllowAuth(mailbox, password string) bool {
roomID, ok := b.GetMapping(mailbox)
if !ok {
return false
}
cfg, err := b.getRoomSettings(roomID)
if err != nil {
b.log.Error("failed to retrieve settings: %v", err)
return false
}
return cfg.Password() != "" && cfg.Password() == password
}

View File

@@ -73,6 +73,12 @@ func (b *Bot) initCommands() commandList {
sanitizer: func(s string) string { return s },
allowed: b.allowOwner,
},
{
key: roomOptionPassword,
description: "Get or set SMTP password of the room's mailbox",
sanitizer: func(s string) string { return strings.TrimSpace(s) },
allowed: b.allowOwner,
},
{allowed: b.allowOwner}, // delimiter
{
key: roomOptionNoSend,
@@ -293,6 +299,11 @@ func (b *Bot) runSend(ctx context.Context) {
return
}
if !utils.AddressValid(to) {
b.Error(ctx, evt.RoomID, "email address is not valid")
return
}
cfg, err := b.getRoomSettings(evt.RoomID)
if err != nil {
b.Error(ctx, evt.RoomID, "failed to retrieve room settings: %v", err)

View File

@@ -46,8 +46,8 @@ func (b *Bot) GetMapping(mailbox string) (id.RoomID, bool) {
}
// Send email to matrix room
func (b *Bot) Send2Matrix(ctx context.Context, email *utils.Email) error {
roomID, ok := b.GetMapping(utils.Mailbox(email.To))
func (b *Bot) Send2Matrix(ctx context.Context, email *utils.Email, local bool) error {
roomID, ok := b.GetMapping(email.Mailbox(local))
if !ok {
return errors.New("room not found")
}
@@ -59,6 +59,10 @@ func (b *Bot) Send2Matrix(ctx context.Context, email *utils.Email) error {
b.Error(ctx, roomID, "cannot get settings: %v", err)
}
if !local && cfg.NoSend() {
return errors.New("that mailbox is receive-only")
}
var threadID id.EventID
if email.InReplyTo != "" && !cfg.NoThreads() {
threadID = b.getThreadID(roomID, email.InReplyTo)
@@ -81,6 +85,11 @@ func (b *Bot) Send2Matrix(ctx context.Context, email *utils.Email) error {
if !cfg.NoFiles() {
b.sendFiles(ctx, roomID, email.Files, cfg.NoThreads(), threadID)
}
if !local {
email.MessageID = fmt.Sprintf("<%s@%s>", eventID, b.domain)
return b.mta.Send(email.From, email.To, email.Compose(b.getBotSettings().DKIMPrivateKey()))
}
return nil
}

View File

@@ -21,6 +21,7 @@ const (
roomOptionNoHTML = "nohtml"
roomOptionNoThreads = "nothreads"
roomOptionNoFiles = "nofiles"
roomOptionPassword = "password"
)
type roomSettings map[string]string
@@ -43,6 +44,10 @@ func (s roomSettings) Owner() string {
return s.Get(roomOptionOwner)
}
func (s roomSettings) Password() string {
return s.Get(roomOptionPassword)
}
func (s roomSettings) NoSend() bool {
return utils.Bool(s.Get(roomOptionNoSend))
}