Compare commits

...

2 Commits

Author SHA1 Message Date
c05dfb36d3 chore: Stone Bridge 3.3.2 changelog. 2023-07-11 17:02:38 +02:00
7997ad2b93 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.
2023-07-11 15:17:25 +02:00
3 changed files with 56 additions and 18 deletions

View File

@ -3,9 +3,13 @@
Changelog [format](http://keepachangelog.com/en/1.0.0/)
## Stone Bridge 3.3.1
## Stone Bridge 3.3.2
### Added
### Fixed
* GODT-2782: Filter all labels when doing perma delete check.
## Stone Bridge 3.3.1
### Changed
* GODT-2707: Set bridge-gui default log level to 'debug'.

View File

@ -11,7 +11,7 @@ ROOT_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
.PHONY: build build-gui build-nogui build-launcher versioner hasher
# Keep version hardcoded so app build works also without Git repository.
BRIDGE_APP_VERSION?=3.3.1+git
BRIDGE_APP_VERSION?=3.3.2+git
APP_VERSION:=${BRIDGE_APP_VERSION}
APP_FULL_NAME:=Proton Mail Bridge
APP_VENDOR:=Proton AG

View File

@ -418,33 +418,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
}
}