package mail import ( "encoding/json" "strconv" "strings" "github.com/ultisuite/ulti-backend/internal/api/apivalidate" "github.com/ultisuite/ulti-backend/internal/mail/limits" ) type draftRequest struct { AccountID string `json:"account_id"` IdentityID string `json:"identity_id"` To []string `json:"to"` Cc []string `json:"cc"` Bcc []string `json:"bcc"` Subject string `json:"subject"` BodyText string `json:"body_text"` BodyHTML string `json:"body_html"` InReplyTo string `json:"in_reply_to"` Attachments any `json:"attachments"` } func validateDraftRecipients(req *draftRequest) []apivalidate.FieldDetail { var details []apivalidate.FieldDetail for i, addr := range req.To { if d := validateRecipient(addr); d != nil { d.Field = "to[" + strconv.Itoa(i) + "]" details = append(details, *d) } } for i, addr := range req.Cc { if d := validateRecipient(addr); d != nil { d.Field = "cc[" + strconv.Itoa(i) + "]" details = append(details, *d) } } for i, addr := range req.Bcc { if d := validateRecipient(addr); d != nil { d.Field = "bcc[" + strconv.Itoa(i) + "]" details = append(details, *d) } } return details } func validateDraftContent(req *draftRequest) []apivalidate.FieldDetail { var details []apivalidate.FieldDetail if len(req.Subject) > maxSubjectLen { details = append(details, apivalidate.FieldDetail{Field: "subject", Message: "too long"}) } if len(req.BodyText) > limits.MaxBodyFieldBytes { details = append(details, apivalidate.FieldDetail{Field: "body_text", Message: "too long"}) } if len(req.BodyHTML) > limits.MaxBodyFieldBytes { details = append(details, apivalidate.FieldDetail{Field: "body_html", Message: "too long"}) } if req.InReplyTo != "" && len(req.InReplyTo) > 998 { details = append(details, apivalidate.FieldDetail{Field: "in_reply_to", Message: "too long"}) } if req.Attachments != nil { if b, err := json.Marshal(req.Attachments); err != nil { details = append(details, apivalidate.FieldDetail{Field: "attachments", Message: "invalid"}) } else if len(b) > limits.MaxSendRequestBodyBytes { details = append(details, apivalidate.FieldDetail{Field: "attachments", Message: "too large"}) } } return details } func validateCreateDraft(req *draftRequest) *apivalidate.ValidationError { var details []apivalidate.FieldDetail if strings.TrimSpace(req.AccountID) == "" { details = append(details, apivalidate.FieldDetail{Field: "account_id", Message: "required"}) } details = append(details, validateDraftRecipients(req)...) details = append(details, validateDraftContent(req)...) if len(details) == 0 { return nil } return apivalidate.NewValidationError(details...) } func validateUpdateDraft(req *draftRequest) *apivalidate.ValidationError { var details []apivalidate.FieldDetail details = append(details, validateDraftRecipients(req)...) details = append(details, validateDraftContent(req)...) if len(details) == 0 { return nil } return apivalidate.NewValidationError(details...) }