diff --git a/lib/Providers/Mail/Service.php b/lib/Providers/Mail/Service.php index 2bbb900..028f8c5 100644 --- a/lib/Providers/Mail/Service.php +++ b/lib/Providers/Mail/Service.php @@ -484,17 +484,34 @@ class Service implements ServiceBaseInterface, ServiceMutableInterface, ServiceC } } - // we need to determine if the folder being deleted is already in the trash - if (str_starts_with((string) $target->collection(), (string) $deleteTargetIdentifier?->collection())) { - // if so, we should hard delete instead of moving to avoid duplicates in the trash - $deleteMode = 'hard'; + if ($deleteMode === 'soft') { + $targetMailbox = $this->mailService->collectionFetch((string) $target->collection()); + if ($targetMailbox === null) { + throw new \RuntimeException('Collection not found for delete operation'); + } + + $targetIdentifier = (string) $target->collection(); + $trashIdentifier = (string) $deleteTargetIdentifier->collection(); + $parentIdentifier = isset($targetMailbox['parentId']) + ? (string) $targetMailbox['parentId'] + : null; + + // JMAP mailbox IDs are opaque, so containment must be determined + // from parentId rather than by comparing ID prefixes. + if ($targetIdentifier === $trashIdentifier || $parentIdentifier === $trashIdentifier) { + $deleteMode = 'hard'; + } } - $result = match ($deleteMode) { - 'soft' => $this->collectionMove($deleteTargetIdentifier, $target), - 'hard' => $this->mailService->collectionDestroy($target->collection(), $force), - }; - return $result; + if ($deleteMode === 'soft') { + return $this->collectionMove($deleteTargetIdentifier, $target); + } + + if ($this->mailService->collectionDestroy((string) $target->collection(), $force) === null) { + throw new \RuntimeException("Failed to delete collection: {$target->collection()}"); + } + + return true; } public function collectionMove(CollectionIdentifier $target, CollectionIdentifier $source): CollectionBaseInterface