feat: implement message deletion functionality and improve draft handling

- Added `MoveToTrash` method in `WebmailRepository` to move messages to the Trash folder instead of deleting them permanently.
- Introduced `handleDelete` method in `mailAPI` to handle message deletion requests from the client.
- Updated router to include a new route for message deletion.
- Enhanced the compose page to manage draft integrity, ensuring drafts are correctly associated with sent messages.
- Implemented UI changes to allow users to delete messages from the mail folder view.
- Added tests to verify the correct behavior of message deletion and draft handling.
- Updated database migration scripts to reconcile folder counters and ensure accurate unread counts.
- Added tests for TLS-RPT report parsing and webmail repository functionalities.
This commit is contained in:
Lucas Rayan committed 2026-08-20 15:32:14 -03:00
1 parent 4f1b9c5217
commit 880dced9e4
20 files changed
+1053 -30

No files matched your search

@@ -22,7 +22,12 @@ type PersistInboundMessageInput struct {
FromDisplayName string
MessageIDHeader string
HasAttachments bool
SPFResult string
// AlreadySeen marks a copy the user themselves composed - their own Sent
// copy, or a draft. It is not unread mail, and counting it as such is why
// the Sent folder carried an unread badge that nothing could clear: no
// reader ever opens their own outgoing copy, so the flag was never set.
AlreadySeen bool
SPFResult string
DKIMResult string
DMARCResult string
}
@@ -2,6 +2,7 @@ package port
import (
"context"
"errors"
"time"
"github.com/google/uuid"
@@ -63,4 +64,16 @@ type WebmailRepository interface {
MarkSeen(ctx context.Context, mailboxID, folderName string, uid uint32, seen bool) error
// Expunge soft-deletes one message, keeping the folder counters in step.
Expunge(ctx context.Context, mailboxID, folderName string, uid uint32) error
// MoveToTrash relocates one message into Trash and returns its new UID
// there. This is what deleting a message means everywhere but in Trash
// itself, where Expunge is the operation instead.
MoveToTrash(ctx context.Context, mailboxID, folderName string, uid uint32) (uint32, error)
}
// ErrNoTrashFolder reports a mailbox with nowhere to put deleted mail, rather
// than the message being destroyed instead.
var ErrNoTrashFolder = errors.New("webmail: this mailbox has no Trash folder")
// ErrAlreadyInTrash tells the caller to expunge rather than move: a message
// already in Trash has no further destination.
var ErrAlreadyInTrash = errors.New("webmail: message is already in Trash")