160 lines
4.6 KiB
Go
160 lines
4.6 KiB
Go
package mail
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/ultisuite/ulti-backend/internal/api/apivalidate"
|
|
)
|
|
|
|
const maxSettingsRequestBody = 4 << 10 // 4 KiB
|
|
|
|
var (
|
|
allowedDensities = map[string]struct{}{
|
|
"default": {},
|
|
"normal": {},
|
|
"compact": {},
|
|
}
|
|
allowedThemeModes = map[string]struct{}{
|
|
"light": {},
|
|
"dark": {},
|
|
"system": {},
|
|
}
|
|
allowedBackgroundIDs = map[string]struct{}{
|
|
"none": {},
|
|
"gradient-aurora": {},
|
|
"gradient-sunset": {},
|
|
"gradient-ocean": {},
|
|
"gradient-blossom": {},
|
|
"photo-mountains": {},
|
|
"photo-ocean": {},
|
|
"photo-city": {},
|
|
"photo-nature": {},
|
|
}
|
|
allowedInboxSorts = map[string]struct{}{
|
|
"default": {},
|
|
"important": {},
|
|
"unread": {},
|
|
"starred": {},
|
|
}
|
|
allowedReadingPanes = map[string]struct{}{
|
|
"none": {},
|
|
"right": {},
|
|
"below": {},
|
|
}
|
|
)
|
|
|
|
type MailNotificationSettings struct {
|
|
DesktopNewMail bool `json:"desktop_new_mail"`
|
|
DesktopMentions bool `json:"desktop_mentions"`
|
|
EmailDigest bool `json:"email_digest"`
|
|
SoundEnabled bool `json:"sound_enabled"`
|
|
}
|
|
|
|
type MailSettings struct {
|
|
Density string `json:"density"`
|
|
ThemeMode string `json:"theme_mode"`
|
|
BackgroundID string `json:"background_id"`
|
|
InboxSort string `json:"inbox_sort"`
|
|
ReadingPane string `json:"reading_pane"`
|
|
ConversationMode bool `json:"conversation_mode"`
|
|
Notifications MailNotificationSettings `json:"notifications"`
|
|
UpdatedAt any `json:"updated_at,omitempty"`
|
|
}
|
|
|
|
type patchMailNotificationSettings struct {
|
|
DesktopNewMail *bool `json:"desktop_new_mail"`
|
|
DesktopMentions *bool `json:"desktop_mentions"`
|
|
EmailDigest *bool `json:"email_digest"`
|
|
SoundEnabled *bool `json:"sound_enabled"`
|
|
}
|
|
|
|
type patchMailSettingsRequest struct {
|
|
Density *string `json:"density"`
|
|
ThemeMode *string `json:"theme_mode"`
|
|
BackgroundID *string `json:"background_id"`
|
|
InboxSort *string `json:"inbox_sort"`
|
|
ReadingPane *string `json:"reading_pane"`
|
|
ConversationMode *bool `json:"conversation_mode"`
|
|
Notifications *patchMailNotificationSettings `json:"notifications"`
|
|
}
|
|
|
|
func defaultMailNotificationSettings() MailNotificationSettings {
|
|
return MailNotificationSettings{
|
|
DesktopNewMail: true,
|
|
DesktopMentions: true,
|
|
EmailDigest: false,
|
|
SoundEnabled: false,
|
|
}
|
|
}
|
|
|
|
func defaultMailSettings() MailSettings {
|
|
return MailSettings{
|
|
Density: "default",
|
|
ThemeMode: "system",
|
|
BackgroundID: "none",
|
|
InboxSort: "default",
|
|
ReadingPane: "none",
|
|
ConversationMode: true,
|
|
Notifications: defaultMailNotificationSettings(),
|
|
}
|
|
}
|
|
|
|
func validateEnum(field, value string, allowed map[string]struct{}) *apivalidate.FieldDetail {
|
|
value = strings.TrimSpace(strings.ToLower(value))
|
|
if value == "" {
|
|
return &apivalidate.FieldDetail{Field: field, Message: "required"}
|
|
}
|
|
if _, ok := allowed[value]; !ok {
|
|
return &apivalidate.FieldDetail{Field: field, Message: "invalid"}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func validatePatchMailSettings(req *patchMailSettingsRequest) *apivalidate.ValidationError {
|
|
if req == nil {
|
|
return apivalidate.NewValidationError(apivalidate.FieldDetail{Field: "body", Message: "required"})
|
|
}
|
|
|
|
hasField := req.Density != nil ||
|
|
req.ThemeMode != nil ||
|
|
req.BackgroundID != nil ||
|
|
req.InboxSort != nil ||
|
|
req.ReadingPane != nil ||
|
|
req.ConversationMode != nil ||
|
|
req.Notifications != nil
|
|
if !hasField {
|
|
return apivalidate.NewValidationError(apivalidate.FieldDetail{Field: "body", Message: "at least one field required"})
|
|
}
|
|
|
|
var details []apivalidate.FieldDetail
|
|
if req.Density != nil {
|
|
if d := validateEnum("density", *req.Density, allowedDensities); d != nil {
|
|
details = append(details, *d)
|
|
}
|
|
}
|
|
if req.ThemeMode != nil {
|
|
if d := validateEnum("theme_mode", *req.ThemeMode, allowedThemeModes); d != nil {
|
|
details = append(details, *d)
|
|
}
|
|
}
|
|
if req.BackgroundID != nil {
|
|
if d := validateEnum("background_id", *req.BackgroundID, allowedBackgroundIDs); d != nil {
|
|
details = append(details, *d)
|
|
}
|
|
}
|
|
if req.InboxSort != nil {
|
|
if d := validateEnum("inbox_sort", *req.InboxSort, allowedInboxSorts); d != nil {
|
|
details = append(details, *d)
|
|
}
|
|
}
|
|
if req.ReadingPane != nil {
|
|
if d := validateEnum("reading_pane", *req.ReadingPane, allowedReadingPanes); d != nil {
|
|
details = append(details, *d)
|
|
}
|
|
}
|
|
if len(details) == 0 {
|
|
return nil
|
|
}
|
|
return apivalidate.NewValidationError(details...)
|
|
}
|