diff --git a/internal/user/imap.go b/internal/user/imap.go index 018d9194..e3e2b7a5 100644 --- a/internal/user/imap.go +++ b/internal/user/imap.go @@ -419,72 +419,13 @@ func (conn *imapConnector) RemoveMessagesFromMailbox(ctx context.Context, messag return connector.ErrOperationNotAllowed } - if err := conn.client.UnlabelMessages(ctx, mapTo[imap.MessageID, string](messageIDs), string(mailboxID)); err != nil { + msgIDs := mapTo[imap.MessageID, string](messageIDs) + if err := conn.client.UnlabelMessages(ctx, msgIDs, string(mailboxID)); err != nil { return err } if mailboxID == proton.TrashLabel || mailboxID == proton.DraftsLabel { - var msgToPermaDelete []string - // 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, 150) { - metadata, err := conn.client.GetMessageMetadata(ctx, proton.MessageFilter{ - ID: mapTo[imap.MessageID, string](messageIDs), - }) - if err != nil { - return err - } - - msgIds, err := safe.LockRetErr(func() ([]string, error) { - var msgIds []string - - // 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 := conn.apiLabels[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 = conn.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 nil, fmt.Errorf("failed to resolve label: %w", err) - } - } - if !wantLabel(label) { - continue - } - - if id != proton.AllDraftsLabel && id != proton.AllMailLabel && id != proton.AllSentLabel { - remainingLabels = append(remainingLabels, m.ID) - } - } - - if len(remainingLabels) == 0 { - msgIds = append(msgIds, m.ID) - } - } - - return msgIds, nil - }, conn.User.apiLabelsLock) - if err != nil { - return err - } - - msgToPermaDelete = append(msgToPermaDelete, msgIds...) - } - - logrus.Debugf("Following message(s) will be perma-deleted: %v", msgToPermaDelete) - - if err := conn.client.DeleteMessage(ctx, msgToPermaDelete...); err != nil { + if err := conn.client.DeleteMessage(ctx, msgIDs...); err != nil { return err } } diff --git a/tests/features/imap/message/delete_from_trash.feature b/tests/features/imap/message/delete_from_trash.feature index 15446eed..a8323e91 100644 --- a/tests/features/imap/message/delete_from_trash.feature +++ b/tests/features/imap/message/delete_from_trash.feature @@ -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 not permanently deleted + Scenario Outline: Message in Trash and some other label is 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 2 messages in "All Mail" - And IMAP client "1" eventually sees 1 messages in "Labels/label" + And IMAP client "1" eventually sees 1 messages in "All Mail" + And IMAP client "1" eventually sees 0 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":