package config import ( "encoding/json" "log" "os" "sync" ) // Config holds SyncWarden configuration. type Config struct { // Connection SyncthingAddress string `json:"syncthing_address"` SyncthingAPIKey string `json:"syncthing_api_key"` SyncthingUseTLS bool `json:"syncthing_use_tls"` SyncthingInsecureTLS bool `json:"syncthing_insecure_tls"` // Feature toggles EnableNotifications bool `json:"enable_notifications"` EnableRecentFiles bool `json:"enable_recent_files"` EnableConflictAlerts bool `json:"enable_conflict_alerts"` EnableTransferRate bool `json:"enable_transfer_rate"` AutoStartSyncthing bool `json:"auto_start_syncthing"` StartOnLogin bool `json:"start_on_login"` // Per-event notification toggles NotifySyncComplete bool `json:"notify_sync_complete"` NotifyDeviceConnect bool `json:"notify_device_connect"` NotifyDeviceDisconnect bool `json:"notify_device_disconnect"` NotifyNewDevice bool `json:"notify_new_device"` NotifyConflict bool `json:"notify_conflict"` // Persisted state LastEventID int `json:"last_event_id"` } var defaults = Config{ SyncthingAddress: "localhost:8384", SyncthingAPIKey: "", SyncthingUseTLS: false, SyncthingInsecureTLS: true, EnableNotifications: true, EnableRecentFiles: true, EnableConflictAlerts: true, EnableTransferRate: true, AutoStartSyncthing: false, StartOnLogin: false, NotifySyncComplete: true, NotifyDeviceConnect: false, NotifyDeviceDisconnect: true, NotifyNewDevice: true, NotifyConflict: true, LastEventID: 0, } var ( mu sync.Mutex cached *Config ) // Load reads config from disk, merging with defaults. func Load() Config { mu.Lock() defer mu.Unlock() cfg := defaults data, err := os.ReadFile(ConfigPath()) if err != nil { return cfg } if err := json.Unmarshal(data, &cfg); err != nil { log.Printf("config: parse error: %v", err) } cached = &cfg return cfg } // Save writes config to disk. func Save(cfg Config) error { mu.Lock() defer mu.Unlock() dir := configDir() if err := os.MkdirAll(dir, 0o755); err != nil { return err } data, err := json.MarshalIndent(cfg, "", " ") if err != nil { return err } cached = &cfg return os.WriteFile(ConfigPath(), data, 0o644) } // BaseURL returns the full Syncthing base URL. func (c Config) BaseURL() string { scheme := "http" if c.SyncthingUseTLS { scheme = "https" } return scheme + "://" + c.SyncthingAddress }