Allow multiple localpart catch all separators, e.g. both "+" and "-", for addresses you+anything@example.com and you-anything@example.com

The original config option stays, and we still use it for the common case where
we have a single separator. The "+" is configured by default. It is optional,
just like the new option "LocalpartCatchallSeparators" (plural).

When parsing the config file, we combine LocalpartCatchallSeparator and
LocalpartCatchallSeparators into a single list
LocalpartCatchallSeparatorsEffective, which we use throughout the code.

For issue #301 by janc13
This commit is contained in:
Mechiel Lukkien
2025-03-07 14:39:58 +01:00
parent d0b241499f
commit 9a8bb1134b
26 changed files with 255 additions and 95 deletions

View File

@ -1007,10 +1007,7 @@ func (s server) Send(ctx context.Context, req webapi.SendRequest) (resp webapi.S
useFromID := slices.Contains(accConf.ParsedFromIDLoginAddresses, loginAddr)
var localpartBase string
if useFromID {
if confDom.LocalpartCatchallSeparator == "" {
xcheckuserf(errors.New(`localpart catchall separator must be configured for domain`), `composing unique "from" address`)
}
localpartBase = strings.SplitN(string(fromPath.Localpart), confDom.LocalpartCatchallSeparator, 2)[0]
localpartBase = strings.SplitN(string(fromPath.Localpart), confDom.LocalpartCatchallSeparatorsEffective[0], 2)[0]
}
fromIDs := make([]string, len(recipients))
qml := make([]queue.Msg, len(recipients))
@ -1019,7 +1016,7 @@ func (s server) Send(ctx context.Context, req webapi.SendRequest) (resp webapi.S
fp := fromPath
if useFromID {
fromIDs[i] = xrandomID(16)
fp.Localpart = smtp.Localpart(localpartBase + confDom.LocalpartCatchallSeparator + fromIDs[i])
fp.Localpart = smtp.Localpart(localpartBase + confDom.LocalpartCatchallSeparatorsEffective[0] + fromIDs[i])
}
// Don't use per-recipient unique message prefix when multiple recipients are