fix(GODT-2956): Restore old deletion rules
When unlabeling a message from trash we have to check if this message is present in another folder before perma-deleting.
This commit is contained in:
parent
bfe25e3a46
commit
bbe19bf960
|
@ -37,6 +37,7 @@ import (
|
|||
"github.com/ProtonMail/proton-bridge/v3/pkg/message"
|
||||
"github.com/ProtonMail/proton-bridge/v3/pkg/message/parser"
|
||||
"github.com/bradenaw/juniper/stream"
|
||||
"github.com/bradenaw/juniper/xslices"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
@ -334,8 +335,69 @@ func (s *Connector) RemoveMessagesFromMailbox(ctx context.Context, _ connector.I
|
|||
}
|
||||
|
||||
if mboxID == proton.TrashLabel || mboxID == proton.DraftsLabel {
|
||||
if err := s.client.DeleteMessage(ctx, msgIDs...); err != nil {
|
||||
return err
|
||||
const ChunkSize = 150
|
||||
var msgToPermaDelete []string
|
||||
|
||||
rdLabels := s.labels.Read()
|
||||
defer rdLabels.Close()
|
||||
|
||||
// There's currently no limit on how many IDs we can filter on,
|
||||
// but to be nice to API, let's chunk it by 150.
|
||||
for _, messageIDs := range xslices.Chunk(messageIDs, ChunkSize) {
|
||||
metadata, err := s.client.GetMessageMetadataPage(ctx, 0, ChunkSize, proton.MessageFilter{
|
||||
ID: usertypes.MapTo[imap.MessageID, string](messageIDs),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// If a message is not preset in any other label other than AllMail, AllDrafts and AllSent, it can be
|
||||
// permanently deleted.
|
||||
for _, m := range metadata {
|
||||
var remainingLabels []string
|
||||
|
||||
for _, id := range m.LabelIDs {
|
||||
label, ok := rdLabels.GetLabel(id)
|
||||
if !ok {
|
||||
// Handle case where this label was newly introduced and we do not yet know about it.
|
||||
logrus.WithField("labelID", id).Warnf("Unknown label found during expung from Trash, attempting to locate it")
|
||||
label, err = s.client.GetLabel(ctx, id, proton.LabelTypeFolder, proton.LabelTypeSystem, proton.LabelTypeSystem)
|
||||
if err != nil {
|
||||
if errors.Is(err, proton.ErrNoSuchLabel) {
|
||||
logrus.WithField("labelID", id).Warn("Label does not exist, ignoring")
|
||||
continue
|
||||
}
|
||||
|
||||
logrus.WithField("labelID", id).Errorf("Failed to resolve label: %v", err)
|
||||
return fmt.Errorf("failed to resolve label: %w", err)
|
||||
}
|
||||
}
|
||||
if !WantLabel(label) {
|
||||
continue
|
||||
}
|
||||
|
||||
if label.Type == proton.LabelTypeSystem && (id == proton.AllDraftsLabel ||
|
||||
id == proton.AllMailLabel ||
|
||||
id == proton.AllSentLabel ||
|
||||
id == proton.AllScheduledLabel) {
|
||||
continue
|
||||
}
|
||||
|
||||
remainingLabels = append(remainingLabels, m.ID)
|
||||
}
|
||||
|
||||
if len(remainingLabels) == 0 {
|
||||
msgToPermaDelete = append(msgToPermaDelete, m.ID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(msgToPermaDelete) != 0 {
|
||||
logrus.Debugf("Following message(s) will be perma-deleted: %v", msgToPermaDelete)
|
||||
|
||||
if err := s.client.DeleteMessage(ctx, msgToPermaDelete...); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -85,3 +85,18 @@ Feature: IMAP copy messages
|
|||
| from | to | subject | unread |
|
||||
| john.doe@mail.com | [user:user]@[domain] | foo | false |
|
||||
|
||||
Scenario: Move message to trash then copy to folder does not delete message
|
||||
When IMAP client "1" moves the message with subject "foo" from "INBOX" to "Trash"
|
||||
And it succeeds
|
||||
Then IMAP client "1" eventually sees the following messages in "Trash":
|
||||
| from | to | subject | unread |
|
||||
| john.doe@mail.com | [user:user]@[domain] | foo | false |
|
||||
When IMAP client "1" copies the message with subject "foo" from "Trash" to "Folders/mbox"
|
||||
And it succeeds
|
||||
When IMAP client "1" marks the message with subject "foo" as deleted
|
||||
Then it succeeds
|
||||
When IMAP client "1" expunges
|
||||
Then it succeeds
|
||||
Then IMAP client "1" eventually sees the following messages in "Folders/mbox":
|
||||
| from | to | subject | unread |
|
||||
| john.doe@mail.com | [user:user]@[domain] | foo | false |
|
||||
|
|
|
@ -7,7 +7,7 @@ Feature: IMAP remove messages from Trash
|
|||
| label | label |
|
||||
Then it succeeds
|
||||
|
||||
Scenario Outline: Message in Trash and some other label is permanently deleted
|
||||
Scenario Outline: Message in Trash and some other label is not permanently deleted
|
||||
Given the address "[user:user]@[domain]" of account "[user:user]" has the following messages in "Trash":
|
||||
| from | to | subject | body |
|
||||
| john.doe@mail.com | [user:user]@[domain] | foo | hello |
|
||||
|
@ -27,8 +27,8 @@ Feature: IMAP remove messages from Trash
|
|||
When IMAP client "1" expunges
|
||||
Then it succeeds
|
||||
And IMAP client "1" eventually sees 1 messages in "Trash"
|
||||
And IMAP client "1" eventually sees 1 messages in "All Mail"
|
||||
And IMAP client "1" eventually sees 0 messages in "Labels/label"
|
||||
And IMAP client "1" eventually sees 2 messages in "All Mail"
|
||||
And IMAP client "1" eventually sees 1 messages in "Labels/label"
|
||||
|
||||
Scenario Outline: Message in Trash only is permanently deleted
|
||||
Given the address "[user:user]@[domain]" of account "[user:user]" has the following messages in "Trash":
|
||||
|
|
Loading…
Reference in New Issue