- Introduced new functionality for managing email attachments and drafts in the mail API. - Added handlers for listing, uploading, and downloading message attachments in `internal/api/mail/handlers_attachments.go`. - Implemented draft management endpoints for creating, updating, and deleting drafts in `internal/api/mail/handlers_drafts.go`. - Created new service methods for handling draft and attachment operations in `internal/api/mail/drafts.go` and `internal/api/mail/storage.go`. - Added validation and error handling for draft and attachment operations. - Included unit tests for draft and folder functionalities in `internal/api/mail/drafts_test.go` and `internal/api/mail/folders_test.go`. - Updated API routes to support new draft and attachment features, enhancing overall mail management capabilities.
92 lines
2.8 KiB
Go
92 lines
2.8 KiB
Go
package mail
|
|
|
|
import (
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/ultisuite/ulti-backend/internal/api/apivalidate"
|
|
)
|
|
|
|
const (
|
|
maxIdentityRequestBody = 256 << 10 // 256 KiB
|
|
maxIdentityName = 128
|
|
maxSignatureHTML = 64 << 10 // 64 KiB
|
|
maxReplyToAddrs = 10
|
|
)
|
|
|
|
type createIdentityRequest struct {
|
|
Email string `json:"email"`
|
|
Name string `json:"name"`
|
|
IsDefault bool `json:"is_default"`
|
|
SignatureHTML string `json:"signature_html"`
|
|
ReplyToAddrs []string `json:"reply_to_addrs"`
|
|
}
|
|
|
|
type updateIdentityRequest struct {
|
|
Email string `json:"email"`
|
|
Name string `json:"name"`
|
|
IsDefault bool `json:"is_default"`
|
|
SignatureHTML string `json:"signature_html"`
|
|
ReplyToAddrs []string `json:"reply_to_addrs"`
|
|
}
|
|
|
|
func validateReplyToAddrs(field string, addrs []string) []apivalidate.FieldDetail {
|
|
if len(addrs) > maxReplyToAddrs {
|
|
return []apivalidate.FieldDetail{{
|
|
Field: field, Message: "too many entries",
|
|
}}
|
|
}
|
|
var details []apivalidate.FieldDetail
|
|
for i, addr := range addrs {
|
|
if d := validateRecipient(addr); d != nil {
|
|
d.Field = field + "[" + strconv.Itoa(i) + "]"
|
|
details = append(details, *d)
|
|
}
|
|
}
|
|
return details
|
|
}
|
|
|
|
func validateCreateIdentity(req *createIdentityRequest) *apivalidate.ValidationError {
|
|
var details []apivalidate.FieldDetail
|
|
if d := validateEmailField("email", req.Email); d != nil {
|
|
details = append(details, *d)
|
|
}
|
|
if req.Name != "" && len(req.Name) > maxIdentityName {
|
|
details = append(details, apivalidate.FieldDetail{Field: "name", Message: "too long"})
|
|
}
|
|
if len(req.SignatureHTML) > maxSignatureHTML {
|
|
details = append(details, apivalidate.FieldDetail{Field: "signature_html", Message: "too long"})
|
|
}
|
|
if req.ReplyToAddrs == nil {
|
|
req.ReplyToAddrs = []string{}
|
|
}
|
|
details = append(details, validateReplyToAddrs("reply_to_addrs", req.ReplyToAddrs)...)
|
|
if len(details) == 0 {
|
|
return nil
|
|
}
|
|
return apivalidate.NewValidationError(details...)
|
|
}
|
|
|
|
func validateUpdateIdentity(req *updateIdentityRequest) *apivalidate.ValidationError {
|
|
var details []apivalidate.FieldDetail
|
|
if d := validateEmailField("email", req.Email); d != nil {
|
|
details = append(details, *d)
|
|
}
|
|
if strings.TrimSpace(req.Name) == "" {
|
|
details = append(details, apivalidate.FieldDetail{Field: "name", Message: "required"})
|
|
} else if len(req.Name) > maxIdentityName {
|
|
details = append(details, apivalidate.FieldDetail{Field: "name", Message: "too long"})
|
|
}
|
|
if len(req.SignatureHTML) > maxSignatureHTML {
|
|
details = append(details, apivalidate.FieldDetail{Field: "signature_html", Message: "too long"})
|
|
}
|
|
if req.ReplyToAddrs == nil {
|
|
req.ReplyToAddrs = []string{}
|
|
}
|
|
details = append(details, validateReplyToAddrs("reply_to_addrs", req.ReplyToAddrs)...)
|
|
if len(details) == 0 {
|
|
return nil
|
|
}
|
|
return apivalidate.NewValidationError(details...)
|
|
}
|