Skip to content

Commit

Permalink
fix: Remove messages for non selected mailboxes with update
Browse files Browse the repository at this point in the history
Fixes a bug where the messages were not removed from mailboxes if
they are not selected by any clients.
  • Loading branch information
LBeernaertProton committed Oct 28, 2022
1 parent c7a38cb commit d8206f6
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 3 deletions.
30 changes: 27 additions & 3 deletions internal/backend/connector_updates.go
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,9 @@ func (user *user) removeMessageFlags(ctx context.Context, tx *ent.Tx, messageID
}

func (user *user) applyMessageDeleted(ctx context.Context, update *imap.MessageDeleted) error {
return user.db.Write(ctx, func(ctx context.Context, tx *ent.Tx) error {
var stateUpdates []state.Update

if err := user.db.Write(ctx, func(ctx context.Context, tx *ent.Tx) error {
if err := db.MarkMessageAsDeletedWithRemoteID(ctx, tx, update.MessageID); err != nil {
return err
}
Expand All @@ -460,8 +462,30 @@ func (user *user) applyMessageDeleted(ctx context.Context, update *imap.MessageD
return err
}

user.queueStateUpdate(state.NewRemoteMessageDeletedStateUpdate(internalMessageID, update.MessageID))
mailboxes, err := db.GetMessageMailboxIDs(ctx, tx.Client(), internalMessageID)
if err != nil {
return err
}

messageIDs := []imap.InternalMessageID{internalMessageID}

for _, mailbox := range mailboxes {
updates, err := state.RemoveMessagesFromMailbox(ctx, tx, mailbox, messageIDs)
if err != nil {
return err
}

stateUpdates = append(stateUpdates, updates...)
}

return nil
})
}); err != nil {
return err
}

for _, update := range stateUpdates {
user.queueStateUpdate(update)
}

return nil
}
46 changes: 46 additions & 0 deletions tests/deleted_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package tests

import (
"testing"
"time"
)

func TestDeleted(t *testing.T) {
Expand Down Expand Up @@ -131,3 +132,48 @@ func TestUIDDeleted(t *testing.T) {
c.S(`A00E OK STATUS`)
})
}

func TestRemoteDeleteOnSelectedMailboxRemoveMessageFromMailbox(t *testing.T) {
runOneToOneTestWithAuth(t, defaultServerOptions(t), func(c *testConnection, s *testSession) {
mailboxID := s.mailboxCreated("user", []string{"mbox1"})
messageID1 := s.messageCreated("user", mailboxID, []byte("To: [email protected]"), time.Now())
s.messageCreated("user", mailboxID, []byte("To: [email protected]"), time.Now())

s.flush("user")

c.C(`A002 STATUS mbox1 (MESSAGES)`)
c.S(`* STATUS "mbox1" (MESSAGES 2)`)
c.S(`A002 OK STATUS`)

c.C("A003 SELECT mbox1").OK("A003")

s.messageDeleted("user", messageID1)
s.flush("user")

c.C(`A002 STATUS mbox1 (MESSAGES)`)
c.S(`* 1 EXPUNGE`)
c.S(`* STATUS "mbox1" (MESSAGES 1)`)
c.S(`A002 OK STATUS`)
})
}

func TestRemoteDeleteOnNonSelectedMailboxRemoveMessageFromMailbox(t *testing.T) {
runOneToOneTestWithAuth(t, defaultServerOptions(t), func(c *testConnection, s *testSession) {
mailboxID := s.mailboxCreated("user", []string{"mbox1"})
messageID1 := s.messageCreated("user", mailboxID, []byte("To: [email protected]"), time.Now())
s.messageCreated("user", mailboxID, []byte("To: [email protected]"), time.Now())

s.flush("user")

c.C(`A002 STATUS mbox1 (MESSAGES)`)
c.S(`* STATUS "mbox1" (MESSAGES 2)`)
c.S(`A002 OK STATUS`)

s.messageDeleted("user", messageID1)
s.flush("user")

c.C(`A002 STATUS mbox1 (MESSAGES)`)
c.S(`* STATUS "mbox1" (MESSAGES 1)`)
c.S(`A002 OK STATUS`)
})
}

0 comments on commit d8206f6

Please sign in to comment.