added JMAP (not tested yet)

This commit is contained in:
2026-08-22 15:03:32 +01:00
parent 123e58a6b0
commit c34c876c99
9 changed files with 408 additions and 23 deletions
+10 -9
View File
@@ -52,7 +52,7 @@ func (r *Relay) processQueueItem(item db.RelayQueueItem) {
for i, rec := range item.Recipients {
rcpts[i] = rec.Recipient
}
status, serverResp, errCode, errMsg := r.deliverToDomain(item.Domain, item.MailFrom, rcpts, item.Content)
status, serverResp, errCode, errMsg, permanent := r.deliverToDomain(item.Domain, item.MailFrom, rcpts, item.Content)
if status == "success" {
for _, rec := range item.Recipients {
@@ -67,7 +67,7 @@ func (r *Relay) processQueueItem(item db.RelayQueueItem) {
return
}
if item.Attempts < len(retrySchedule) {
if !permanent && item.Attempts < len(retrySchedule) {
next := time.Now().Add(retrySchedule[item.Attempts])
if err := r.DB.RescheduleRelayQueueItem(item.ID, next, errMsg); err != nil {
r.Logger.Error("relay queue: reschedule item %d: %v", item.ID, err)
@@ -75,13 +75,14 @@ func (r *Relay) processQueueItem(item db.RelayQueueItem) {
return
}
// Retries exhausted — final failure. Resolve the recipient rows, drop the queue
// row, and bounce back to the original sender (skipped for a null sender, the
// same rule Session.Data's own immediate-bounce path already follows — replying
// to a bounce is the classic loop bug). Unlike that synchronous path, there's no
// live peer connection here to gate the bounce on IsIPBlacklisted — by the time
// retries are exhausted (minutes to hours later), this is no longer a live
// mailbox-enumeration oracle the way an instant response would be.
// Retries exhausted, or the remote server gave a permanent (RFC 5321 5xx) rejection
// on the very first attempt — either way this is final. Resolve the recipient rows,
// drop the queue row, and bounce back to the original sender (skipped for a null
// sender, the same rule Session.Data's own immediate-bounce path already follows —
// replying to a bounce is the classic loop bug). Unlike that synchronous path,
// there's no live peer connection here to gate the bounce on IsIPBlacklisted — by
// the time this runs, this is no longer a live mailbox-enumeration oracle the way an
// instant response would be.
var failedResults []Result
for _, rec := range item.Recipients {
if err := r.DB.UpdateEmailRecipientLogStatus(item.EmailLogID, rec.Recipient, "failed", errCode, errMsg, serverResp); err != nil {