aboutsummaryrefslogtreecommitdiffstats
path: root/commands/msg/reply.go
diff options
context:
space:
mode:
authorJason Cox <me@jasoncarloscox.com>2023-10-12 10:38:39 -0400
committerRobin Jarry <robin@jarry.cc>2023-10-22 15:12:45 +0200
commit863e124e8437ac2f5a92fe3f291b7e7e022787fc (patch)
tree54aca238e0c622b6a34e4095830c45c264c0fabf /commands/msg/reply.go
parent8fdabbc4bfcaf8f0214a66777336a356cc2a0616 (diff)
downloadaerc-863e124e8437ac2f5a92fe3f291b7e7e022787fc.tar.gz
accounts: allow fnmatch-style wildcards in aliases
Wildcard aliases make it possible to always reply from the same address to which a message was addressed, which is useful for catch-all email domains. Support fnmatch-style wildcards in only the address portion of an alias. When replying to a message that matches a wildcard alias, substitute the matching email address for the wildcard address, but keep the name specified with the wildcard address. For example, when the alias "Someone Awesome" <*@someone.com> is present, the reply to an email addressed to "Someone" <hi@someone.com> would be from "Someone Awesome" <hi@someone.com>. Signed-off-by: Jason Cox <me@jasoncarloscox.com> Acked-by: Robin Jarry <robin@jarry.cc>
Diffstat (limited to 'commands/msg/reply.go')
-rw-r--r--commands/msg/reply.go52
1 files changed, 34 insertions, 18 deletions
diff --git a/commands/msg/reply.go b/commands/msg/reply.go
index b9ee050a..fff90fff 100644
--- a/commands/msg/reply.go
+++ b/commands/msg/reply.go
@@ -20,6 +20,7 @@ import (
"git.sr.ht/~rjarry/aerc/lib/parse"
"git.sr.ht/~rjarry/aerc/log"
"git.sr.ht/~rjarry/aerc/models"
+ "github.com/danwakefield/fnmatch"
"github.com/emersion/go-message/mail"
)
@@ -76,7 +77,6 @@ func (reply) Execute(args []string) error {
return errors.New("No account selected")
}
conf := acct.AccountConfig()
- from := conf.From
store := widget.Store()
if store == nil {
@@ -87,23 +87,7 @@ func (reply) Execute(args []string) error {
return err
}
- // figure out the sending from address if we have aliases
- if len(conf.Aliases) != 0 {
- rec := newAddrSet()
- rec.AddList(msg.Envelope.To)
- rec.AddList(msg.Envelope.Cc)
- // test the from first, it has priority over any present alias
- if rec.Contains(from) {
- // do nothing
- } else {
- for _, a := range conf.Aliases {
- if rec.Contains(a) {
- from = a
- break
- }
- }
- }
- }
+ from := chooseFromAddr(conf, msg)
var (
to []*mail.Address
@@ -279,6 +263,28 @@ func (reply) Execute(args []string) error {
}
}
+func chooseFromAddr(conf *config.AccountConfig, msg *models.MessageInfo) *mail.Address {
+ if len(conf.Aliases) == 0 {
+ return conf.From
+ }
+
+ rec := newAddrSet()
+ rec.AddList(msg.Envelope.To)
+ rec.AddList(msg.Envelope.Cc)
+ // test the from first, it has priority over any present alias
+ if rec.Contains(conf.From) {
+ // do nothing
+ } else {
+ for _, a := range conf.Aliases {
+ if match := rec.FindMatch(a); match != "" {
+ return &mail.Address{Name: a.Name, Address: match}
+ }
+ }
+ }
+
+ return conf.From
+}
+
type addrSet map[string]struct{}
func newAddrSet() addrSet {
@@ -301,6 +307,16 @@ func (s addrSet) Contains(a *mail.Address) bool {
return ok
}
+func (s addrSet) FindMatch(a *mail.Address) string {
+ for addr := range s {
+ if fnmatch.Match(a.Address, addr, 0) {
+ return addr
+ }
+ }
+
+ return ""
+}
+
// setReferencesHeader adds the references header to target based on parent
// according to RFC2822
func setReferencesHeader(target, parent *mail.Header) error {