mirror of
https://github.com/karatektus/pl_mail.git
synced 2026-10-25 01:54:10 +00:00
fix(imap): a folder missing from one LIST no longer deletes its mail
MailboxSyncer removed every stored folder the server's LIST did not name, and message.mailbox_id cascades, so an empty or partial LIST, or a rename done in another client, deleted every message of those folders in one poll. Now an empty listing is refused outright, a listing that would leave out most of the stored folders is refused like VanishedMessageReconciler's bulk guard, and a folder that is really gone is only marked (mailbox.missing_since and missing_syncs, new migration) and skipped by the sync loop. It is removed only after three consecutive listings and 24 hours, and its messages go through MessageEraser so JMAP clients get a destroyed change for each. A new folder with the same special use or the same UIDVALIDITY as exactly one missing folder is treated as a rename: the row keeps its mail and takes the new path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
5a19c3bddb
commit
63b236b134
7 files changed
+474
-32
No files matched your search
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* A folder that drops out of the server's LIST is marked, not deleted.
|
||||
*
|
||||
* MailboxSyncer used to remove any mailbox row the listing did not name, and
|
||||
* message.mailbox_id cascades — so one partial or empty LIST, or a rename done
|
||||
* in another client, deleted every message of the folder. The mark and the
|
||||
* counter let the syncer wait for the absence to last before believing it.
|
||||
*/
|
||||
final class Version20260923101100 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Add mailbox.missing_since and mailbox.missing_syncs.';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE mailbox ADD missing_since TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL');
|
||||
$this->addSql('ALTER TABLE mailbox ADD missing_syncs INT DEFAULT 0 NOT NULL');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE mailbox DROP missing_since');
|
||||
$this->addSql('ALTER TABLE mailbox DROP missing_syncs');
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user