forked from Silverfish/proton-bridge
GODT-967 Append external message to All Mail should be APPEND to Archive instead
This commit is contained in:
committed by
Jakub Cuth
parent
6b7e706100
commit
0cf1b38c2b
@ -20,6 +20,7 @@ package imap
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/mail"
|
"net/mail"
|
||||||
"strings"
|
"strings"
|
||||||
@ -145,6 +146,16 @@ func (im *imapMailbox) createDraftMessage(kr *crypto.KeyRing, email string, body
|
|||||||
return uidplus.AppendResponse(im.storeMailbox.UIDValidity(), im.storeMailbox.GetUIDList([]string{draft.ID}))
|
return uidplus.AppendResponse(im.storeMailbox.UIDValidity(), im.storeMailbox.GetUIDList([]string{draft.ID}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func findMailboxForAddress(address storeAddressProvider, labelID string) (storeMailboxProvider, error) {
|
||||||
|
for _, mailBox := range address.ListMailboxes() {
|
||||||
|
if mailBox.LabelID() == labelID {
|
||||||
|
return mailBox, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("could not find %v label in mailbox for user %v", labelID,
|
||||||
|
address.AddressString())
|
||||||
|
}
|
||||||
|
|
||||||
func (im *imapMailbox) labelExistingMessage(msg storeMessageProvider) error { //nolint[funlen]
|
func (im *imapMailbox) labelExistingMessage(msg storeMessageProvider) error { //nolint[funlen]
|
||||||
im.log.Info("Labelling existing message")
|
im.log.Info("Labelling existing message")
|
||||||
|
|
||||||
@ -161,29 +172,20 @@ func (im *imapMailbox) labelExistingMessage(msg storeMessageProvider) error { //
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
storeMBox := im.storeMailbox
|
|
||||||
|
|
||||||
// Outlook Uses APPEND instead of COPY. There is no need to copy to All Mail because messages are already there.
|
// Outlook Uses APPEND instead of COPY. There is no need to copy to All Mail because messages are already there.
|
||||||
// If the message is copied from Spam or Trash, it must be moved otherwise we will have data loss.
|
// If the message is copied from Spam or Trash, it must be moved otherwise we will have data loss.
|
||||||
// If the message is moved from any folder, the moment when expunge happens on source we will move message trash unless we move it to archive.
|
// If the message is moved from any folder, the moment when expunge happens on source we will move message trash unless we move it to archive.
|
||||||
// If the message is already in Archive we should not call API at all.
|
// If the message is already in Archive we should not call API at all.
|
||||||
// Otherwise the message is already in All mail, Return OK.
|
// Otherwise the message is already in All mail, Return OK.
|
||||||
|
var storeMBox = im.storeMailbox
|
||||||
if pmapi.AllMailLabel == storeMBox.LabelID() {
|
if pmapi.AllMailLabel == storeMBox.LabelID() {
|
||||||
if msg.Message().HasLabelID(pmapi.ArchiveLabel) {
|
if msg.Message().HasLabelID(pmapi.ArchiveLabel) {
|
||||||
return uidplus.AppendResponse(im.storeMailbox.UIDValidity(), im.storeMailbox.GetUIDList([]string{msg.ID()}))
|
return uidplus.AppendResponse(storeMBox.UIDValidity(), storeMBox.GetUIDList([]string{msg.ID()}))
|
||||||
}
|
}
|
||||||
|
var err error
|
||||||
foundArchive := false
|
storeMBox, err = findMailboxForAddress(im.storeAddress, pmapi.ArchiveLabel)
|
||||||
for _, mBox := range im.storeAddress.ListMailboxes() {
|
if err != nil {
|
||||||
if mBox.LabelID() == pmapi.ArchiveLabel {
|
return err
|
||||||
foundArchive = true
|
|
||||||
storeMBox = mBox
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !foundArchive {
|
|
||||||
return errors.New("could not find Archive folder")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,7 +196,7 @@ func (im *imapMailbox) labelExistingMessage(msg storeMessageProvider) error { //
|
|||||||
return uidplus.AppendResponse(im.storeMailbox.UIDValidity(), im.storeMailbox.GetUIDList([]string{msg.ID()}))
|
return uidplus.AppendResponse(im.storeMailbox.UIDValidity(), im.storeMailbox.GetUIDList([]string{msg.ID()}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (im *imapMailbox) importMessage(kr *crypto.KeyRing, hdr textproto.Header, body []byte, imapFlags []string, date time.Time) error {
|
func (im *imapMailbox) importMessage(kr *crypto.KeyRing, hdr textproto.Header, body []byte, imapFlags []string, date time.Time) error { //nolint[funlen]
|
||||||
im.log.Info("Importing external message")
|
im.log.Info("Importing external message")
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -236,18 +238,29 @@ func (im *imapMailbox) importMessage(kr *crypto.KeyRing, hdr textproto.Header, b
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
messageID, err := im.storeMailbox.ImportMessage(enc, seen, labelIDs, flags, time)
|
var targetMailbox = im.storeMailbox
|
||||||
|
if targetMailbox.LabelID() == pmapi.AllMailLabel {
|
||||||
|
// Importing mail in directly into All Mail is not allowed. Instead we redirect the import to Archive
|
||||||
|
// The mail will automatically appear in All mail. The appends response still reports that the mail was
|
||||||
|
// successfully APPEND to All Mail.
|
||||||
|
targetMailbox, err = findMailboxForAddress(im.storeAddress, pmapi.ArchiveLabel)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
messageID, err := targetMailbox.ImportMessage(enc, seen, labelIDs, flags, time)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
msg, err := im.storeMailbox.GetMessage(messageID)
|
msg, err := targetMailbox.GetMessage(messageID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if msg.IsMarkedDeleted() {
|
if msg.IsMarkedDeleted() {
|
||||||
if err := im.storeMailbox.MarkMessagesUndeleted([]string{messageID}); err != nil {
|
if err := targetMailbox.MarkMessagesUndeleted([]string{messageID}); err != nil {
|
||||||
log.WithError(err).Error("Failed to undelete re-imported message")
|
log.WithError(err).Error("Failed to undelete re-imported message")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -198,3 +198,23 @@ Feature: IMAP import messages
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
Then IMAP response is "OK \[APPENDUID \d 1\] APPEND completed"
|
Then IMAP response is "OK \[APPENDUID \d 1\] APPEND completed"
|
||||||
|
|
||||||
|
Scenario: Import message to All Mail
|
||||||
|
When IMAP client imports message to "All Mail"
|
||||||
|
"""
|
||||||
|
From: Foo <from1@pm.me>
|
||||||
|
To: Bridge Test <to1@pm.me>
|
||||||
|
Subject: subj1
|
||||||
|
Received: by 2002:0:0:0:0:0:0:0 with SMTP id 0123456789abcdef; Wed, 30 Dec 2020 01:23:45 0000
|
||||||
|
|
||||||
|
body1
|
||||||
|
"""
|
||||||
|
Then IMAP response is "OK \[APPENDUID \d 1\] APPEND completed"
|
||||||
|
Then mailbox "Archive" for "user" has messages
|
||||||
|
| from | to | subject | body
|
||||||
|
| from1@pm.me | to1@pm.me | subj1 | body1
|
||||||
|
And API mailbox "Archive" for "user" has 1 message
|
||||||
|
And mailbox "All Mail" for "user" has messages
|
||||||
|
| from | to | subject | body
|
||||||
|
| from1@pm.me | to1@pm.me | subj1 | body1
|
||||||
|
And API mailbox "All Mail" for "user" has 1 message
|
||||||
|
|||||||
Reference in New Issue
Block a user