fix(mail): unsubscribe from all subfolders when deleting parent

Fixes #5218
pull/296/head
Francis Lachapelle 2021-03-16 11:50:05 -04:00
parent 1914a3516a
commit cb6de75845
4 changed files with 61 additions and 14 deletions

View File

@ -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
@ -91,6 +91,8 @@
- (BOOL) ensureTrashFolder;
- (NSException *) unsubscribe;
- (NSException *) expunge;
- (NSException *) renameTo: (NSString *) newName;

View File

@ -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.
@ -1221,6 +1221,20 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
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

View File

@ -298,8 +298,7 @@
connection = [co imap4Connection];
folderName = [[srcURL path] lastPathComponent];
trashFolderName
= [[co mailAccountFolder] trashFolderNameInContext: context];
trashFolderName = [[co mailAccountFolder] trashFolderNameInContext: context];
path = [NSString stringWithFormat: @"/%@/%@",
trashFolderName, folderName];
testPath = path;
@ -326,17 +325,15 @@
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
@ -346,7 +343,6 @@
us = [[context activeUser] userSettings];
moduleSettings = [us objectForKey: @"Mail"];
threadsCollapsed = [moduleSettings objectForKey: @"threadsCollapsed"];
if (threadsCollapsed)
{
currentMailbox = [co nameInContainer];
@ -363,26 +359,30 @@
- (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]];
@ -397,7 +397,9 @@
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]
@ -407,9 +409,30 @@
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];
}
}
@ -433,7 +456,12 @@
}
else
{
[self _removeFolder];
// Cleanup all references to mailbox and submailboxes
[self _removeFolderAtURL: srcURL];
while (!error && (currentURL = [subURLs nextObject]))
{
[self _removeFolderAtURL: currentURL];
}
response = [self responseWith204];
}
}

View File

@ -655,7 +655,10 @@
// 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:@","];