package settings import ( "cwtch.im/cwtch/event" "cwtch.im/cwtch/model/constants" "cwtch.im/cwtch/storage/v1" "encoding/json" "git.openprivacy.ca/openprivacy/log" "os" path "path/filepath" ) const ( CwtchStarted = event.Type("CwtchStarted") CwtchStartError = event.Type("CwtchStartError") UpdateGlobalSettings = event.Type("UpdateGlobalSettings") ) const GlobalSettingsFilename = "ui.globals" const saltFile = "SALT" type NotificationPolicy string const ( NotificationPolicyMute = NotificationPolicy("NotificationPolicy.Mute") NotificationPolicyOptIn = NotificationPolicy("NotificationPolicy.OptIn") NotificationPolicyDefaultAll = NotificationPolicy("NotificationPolicy.DefaultAll") ) type GlobalSettingsFile struct { v1.FileStore } type GlobalSettings struct { Locale string Theme string ThemeMode string ThemeImages bool PreviousPid int64 ExperimentsEnabled bool Experiments map[string]bool BlockUnknownConnections bool NotificationPolicy NotificationPolicy NotificationContent string StreamerMode bool StateRootPane int FirstTime bool UIColumnModePortrait string UIColumnModeLandscape string DownloadPath string AllowAdvancedTorConfig bool CustomTorrc string UseCustomTorrc bool UseExternalTor bool CustomSocksPort int CustomControlPort int UseTorCache bool TorCacheDir string BlodeuweddPath string FontScaling float64 DefaultSaveHistory bool } var DefaultGlobalSettings = GlobalSettings{ Locale: "en", Theme: "cwtch", ThemeMode: "dark", ThemeImages: false, PreviousPid: -1, ExperimentsEnabled: false, Experiments: map[string]bool{constants.MessageFormattingExperiment: true}, StateRootPane: 0, FirstTime: true, BlockUnknownConnections: false, StreamerMode: false, UIColumnModePortrait: "DualpaneMode.Single", UIColumnModeLandscape: "DualpaneMode.CopyPortrait", NotificationPolicy: "NotificationPolicy.Mute", NotificationContent: "NotificationContent.SimpleEvent", DownloadPath: "", AllowAdvancedTorConfig: false, CustomTorrc: "", UseCustomTorrc: false, CustomSocksPort: -1, CustomControlPort: -1, UseTorCache: false, TorCacheDir: "", BlodeuweddPath: "", FontScaling: 1.0, // use the system pixel scaling default DefaultSaveHistory: false, } func InitGlobalSettingsFile(directory string, password string) (*GlobalSettingsFile, error) { var key [32]byte salt, err := os.ReadFile(path.Join(directory, saltFile)) if err != nil { log.Infof("Could not find salt file: %v (creating a new settings file)", err) var newSalt [128]byte key, newSalt, err = v1.CreateKeySalt(password) if err != nil { log.Errorf("Could not initialize salt: %v", err) return nil, err } err := os.MkdirAll(directory, 0700) if err != nil { return nil, err } err = os.WriteFile(path.Join(directory, saltFile), newSalt[:], 0600) if err != nil { log.Errorf("Could not write salt file: %v", err) return nil, err } } else { key = v1.CreateKey(password, salt) } gsFile := v1.NewFileStore(directory, GlobalSettingsFilename, key) log.Infof("initialized global settings file: %v", gsFile) globalSettingsFile := GlobalSettingsFile{ gsFile, } return &globalSettingsFile, nil } func (globalSettingsFile *GlobalSettingsFile) ReadGlobalSettings() GlobalSettings { settings := DefaultGlobalSettings if globalSettingsFile == nil { log.Errorf("Global Settings File was not Initialized Properly") return settings } settingsBytes, err := globalSettingsFile.Read() if err != nil { log.Infof("Could not read global ui settings: %v (assuming this is a first time app deployment...)", err) return settings //firstTime = true } // note: by giving json.Unmarshal settings we are providing it defacto defaults // from DefaultGlobalSettings err = json.Unmarshal(settingsBytes, &settings) if err != nil { log.Errorf("Could not parse global ui settings: %v\n", err) // TODO if settings is corrupted, we probably want to alert the UI. return settings //firstTime = true } log.Debugf("Settings: %#v", settings) return settings } func (globalSettingsFile *GlobalSettingsFile) WriteGlobalSettings(globalSettings GlobalSettings) { bytes, _ := json.Marshal(globalSettings) // override first time setting globalSettings.FirstTime = true err := globalSettingsFile.Write(bytes) if err != nil { log.Errorf("Could not write global ui settings: %v\n", err) } }