| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- package service
- import (
- "encoding/json"
- "strings"
- )
- // NotifyEmailEntry represents a notification email with enable/disable and verification state.
- // All emails are user-managed; maximum 3 entries per user.
- type NotifyEmailEntry struct {
- Email string `json:"email"`
- Disabled bool `json:"disabled"`
- Verified bool `json:"verified"`
- }
- // parseNotifyEmails parses a JSON string into []NotifyEmailEntry.
- // It auto-detects the format:
- // - Old format ["email1","email2"] → converted to [{email, disabled:false, verified:true}, ...]
- // - New format [{email,disabled,verified}, ...] → parsed directly
- //
- // Returns nil on empty/invalid input.
- func ParseNotifyEmails(raw string) []NotifyEmailEntry {
- raw = strings.TrimSpace(raw)
- if raw == "" || raw == "[]" {
- return nil
- }
- // Try parsing as new format first (array of objects)
- var entries []NotifyEmailEntry
- if err := json.Unmarshal([]byte(raw), &entries); err == nil && len(entries) > 0 {
- // Verify it's actually the new format by checking the first element
- // json.Unmarshal into []NotifyEmailEntry succeeds even for ["string"]
- // because it tries to fit "string" into NotifyEmailEntry and gets zero values.
- // We need to detect old format explicitly.
- if !isOldStringArrayFormat(raw) {
- return entries
- }
- }
- // Try parsing as old format (array of strings)
- var emails []string
- if err := json.Unmarshal([]byte(raw), &emails); err == nil {
- result := make([]NotifyEmailEntry, 0, len(emails))
- for _, e := range emails {
- e = strings.TrimSpace(e)
- if e != "" {
- result = append(result, NotifyEmailEntry{
- Email: e,
- Disabled: false,
- Verified: false, // Old format emails default to unverified
- })
- }
- }
- return result
- }
- return nil
- }
- // isOldStringArrayFormat checks if the JSON is a string array like ["email1","email2"].
- func isOldStringArrayFormat(raw string) bool {
- var arr []json.RawMessage
- if err := json.Unmarshal([]byte(raw), &arr); err != nil || len(arr) == 0 {
- return false
- }
- // Check if first element starts with a quote (string) vs { (object)
- first := strings.TrimSpace(string(arr[0]))
- return len(first) > 0 && first[0] == '"'
- }
- // marshalNotifyEmails serializes []NotifyEmailEntry to JSON string.
- func MarshalNotifyEmails(entries []NotifyEmailEntry) string {
- if len(entries) == 0 {
- return "[]"
- }
- data, err := json.Marshal(entries)
- if err != nil {
- return "[]"
- }
- return string(data)
- }
|