Skip to content

Commit

Permalink
fix(mail): unsubscribe from all subfolders when deleting parent
Browse files Browse the repository at this point in the history
Fixes #5218
  • Loading branch information
cgx committed Mar 16, 2021
1 parent 1914a35 commit cb6de75
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 14 deletions.
4 changes: 3 additions & 1 deletion SoObjects/Mailer/SOGoMailFolder.h
@@ -1,5 +1,5 @@
/*
Copyright (C) 2009-2014 Inverse inc.
Copyright (C) 2009-2021 Inverse inc.
Copyright (C) 2004-2005 SKYRIX Software AG
This file is part of SOGo
Expand Down Expand Up @@ -91,6 +91,8 @@

- (BOOL) ensureTrashFolder;

- (NSException *) unsubscribe;

- (NSException *) expunge;

- (NSException *) renameTo: (NSString *) newName;
Expand Down
16 changes: 15 additions & 1 deletion SoObjects/Mailer/SOGoMailFolder.m
@@ -1,5 +1,5 @@
/*
Copyright (C) 2009-2019 Inverse inc.
Copyright (C) 2009-2021 Inverse inc.
Copyright (C) 2004-2005 SKYRIX Software AG
This file is part of SOGo.
Expand Down Expand Up @@ -1221,6 +1221,20 @@ - (NSException *) delete
return error;
}

- (NSException *) unsubscribe
{
NSException *error = nil;

if ([self imap4Connection])
[[imap4 client] unsubscribe: [[self imap4URL] path]];
else
error = [NSException exceptionWithName: @"SOGoMailException"
reason: @"IMAP connection is invalid"
userInfo: nil];

return error;
}

- (NSException *) davMoveToTargetObject: (id) _target
newName: (NSString *) _name
inContext: (id)_ctx
Expand Down
50 changes: 39 additions & 11 deletions UI/MailerUI/UIxMailFolderActions.m
Expand Up @@ -298,8 +298,7 @@ - (NSURL *) _trashedURLOfFolder: (NSURL *) srcURL

connection = [co imap4Connection];
folderName = [[srcURL path] lastPathComponent];
trashFolderName
= [[co mailAccountFolder] trashFolderNameInContext: context];
trashFolderName = [[co mailAccountFolder] trashFolderNameInContext: context];
path = [NSString stringWithFormat: @"/%@/%@",
trashFolderName, folderName];
testPath = path;
Expand All @@ -326,17 +325,15 @@ - (NSURL *) _trashedURLOfFolder: (NSURL *) srcURL
return destURL;
}

- (void) _removeFolder
- (void) _removeFolderAtURL: (NSURL *) srcURL
{
NGImap4Connection *connection;
NSMutableDictionary *moduleSettings, *threadsCollapsed;;
NSString *keyForMsgUIDs, *currentMailbox, *currentAccount;
NSURL *srcURL;
SOGoMailFolder *co;
SOGoUserSettings *us;

co = [self clientObject];
srcURL = [co imap4URL];
connection = [co imap4Connection];

// Unsubscribe from mailbox
Expand All @@ -346,7 +343,6 @@ - (void) _removeFolder
us = [[context activeUser] userSettings];
moduleSettings = [us objectForKey: @"Mail"];
threadsCollapsed = [moduleSettings objectForKey: @"threadsCollapsed"];

if (threadsCollapsed)
{
currentMailbox = [co nameInContainer];
Expand All @@ -363,26 +359,30 @@ - (void) _removeFolder
- (WOResponse *) deleteAction
{
NSDictionary *jsonRequest, *jsonResponse;
NSEnumerator *subURLs;
NGImap4Connection *connection;
SOGoMailFolder *co, *inbox;
NSURL *srcURL, *destURL;
NSURL *srcURL, *destURL, *currentURL;
WORequest *request;
WOResponse *response;
NSException *error;
NSInteger count;
BOOL moved, withTrash;

request = [context request];
co = [self clientObject];
connection = [co imap4Connection];
srcURL = [co imap4URL];
subURLs = [[co allFolderURLs] objectEnumerator];
jsonRequest = [[request contentAsString] objectFromJSONString];
withTrash = ![[jsonRequest objectForKey: @"withoutTrash"] boolValue];
error = nil;
moved = YES;

if (withTrash)
{
if ([co ensureTrashFolder])
{
connection = [co imap4Connection];
destURL = [self _trashedURLOfFolder: srcURL withObject: co];
inbox = [[co mailAccountFolder] inboxFolderInContext: context];
[[connection client] select: [inbox absoluteImap4Name]];
Expand All @@ -397,7 +397,9 @@ - (WOResponse *) deleteAction
moved = NO;
}
else
error = [connection moveMailboxAtURL: srcURL toURL: destURL];
{
error = [connection moveMailboxAtURL: srcURL toURL: destURL];
}
if (error)
{
jsonResponse = [NSDictionary dictionaryWithObject: [self labelForKey: @"Unable to move/delete folder." inContext: context]
Expand All @@ -407,9 +409,30 @@ - (WOResponse *) deleteAction
else
{
// We unsubscribe to the old one, and subscribe back to the new one
[self _removeFolderAtURL: srcURL];
if (moved)
[[connection client] subscribe: [destURL path]];
[self _removeFolder];

// We do the same for all subfolders
count = [[srcURL pathComponents] count];
while (!error && (currentURL = [subURLs nextObject]))
{
[self _removeFolderAtURL: currentURL];
if (moved)
{
NSArray *currentComponents;
NSMutableArray *destComponents;
NSInteger currentCount;

destComponents = [NSMutableArray arrayWithArray: [destURL pathComponents]];
[destComponents removeObjectAtIndex: 0]; // remove leading forward slash
currentCount = [[currentURL pathComponents] count];
currentComponents = [[currentURL pathComponents] subarrayWithRange: NSMakeRange(count, currentCount - count)];
[destComponents addObjectsFromArray: currentComponents];

[[connection client] subscribe: [NSString stringWithFormat: @"/%@", [destComponents componentsJoinedByString: @"/"]]];
}
}
response = [self responseWith204];
}
}
Expand All @@ -433,7 +456,12 @@ - (WOResponse *) deleteAction
}
else
{
[self _removeFolder];
// Cleanup all references to mailbox and submailboxes
[self _removeFolderAtURL: srcURL];
while (!error && (currentURL = [subURLs nextObject]))
{
[self _removeFolderAtURL: currentURL];
}
response = [self responseWith204];
}
}
Expand Down
5 changes: 4 additions & 1 deletion UI/MailerUI/UIxMailListActions.m
Expand Up @@ -655,7 +655,10 @@ - (NSDictionary *) getUIDsInFolder: (SOGoMailFolder *) folder
// Retrieve messages UIDs using form parameters "sort" and "asc"
uids = [self getSortedUIDsInFolder: folder];
if (uids == nil)
return nil;
{
[folder unsubscribe]; // Mailbox is possibly missing -- cleanup subscriptions
return nil;
}

// Get rid of the extra parenthesis
// uids = [[[[uids stringValue] stringByReplacingOccurrencesOfString:@"(" withString:@""] stringByReplacingOccurrencesOfString:@")" withString:@""] componentsSeparatedByString:@","];
Expand Down

0 comments on commit cb6de75

Please sign in to comment.