1
0
Fork 0
mirror of https://git.sr.ht/~rjarry/aerc synced 2025-07-03 23:30:21 +02:00
aerc/worker/imap/imap.go
Julian Swagemakers 4f866e6894 imap: strip whitespace from Message-Id and In-Reply-To
Outlook.com is generating fairly long Message-IDs and using folding[0]
to put the ID on a new line. This is resulting in the Message-ID to
contain a leading white space, which is preventing `TrimPrefix` from
removing the less than symbol. When replying the In-Reply-To header will
then contain "< <message-id>" which is not desired and prevents email
clients or lists form correctly associating the email replied to. For
example lore.kernel.org[1]. Trimming tabs, newlines, and spaces from
Message-ID resolves the issue.

[0]: https://datatracker.ietf.org/doc/html/rfc822#section-3.1.1
[1]: https://lore.kernel.org/git/D4U1RWVWEW5D.2T853XSBO1FPA@swagemakers.org/#t

Changelog-fixed: Remove unwanted less than symbol from In-Reply-To
 header when Message-ID uses folding.
Signed-off-by: Julian Swagemakers <julian@swagemakers.org>
Acked-by: Robin Jarry <robin@jarry.cc>
2024-10-24 22:13:51 +02:00

119 lines
2.8 KiB
Go

package imap
import (
"strings"
"github.com/emersion/go-imap"
"git.sr.ht/~rjarry/aerc/models"
"github.com/emersion/go-message/charset"
"github.com/emersion/go-message/mail"
)
func init() {
imap.CharsetReader = charset.Reader
}
func toSeqSet(uids []models.UID) *imap.SeqSet {
set := new(imap.SeqSet)
for _, uid := range uids {
set.AddNum(models.UidToUint32(uid))
}
return set
}
func translateBodyStructure(bs *imap.BodyStructure) *models.BodyStructure {
if bs == nil {
return nil
}
var parts []*models.BodyStructure
for _, part := range bs.Parts {
parts = append(parts, translateBodyStructure(part))
}
// TODO: is that all?
return &models.BodyStructure{
MIMEType: bs.MIMEType,
MIMESubType: bs.MIMESubType,
Params: bs.Params,
Description: bs.Description,
Encoding: bs.Encoding,
Parts: parts,
Disposition: bs.Disposition,
DispositionParams: bs.DispositionParams,
}
}
func translateEnvelope(e *imap.Envelope) *models.Envelope {
if e == nil {
return nil
}
return &models.Envelope{
Date: e.Date,
Subject: e.Subject,
From: translateAddresses(e.From),
ReplyTo: translateAddresses(e.ReplyTo),
To: translateAddresses(e.To),
Cc: translateAddresses(e.Cc),
Bcc: translateAddresses(e.Bcc),
MessageId: translateMessageID(e.MessageId),
InReplyTo: translateMessageID(e.InReplyTo),
}
}
func translateMessageID(messageID string) string {
// Strip away unwanted characters, go-message expects the message id
// without brackets, spaces, tabs and new lines.
return strings.Trim(messageID, "<> \t\r\n")
}
func translateAddresses(addrs []*imap.Address) []*mail.Address {
var converted []*mail.Address
for _, addr := range addrs {
converted = append(converted, &mail.Address{
Name: addr.PersonalName,
Address: addr.Address(),
})
}
return converted
}
var imapToFlag = map[string]models.Flags{
imap.SeenFlag: models.SeenFlag,
imap.RecentFlag: models.RecentFlag,
imap.AnsweredFlag: models.AnsweredFlag,
imap.DeletedFlag: models.DeletedFlag,
imap.FlaggedFlag: models.FlaggedFlag,
imap.DraftFlag: models.DraftFlag,
}
var flagToImap = map[models.Flags]string{
models.SeenFlag: imap.SeenFlag,
models.RecentFlag: imap.RecentFlag,
models.AnsweredFlag: imap.AnsweredFlag,
models.DeletedFlag: imap.DeletedFlag,
models.FlaggedFlag: imap.FlaggedFlag,
models.DraftFlag: imap.DraftFlag,
}
func translateImapFlags(imapFlags []string) models.Flags {
var flags models.Flags
for _, imapFlag := range imapFlags {
if flag, ok := imapToFlag[imapFlag]; ok {
flags |= flag
}
}
return flags
}
func translateFlags(flags models.Flags) []string {
var imapFlags []string
for flag, imapFlag := range flagToImap {
if flags.Has(flag) {
imapFlags = append(imapFlags, imapFlag)
}
}
return imapFlags
}