fix(GODT-2782): Filter all labels when doing perma delete check

Previously we were not filtering out labels we ignored from the
perma-delete check. The introduction of new system label types could
break this check leading to user never being able to perma-delete
messages.
This commit is contained in:
Leander Beernaert
2023-07-11 10:42:20 +02:00
parent 80194ad797
commit efb6ba0f1b

View File

@ -424,33 +424,67 @@ func (conn *imapConnector) RemoveMessagesFromMailbox(ctx context.Context, messag
}
if mailboxID == proton.TrashLabel || mailboxID == proton.DraftsLabel {
var metadata []proton.MessageMetadata
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) {
m, err := conn.client.GetMessageMetadata(ctx, proton.MessageFilter{
metadata, err := conn.client.GetMessageMetadata(ctx, proton.MessageFilter{
ID: 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.
m = xslices.Filter(m, func(m proton.MessageMetadata) bool {
labelsThatMatter := xslices.Filter(m.LabelIDs, func(id string) bool {
return id != proton.AllDraftsLabel && id != proton.AllMailLabel && id != proton.AllSentLabel
})
return len(labelsThatMatter) == 0
})
msgIds, err := safe.LockRetErr(func() ([]string, error) {
var msgIds []string
metadata = append(metadata, m...)
// 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...)
}
if err := conn.client.DeleteMessage(ctx, xslices.Map(metadata, func(m proton.MessageMetadata) string {
return m.ID
})...); err != nil {
logrus.Debugf("Following message(s) will be perma-deleted: %v", msgToPermaDelete)
if err := conn.client.DeleteMessage(ctx, msgToPermaDelete...); err != nil {
return err
}
}