2023-03-06 21:06:15 +00:00
|
|
|
package settings
|
2023-01-25 20:32:26 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
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
|
2023-04-03 19:44:28 +00:00
|
|
|
BlodeuweddPath string
|
2023-05-09 19:16:49 +00:00
|
|
|
FontScaling float64
|
2023-08-17 16:47:15 +00:00
|
|
|
DefaultSaveHistory bool
|
2023-01-25 20:32:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var DefaultGlobalSettings = GlobalSettings{
|
|
|
|
Locale: "en",
|
|
|
|
Theme: "dark",
|
|
|
|
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: "",
|
2023-04-03 19:44:28 +00:00
|
|
|
BlodeuweddPath: "",
|
2023-05-09 19:16:49 +00:00
|
|
|
FontScaling: 1.0, // use the system pixel scaling default
|
2023-08-17 16:47:15 +00:00
|
|
|
DefaultSaveHistory: false,
|
2023-01-25 20:32:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
2023-04-17 19:33:31 +00:00
|
|
|
err := os.MkdirAll(directory, 0700)
|
2023-04-17 19:05:02 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
err = os.WriteFile(path.Join(directory, saltFile), newSalt[:], 0600)
|
2023-01-25 20:32:26 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2023-08-17 16:47:15 +00:00
|
|
|
// note: by giving json.Unmarshal settings we are providing it defacto defaults
|
|
|
|
// from DefaultGlobalSettings
|
2023-01-25 20:32:26 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|