diff --git a/config.go b/config.go index a09c426..3818b7b 100644 --- a/config.go +++ b/config.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "os" + "sync" ) type WakeOnLanDevice struct { @@ -40,25 +41,28 @@ var defaultConfig = &Config{ DisplayOffAfterSec: 1800, // 30 minutes } -var config *Config +var ( + config *Config + configLock = &sync.Mutex{} +) func LoadConfig() { if config != nil { + logger.Info("config already loaded, skipping") return } file, err := os.Open(configPath) if err != nil { logger.Debug("default config file doesn't exist, using default") - config = defaultConfig return } defer file.Close() - var loadedConfig Config + // load and merge the default config with the user config + loadedConfig := *defaultConfig if err := json.NewDecoder(file).Decode(&loadedConfig); err != nil { logger.Errorf("config file JSON parsing failed, %v", err) - config = defaultConfig return } @@ -66,6 +70,9 @@ func LoadConfig() { } func SaveConfig() error { + configLock.Lock() + defer configLock.Unlock() + file, err := os.Create(configPath) if err != nil { return fmt.Errorf("failed to create config file: %w", err) diff --git a/display.go b/display.go index 416401b..9d22c26 100644 --- a/display.go +++ b/display.go @@ -209,7 +209,6 @@ func watchTsEvents() { // if they're not already set. This is done separately to the init routine as the "never dim" // option has the value set to zero, but time.NewTicker only accept positive values. func startBacklightTickers() { - LoadConfig() // Don't start the tickers if the display is switched off. // Set the display to off if that's the case. if config.DisplayMaxBrightness == 0 { diff --git a/jsonrpc.go b/jsonrpc.go index aa39d25..619e561 100644 --- a/jsonrpc.go +++ b/jsonrpc.go @@ -194,7 +194,6 @@ func rpcSetEDID(edid string) error { } // Save EDID to config, allowing it to be restored on reboot. - LoadConfig() config.EdidString = edid SaveConfig() @@ -235,8 +234,6 @@ func rpcTryUpdate() error { } func rpcSetBacklightSettings(params BacklightSettings) error { - LoadConfig() - blConfig := params // NOTE: by default, the frontend limits the brightness to 64, as that's what the device originally shipped with. @@ -275,8 +272,6 @@ func rpcSetBacklightSettings(params BacklightSettings) error { } func rpcGetBacklightSettings() (*BacklightSettings, error) { - LoadConfig() - return &BacklightSettings{ MaxBrightness: config.DisplayMaxBrightness, DimAfter: int(config.DisplayDimAfterSec), @@ -544,7 +539,6 @@ func rpcSetUsbEmulationState(enabled bool) error { } func rpcGetWakeOnLanDevices() ([]WakeOnLanDevice, error) { - LoadConfig() if config.WakeOnLanDevices == nil { return []WakeOnLanDevice{}, nil } @@ -556,13 +550,11 @@ type SetWakeOnLanDevicesParams struct { } func rpcSetWakeOnLanDevices(params SetWakeOnLanDevicesParams) error { - LoadConfig() config.WakeOnLanDevices = params.Devices return SaveConfig() } func rpcResetConfig() error { - LoadConfig() config = defaultConfig if err := SaveConfig(); err != nil { return fmt.Errorf("failed to reset config: %w", err) diff --git a/native.go b/native.go index 1bd8429..7940f64 100644 --- a/native.go +++ b/native.go @@ -311,7 +311,6 @@ func ensureBinaryUpdated(destPath string) error { // Restore the HDMI EDID value from the config. // Called after successful connection to jetkvm_native. func restoreHdmiEdid() { - LoadConfig() if config.EdidString != "" { logger.Infof("Restoring HDMI EDID to %v", config.EdidString) _, err := CallCtrlAction("set_edid", map[string]interface{}{"edid": config.EdidString}) diff --git a/web.go b/web.go index 6164115..3157847 100644 --- a/web.go +++ b/web.go @@ -147,8 +147,6 @@ func handleWebRTCSession(c *gin.Context) { } func handleLogin(c *gin.Context) { - LoadConfig() - if config.LocalAuthMode == "noPassword" { c.JSON(http.StatusBadRequest, gin.H{"error": "Login is disabled in noPassword mode"}) return @@ -161,7 +159,6 @@ func handleLogin(c *gin.Context) { return } - LoadConfig() err := bcrypt.CompareHashAndPassword([]byte(config.HashedPassword), []byte(req.Password)) if err != nil { c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid password"}) @@ -177,7 +174,6 @@ func handleLogin(c *gin.Context) { } func handleLogout(c *gin.Context) { - LoadConfig() config.LocalAuthToken = "" if err := SaveConfig(); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save configuration"}) @@ -191,8 +187,6 @@ func handleLogout(c *gin.Context) { func protectedMiddleware() gin.HandlerFunc { return func(c *gin.Context) { - LoadConfig() - if config.LocalAuthMode == "noPassword" { c.Next() return @@ -221,8 +215,6 @@ func RunWebServer() { } func handleDevice(c *gin.Context) { - LoadConfig() - response := LocalDevice{ AuthMode: &config.LocalAuthMode, DeviceID: GetDeviceID(), @@ -232,8 +224,6 @@ func handleDevice(c *gin.Context) { } func handleCreatePassword(c *gin.Context) { - LoadConfig() - if config.HashedPassword != "" { c.JSON(http.StatusBadRequest, gin.H{"error": "Password already set"}) return @@ -274,8 +264,6 @@ func handleCreatePassword(c *gin.Context) { } func handleUpdatePassword(c *gin.Context) { - LoadConfig() - if config.HashedPassword == "" { c.JSON(http.StatusBadRequest, gin.H{"error": "Password is not set"}) return @@ -319,8 +307,6 @@ func handleUpdatePassword(c *gin.Context) { } func handleDeletePassword(c *gin.Context) { - LoadConfig() - if config.HashedPassword == "" { c.JSON(http.StatusBadRequest, gin.H{"error": "Password is not set"}) return @@ -357,8 +343,6 @@ func handleDeletePassword(c *gin.Context) { } func handleDeviceStatus(c *gin.Context) { - LoadConfig() - response := DeviceStatus{ IsSetup: config.LocalAuthMode != "", } @@ -367,8 +351,6 @@ func handleDeviceStatus(c *gin.Context) { } func handleDeviceUIConfig(c *gin.Context) { - LoadConfig() - config, _ := json.Marshal(gin.H{ "CLOUD_API": config.CloudURL, "DEVICE_VERSION": builtAppVersion, @@ -384,8 +366,6 @@ func handleDeviceUIConfig(c *gin.Context) { } func handleSetup(c *gin.Context) { - LoadConfig() - // Check if the device is already set up if config.LocalAuthMode != "" || config.HashedPassword != "" { c.JSON(http.StatusBadRequest, gin.H{"error": "Device is already set up"})