mirror of
https://github.com/mjl-/mox.git
synced 2024-12-27 08:53:48 +03:00
in webmail & webapisrv, store bcc header in sent messages
when sending a message with bcc's, prepend the bcc header to the message we store in the sent folder. still not in the message we send to the recipients.
This commit is contained in:
parent
abd098e8c0
commit
c9451d4d06
11 changed files with 42 additions and 11 deletions
|
@ -1405,7 +1405,7 @@ func (a *Account) DeliverMessage(log mlog.Log, tx *bstore.Tx, m *Message, msgFil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: perhaps we should match the recipients based on smtp submission and a matching message-id? we now miss the addresses in bcc's. for webmail, we could insert the recipients directly.
|
// todo: perhaps we should match the recipients based on smtp submission and a matching message-id? we now miss the addresses in bcc's if the mail client doesn't save a message that includes the bcc header in the sent mailbox.
|
||||||
if mb.Sent && part != nil && part.Envelope != nil {
|
if mb.Sent && part != nil && part.Envelope != nil {
|
||||||
e := part.Envelope
|
e := part.Envelope
|
||||||
sent := e.Date
|
sent := e.Date
|
||||||
|
|
|
@ -64,7 +64,8 @@ type Message struct {
|
||||||
To []NameAddress
|
To []NameAddress
|
||||||
CC []NameAddress
|
CC []NameAddress
|
||||||
// For submissions, BCC addressees receive the message but are not added to the
|
// For submissions, BCC addressees receive the message but are not added to the
|
||||||
// message headers. For incoming messages, this is typically empty.
|
// headers of the outgoing message. Only the message saved the to the Sent mailbox
|
||||||
|
// gets the Bcc header prepended. For incoming messages, this is typically empty.
|
||||||
BCC []NameAddress
|
BCC []NameAddress
|
||||||
|
|
||||||
// Optional Reply-To header, where the recipient is asked to send replies to.
|
// Optional Reply-To header, where the recipient is asked to send replies to.
|
||||||
|
|
|
@ -615,7 +615,7 @@ func (s server) Send(ctx context.Context, req webapi.SendRequest) (resp webapi.S
|
||||||
from, fromPath := froms[0], fromPaths[0]
|
from, fromPath := froms[0], fromPaths[0]
|
||||||
to, toPaths := xparseAddresses(m.To)
|
to, toPaths := xparseAddresses(m.To)
|
||||||
cc, ccPaths := xparseAddresses(m.CC)
|
cc, ccPaths := xparseAddresses(m.CC)
|
||||||
_, bccPaths := xparseAddresses(m.BCC)
|
bcc, bccPaths := xparseAddresses(m.BCC)
|
||||||
|
|
||||||
recipients := append(append(toPaths, ccPaths...), bccPaths...)
|
recipients := append(append(toPaths, ccPaths...), bccPaths...)
|
||||||
addresses := append(append(m.To, m.CC...), m.BCC...)
|
addresses := append(append(m.To, m.CC...), m.BCC...)
|
||||||
|
@ -714,6 +714,7 @@ func (s server) Send(ctx context.Context, req webapi.SendRequest) (resp webapi.S
|
||||||
}
|
}
|
||||||
xc.HeaderAddrs("To", to)
|
xc.HeaderAddrs("To", to)
|
||||||
xc.HeaderAddrs("Cc", cc)
|
xc.HeaderAddrs("Cc", cc)
|
||||||
|
// We prepend Bcc headers to the message when adding to the Sent mailbox.
|
||||||
if m.Subject != "" {
|
if m.Subject != "" {
|
||||||
xcheckcontrol(m.Subject)
|
xcheckcontrol(m.Subject)
|
||||||
xc.Subject(m.Subject)
|
xc.Subject(m.Subject)
|
||||||
|
@ -1037,6 +1038,17 @@ func (s server) Send(ctx context.Context, req webapi.SendRequest) (resp webapi.S
|
||||||
modseq, err := acc.NextModSeq(tx)
|
modseq, err := acc.NextModSeq(tx)
|
||||||
xcheckf(err, "next modseq")
|
xcheckf(err, "next modseq")
|
||||||
|
|
||||||
|
// If there were bcc headers, prepend those to the stored message only, before the
|
||||||
|
// DKIM signature. The DKIM-signature oversigns the bcc header, so this stored message
|
||||||
|
// won't validate with DKIM anymore, which is fine.
|
||||||
|
if len(bcc) > 0 {
|
||||||
|
var sb strings.Builder
|
||||||
|
xbcc := message.NewComposer(&sb, 100*1024, smtputf8)
|
||||||
|
xbcc.HeaderAddrs("Bcc", bcc)
|
||||||
|
xbcc.Flush()
|
||||||
|
msgPrefix = sb.String() + msgPrefix
|
||||||
|
}
|
||||||
|
|
||||||
sentm := store.Message{
|
sentm := store.Message{
|
||||||
CreateSeq: modseq,
|
CreateSeq: modseq,
|
||||||
ModSeq: modseq,
|
ModSeq: modseq,
|
||||||
|
|
|
@ -382,7 +382,6 @@ func TestServer(t *testing.T) {
|
||||||
msgRes, err := client.MessageGet(ctxbg, webapi.MessageGetRequest{MsgID: 1})
|
msgRes, err := client.MessageGet(ctxbg, webapi.MessageGetRequest{MsgID: 1})
|
||||||
tcheckf(t, err, "remove suppressed address")
|
tcheckf(t, err, "remove suppressed address")
|
||||||
sentMsg := sendReq.Message
|
sentMsg := sendReq.Message
|
||||||
sentMsg.BCC = []webapi.NameAddress{} // todo: the Sent message should contain the BCC. for webmail too.
|
|
||||||
sentMsg.Date = msgRes.Message.Date
|
sentMsg.Date = msgRes.Message.Date
|
||||||
sentMsg.HTML += "\n"
|
sentMsg.HTML += "\n"
|
||||||
tcompare(t, msgRes.Message, sentMsg)
|
tcompare(t, msgRes.Message, sentMsg)
|
||||||
|
|
|
@ -286,7 +286,8 @@ func xrandom(ctx context.Context, n int) []byte {
|
||||||
// Bcc message header.
|
// Bcc message header.
|
||||||
//
|
//
|
||||||
// If a Sent mailbox is configured, messages are added to it after submitting
|
// If a Sent mailbox is configured, messages are added to it after submitting
|
||||||
// to the delivery queue.
|
// to the delivery queue. If Bcc addresses were present, a header is prepended
|
||||||
|
// to the message stored in the Sent mailbox.
|
||||||
func (w Webmail) MessageSubmit(ctx context.Context, m SubmitMessage) {
|
func (w Webmail) MessageSubmit(ctx context.Context, m SubmitMessage) {
|
||||||
// Similar between ../smtpserver/server.go:/submit\( and ../webmail/api.go:/MessageSubmit\( and ../webapisrv/server.go:/Send\(
|
// Similar between ../smtpserver/server.go:/submit\( and ../webmail/api.go:/MessageSubmit\( and ../webapisrv/server.go:/Send\(
|
||||||
|
|
||||||
|
@ -343,9 +344,11 @@ func (w Webmail) MessageSubmit(ctx context.Context, m SubmitMessage) {
|
||||||
recipients = append(recipients, addr.Address)
|
recipients = append(recipients, addr.Address)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var bccAddrs []message.NameAddress
|
||||||
for _, s := range m.Bcc {
|
for _, s := range m.Bcc {
|
||||||
addr, err := parseAddress(s)
|
addr, err := parseAddress(s)
|
||||||
xcheckuserf(ctx, err, "parsing Bcc address")
|
xcheckuserf(ctx, err, "parsing Bcc address")
|
||||||
|
bccAddrs = append(bccAddrs, addr)
|
||||||
recipients = append(recipients, addr.Address)
|
recipients = append(recipients, addr.Address)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,6 +449,7 @@ func (w Webmail) MessageSubmit(ctx context.Context, m SubmitMessage) {
|
||||||
}
|
}
|
||||||
xc.HeaderAddrs("To", toAddrs)
|
xc.HeaderAddrs("To", toAddrs)
|
||||||
xc.HeaderAddrs("Cc", ccAddrs)
|
xc.HeaderAddrs("Cc", ccAddrs)
|
||||||
|
// We prepend Bcc headers to the message when adding to the Sent mailbox.
|
||||||
if m.Subject != "" {
|
if m.Subject != "" {
|
||||||
xc.Subject(m.Subject)
|
xc.Subject(m.Subject)
|
||||||
}
|
}
|
||||||
|
@ -750,6 +754,17 @@ func (w Webmail) MessageSubmit(ctx context.Context, m SubmitMessage) {
|
||||||
xcheckf(ctx, err, "next modseq")
|
xcheckf(ctx, err, "next modseq")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If there were bcc headers, prepend those to the stored message only, before the
|
||||||
|
// DKIM signature. The DKIM-signature oversigns the bcc header, so this stored
|
||||||
|
// message won't validate with DKIM anymore, which is fine.
|
||||||
|
if len(bccAddrs) > 0 {
|
||||||
|
var sb strings.Builder
|
||||||
|
xbcc := message.NewComposer(&sb, 100*1024, smtputf8)
|
||||||
|
xbcc.HeaderAddrs("Bcc", bccAddrs)
|
||||||
|
xbcc.Flush()
|
||||||
|
msgPrefix = sb.String() + msgPrefix
|
||||||
|
}
|
||||||
|
|
||||||
sentm := store.Message{
|
sentm := store.Message{
|
||||||
CreateSeq: modseq,
|
CreateSeq: modseq,
|
||||||
ModSeq: modseq,
|
ModSeq: modseq,
|
||||||
|
|
|
@ -101,7 +101,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "MessageSubmit",
|
"Name": "MessageSubmit",
|
||||||
"Docs": "MessageSubmit sends a message by submitting it the outgoing email queue. The\nmessage is sent to all addresses listed in the To, Cc and Bcc addresses, without\nBcc message header.\n\nIf a Sent mailbox is configured, messages are added to it after submitting\nto the delivery queue.",
|
"Docs": "MessageSubmit sends a message by submitting it the outgoing email queue. The\nmessage is sent to all addresses listed in the To, Cc and Bcc addresses, without\nBcc message header.\n\nIf a Sent mailbox is configured, messages are added to it after submitting\nto the delivery queue. If Bcc addresses were present, a header is prepended\nto the message stored in the Sent mailbox.",
|
||||||
"Params": [
|
"Params": [
|
||||||
{
|
{
|
||||||
"Name": "m",
|
"Name": "m",
|
||||||
|
|
|
@ -715,7 +715,8 @@ export class Client {
|
||||||
// Bcc message header.
|
// Bcc message header.
|
||||||
//
|
//
|
||||||
// If a Sent mailbox is configured, messages are added to it after submitting
|
// If a Sent mailbox is configured, messages are added to it after submitting
|
||||||
// to the delivery queue.
|
// to the delivery queue. If Bcc addresses were present, a header is prepended
|
||||||
|
// to the message stored in the Sent mailbox.
|
||||||
async MessageSubmit(m: SubmitMessage): Promise<void> {
|
async MessageSubmit(m: SubmitMessage): Promise<void> {
|
||||||
const fn: string = "MessageSubmit"
|
const fn: string = "MessageSubmit"
|
||||||
const paramTypes: string[][] = [["SubmitMessage"]]
|
const paramTypes: string[][] = [["SubmitMessage"]]
|
||||||
|
|
|
@ -424,7 +424,7 @@ func TestAPI(t *testing.T) {
|
||||||
tcompare(t, len(l), 0)
|
tcompare(t, len(l), 0)
|
||||||
tcompare(t, full, true)
|
tcompare(t, full, true)
|
||||||
l, full = api.CompleteRecipient(ctx, "cc2")
|
l, full = api.CompleteRecipient(ctx, "cc2")
|
||||||
tcompare(t, l, []string{"mjl cc2 <mjl+cc2@mox.example>"})
|
tcompare(t, l, []string{"mjl cc2 <mjl+cc2@mox.example>", "mjl bcc2 <mjl+bcc2@mox.example>"})
|
||||||
tcompare(t, full, true)
|
tcompare(t, full, true)
|
||||||
|
|
||||||
// RecipientSecurity
|
// RecipientSecurity
|
||||||
|
|
|
@ -457,7 +457,8 @@ var api;
|
||||||
// Bcc message header.
|
// Bcc message header.
|
||||||
//
|
//
|
||||||
// If a Sent mailbox is configured, messages are added to it after submitting
|
// If a Sent mailbox is configured, messages are added to it after submitting
|
||||||
// to the delivery queue.
|
// to the delivery queue. If Bcc addresses were present, a header is prepended
|
||||||
|
// to the message stored in the Sent mailbox.
|
||||||
async MessageSubmit(m) {
|
async MessageSubmit(m) {
|
||||||
const fn = "MessageSubmit";
|
const fn = "MessageSubmit";
|
||||||
const paramTypes = [["SubmitMessage"]];
|
const paramTypes = [["SubmitMessage"]];
|
||||||
|
|
|
@ -457,7 +457,8 @@ var api;
|
||||||
// Bcc message header.
|
// Bcc message header.
|
||||||
//
|
//
|
||||||
// If a Sent mailbox is configured, messages are added to it after submitting
|
// If a Sent mailbox is configured, messages are added to it after submitting
|
||||||
// to the delivery queue.
|
// to the delivery queue. If Bcc addresses were present, a header is prepended
|
||||||
|
// to the message stored in the Sent mailbox.
|
||||||
async MessageSubmit(m) {
|
async MessageSubmit(m) {
|
||||||
const fn = "MessageSubmit";
|
const fn = "MessageSubmit";
|
||||||
const paramTypes = [["SubmitMessage"]];
|
const paramTypes = [["SubmitMessage"]];
|
||||||
|
|
|
@ -457,7 +457,8 @@ var api;
|
||||||
// Bcc message header.
|
// Bcc message header.
|
||||||
//
|
//
|
||||||
// If a Sent mailbox is configured, messages are added to it after submitting
|
// If a Sent mailbox is configured, messages are added to it after submitting
|
||||||
// to the delivery queue.
|
// to the delivery queue. If Bcc addresses were present, a header is prepended
|
||||||
|
// to the message stored in the Sent mailbox.
|
||||||
async MessageSubmit(m) {
|
async MessageSubmit(m) {
|
||||||
const fn = "MessageSubmit";
|
const fn = "MessageSubmit";
|
||||||
const paramTypes = [["SubmitMessage"]];
|
const paramTypes = [["SubmitMessage"]];
|
||||||
|
|
Loading…
Reference in a new issue