2021-06-24 22:30:46 +00:00
|
|
|
package utils
|
|
|
|
|
|
|
|
import (
|
2022-01-18 20:53:55 +00:00
|
|
|
path "path/filepath"
|
2021-12-14 21:23:32 +00:00
|
|
|
"sync"
|
|
|
|
|
2021-06-24 22:30:46 +00:00
|
|
|
"cwtch.im/cwtch/event"
|
|
|
|
"cwtch.im/cwtch/storage/v1"
|
|
|
|
|
|
|
|
"encoding/json"
|
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
2021-12-14 21:23:32 +00:00
|
|
|
|
|
|
|
"git.openprivacy.ca/openprivacy/log"
|
2021-06-24 22:30:46 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
CwtchStarted = event.Type("CwtchStarted")
|
|
|
|
CwtchStartError = event.Type("CwtchStartError")
|
|
|
|
UpdateGlobalSettings = event.Type("UpdateGlobalSettings")
|
|
|
|
)
|
|
|
|
|
|
|
|
var GlobalSettingsFile v1.FileStore
|
2021-06-30 20:28:16 +00:00
|
|
|
var lock sync.Mutex
|
2021-06-24 22:30:46 +00:00
|
|
|
|
|
|
|
const GlobalSettingsFilename = "ui.globals"
|
|
|
|
const saltFile = "SALT"
|
|
|
|
|
2022-02-05 00:17:39 +00:00
|
|
|
type NotificationPolicy string
|
|
|
|
|
|
|
|
const (
|
2022-02-08 02:12:57 +00:00
|
|
|
NotificationPolicyMute = NotificationPolicy("NotificationPolicy.Mute")
|
|
|
|
NotificationPolicyOptIn = NotificationPolicy("NotificationPolicy.OptIn")
|
|
|
|
NotificationPolicyDefaultAll = NotificationPolicy("NotificationPolicy.DefaultAll")
|
2022-02-05 00:17:39 +00:00
|
|
|
)
|
|
|
|
|
2021-06-24 22:30:46 +00:00
|
|
|
type GlobalSettings struct {
|
|
|
|
Locale string
|
|
|
|
Theme string
|
2021-12-11 00:28:13 +00:00
|
|
|
ThemeMode string
|
2021-06-24 22:30:46 +00:00
|
|
|
PreviousPid int64
|
|
|
|
ExperimentsEnabled bool
|
|
|
|
Experiments map[string]bool
|
|
|
|
BlockUnknownConnections bool
|
2022-02-05 00:17:39 +00:00
|
|
|
NotificationPolicy NotificationPolicy
|
2022-02-04 21:25:06 +00:00
|
|
|
NotificationContent string
|
2021-09-30 17:21:36 +00:00
|
|
|
StreamerMode bool
|
2021-06-24 22:30:46 +00:00
|
|
|
StateRootPane int
|
|
|
|
FirstTime bool
|
|
|
|
UIColumnModePortrait string
|
|
|
|
UIColumnModeLandscape string
|
2021-12-14 21:23:32 +00:00
|
|
|
DownloadPath string
|
2022-01-12 22:11:35 +00:00
|
|
|
AllowAdvancedTorConfig bool
|
2022-01-12 22:02:50 +00:00
|
|
|
CustomTorrc string
|
|
|
|
UseCustomTorrc bool
|
|
|
|
UseExternalTor bool
|
|
|
|
CustomSocksPort int
|
|
|
|
CustomControlPort int
|
2022-01-18 20:49:52 +00:00
|
|
|
UseTorCache bool
|
|
|
|
TorCacheDir string
|
2021-06-24 22:30:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var DefaultGlobalSettings = GlobalSettings{
|
|
|
|
Locale: "en",
|
|
|
|
Theme: "dark",
|
|
|
|
PreviousPid: -1,
|
|
|
|
ExperimentsEnabled: false,
|
|
|
|
Experiments: make(map[string]bool),
|
|
|
|
StateRootPane: 0,
|
|
|
|
FirstTime: true,
|
|
|
|
BlockUnknownConnections: false,
|
2021-09-30 17:21:36 +00:00
|
|
|
StreamerMode: false,
|
2021-06-30 20:28:16 +00:00
|
|
|
UIColumnModePortrait: "DualpaneMode.Single",
|
|
|
|
UIColumnModeLandscape: "DualpaneMode.CopyPortrait",
|
2022-02-23 19:32:21 +00:00
|
|
|
NotificationPolicy: "NotificationPolicy.Mute",
|
2022-02-04 21:25:06 +00:00
|
|
|
NotificationContent: "NotificationContent.SimpleEvent",
|
2021-12-14 21:23:32 +00:00
|
|
|
DownloadPath: "",
|
2022-01-12 22:02:50 +00:00
|
|
|
AllowAdvancedTorConfig: false,
|
|
|
|
CustomTorrc: "",
|
|
|
|
UseCustomTorrc: false,
|
|
|
|
CustomSocksPort: -1,
|
|
|
|
CustomControlPort: -1,
|
2022-01-18 20:49:52 +00:00
|
|
|
UseTorCache: false,
|
|
|
|
TorCacheDir: "",
|
2021-06-24 22:30:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func InitGlobalSettingsFile(directory string, password string) error {
|
2021-06-30 20:28:16 +00:00
|
|
|
lock.Lock()
|
|
|
|
defer lock.Unlock()
|
2021-06-24 22:30:46 +00:00
|
|
|
var key [32]byte
|
|
|
|
salt, err := ioutil.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 err
|
|
|
|
}
|
|
|
|
os.Mkdir(directory, 0700)
|
|
|
|
err := ioutil.WriteFile(path.Join(directory, saltFile), newSalt[:], 0600)
|
|
|
|
if err != nil {
|
|
|
|
log.Errorf("Could not write salt file: %v", err)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
key = v1.CreateKey(password, salt)
|
|
|
|
}
|
|
|
|
|
|
|
|
GlobalSettingsFile = v1.NewFileStore(directory, GlobalSettingsFilename, key)
|
|
|
|
log.Infof("initialized global settings file: %v", GlobalSettingsFile)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func ReadGlobalSettings() *GlobalSettings {
|
2021-06-30 20:28:16 +00:00
|
|
|
lock.Lock()
|
|
|
|
defer lock.Unlock()
|
2021-06-24 22:30:46 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
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 WriteGlobalSettings(globalSettings GlobalSettings) {
|
2021-06-30 20:28:16 +00:00
|
|
|
lock.Lock()
|
|
|
|
defer lock.Unlock()
|
2021-06-24 22:30:46 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|