Reviewed source export adds verified TLS mail, encrypted outbox, mailbox verification and password reset protocols. Preserve public ancestry; omit local development history and operational queue. Consumer deployment and inbox delivery proof remain separate.
2.8 KiB
Encrypted transactional outbox
mailsqlite.Queue stores a single-recipient mail.Message as authenticated
AES-256-GCM ciphertext. Use a separate 32-byte application-managed secret, kept
out of source control and logs; back it up separately. It may be wrapped in SQLite
only if the wrapping key stays outside the database and is backed up separately.
Identity and expiry
are bound to the ciphertext. Key-derived HMACs support idempotency without storing
plaintext message hashes. Losing the key loses pending message contents.
Call CreateSchema inside the application's explicit, versioned migration.
EnqueueTx joins a caller-owned transaction, allowing account changes, audit and
mail intent to commit or roll back together. Enqueue is a convenience for a
standalone transaction. A message ID belongs to exactly one message/expiry, even
after its payload is cleared. Do not use the queue to authorize recipients.
ProcessOne commits a one-minute claim before calling the transport; it never
holds a database writer lock over SMTP. Transports must honor the supplied
deadline (at most 30 seconds). A stale worker cannot acknowledge a newer lease.
Retryable failures back off for 1, 2, 4 and 8 minutes, up to five attempts, only
while the message is valid. Application workers own scheduling and shutdown.
An incorrect key or corrupt payload never reaches SMTP. Such work retains its ciphertext and retries decoding after five minutes without consuming a delivery attempt. Restoring the correct key before expiry can recover pending messages. This is not transparent key rotation: drain the old queue or provide an explicit migration before changing keys.
Payloads expire within 24 hours and are cleared after terminal delivery results
or expiry. Run Sweep periodically even when sending is disabled; each call is
bounded to 100 records. Pending capacity defaults to 1,000 (maximum 10,000).
Safe metadata/deduplication tombstones remain; applications own any later bounded
retention policy and must not reuse purged IDs. Never expose Recent publicly.
SMTP acceptance is not inbox delivery. A crash or lost acknowledgement can cause a retry after the remote server accepted DATA. Stable Message-ID helps diagnose duplicates but cannot make SMTP exactly-once. Do not use this queue for payments or another external operation requiring an exactly-once commitment.
Local Go/race/vet tests cover encryption and identity binding, domain rollback, idempotency, concurrent capacity/claims, lock-free network waits, stale workers, cancelled acknowledgements, retry bounds, safe diagnostics, expiry and wrong-key recovery. No real SMTP credential, provider delivery or consumer deployment is claimed here. Account verification/reset protocols are a separate optional layer, not behavior inferred by the queue.