ultisuite-backend/internal/mail/limits/limits.go
R3D347HR4Y 4eadb91a64 Enhance mail API with rate limiting, idempotency, and attachment management
- Added rate limiting for outbound email sends to prevent abuse, implemented in `internal/api/mail/sendguard`.
- Introduced idempotency key support for email sending to avoid duplicate submissions.
- Enhanced attachment handling with new limits and validation in `internal/api/mail/limits`.
- Updated outbox processing to include retry logic and circuit breaker for SMTP failures.
- Improved HTML sanitization for email content to enhance security.
- Added unit tests for new features, ensuring robust functionality and error handling.
- Updated configuration options in `.env.example` for new mail settings.
2026-05-22 17:19:16 +02:00

39 lines
1.4 KiB
Go

package limits
import "errors"
// Default mail body and attachment size limits (bytes unless noted).
const (
MaxBodyFieldBytes = 4 << 20 // 4 MiB per body_text / body_html field
MaxSendRequestBodyBytes = 5 << 20 // 5 MiB JSON send/draft request
MaxAttachmentBytes = 25 << 20 // 25 MiB per attachment file
MaxMultipartUploadBytes = 26 << 20 // 26 MiB multipart form (file + fields)
MaxAttachmentsPerMessage = 50
MaxTotalAttachmentsPerMessageBytes = 100 << 20 // 100 MiB combined per message/draft
)
var (
ErrAttachmentTooLarge = errors.New("attachment too large")
ErrTooManyAttachments = errors.New("too many attachments")
ErrAttachmentsTotalTooLarge = errors.New("attachments total size exceeded")
)
// ValidateAttachmentSize rejects a single attachment larger than MaxAttachmentBytes.
func ValidateAttachmentSize(size int64) error {
if size > MaxAttachmentBytes {
return ErrAttachmentTooLarge
}
return nil
}
// ValidateAttachmentQuota rejects when adding newSize would exceed per-message count or total size limits.
func ValidateAttachmentQuota(existingCount int, existingTotalBytes int64, newSize int64) error {
if existingCount >= MaxAttachmentsPerMessage {
return ErrTooManyAttachments
}
if existingTotalBytes+newSize > MaxTotalAttachmentsPerMessageBytes {
return ErrAttachmentsTotalTooLarge
}
return nil
}