From 3f349299950dadfffc364077f84e922bbc67b9c4 Mon Sep 17 00:00:00 2001 From: Ken Van Hoeylandt Date: Tue, 28 Jul 2026 00:37:25 +0200 Subject: [PATCH] WebServer doesn't save config as a side-effect of reading the config --- Documentation/ideas.md | 1 - .../Source/settings/WebServerSettings.cpp | 45 ++++++------------- 2 files changed, 14 insertions(+), 32 deletions(-) diff --git a/Documentation/ideas.md b/Documentation/ideas.md index c12417b63..f92dbe67f 100644 --- a/Documentation/ideas.md +++ b/Documentation/ideas.md @@ -2,7 +2,6 @@ ## Before release -- WebServer service shouldn't save webserver.properties at start, it slows the boot process - Remove incubating flag from various devices - Add `// SPDX-License-Identifier: GPL-3.0-only` and `// SPDX-License-Identifier: Apache-2.0` to individual files in the project - Elecrow Basic & Advance 3.5" memory issue: not enough memory for App Hub diff --git a/Tactility/Source/settings/WebServerSettings.cpp b/Tactility/Source/settings/WebServerSettings.cpp index 1a5860191..99cc17d15 100644 --- a/Tactility/Source/settings/WebServerSettings.cpp +++ b/Tactility/Source/settings/WebServerSettings.cpp @@ -144,23 +144,17 @@ bool load(WebServerSettings& settings) { ? static_cast(parseInt(ap_channel->second, 1, 13, 1)) : 1; - // Security: If AP password is empty, generate a strong random password. + // Security: If AP password is empty, generate a strong random password in memory. // Skip this if user explicitly wants an open network. // Note: We only auto-generate for EMPTY passwords, not user-set ones. + // This is a read-only function: the generated password is NOT persisted here — + // callers that want it saved must call save() explicitly. if (!settings.apOpenNetwork && isEmptyCredential(settings.apPassword)) { - LOG_I(TAG, "AP password is empty - generating secure random password"); + LOG_I(TAG, "AP password is empty - generating secure random password (not persisted)"); // Generate 12-character random password (alphanumeric, ~71 bits of entropy) // WPA2 requires 8-63 characters, so 12 is well within range settings.apPassword = generateRandomCredential(12); - - // Persist the generated password immediately - map[KEY_AP_PASSWORD] = settings.apPassword; - if (file::savePropertiesFile(getSettingsFilePath(), map)) { - LOG_I(TAG, "Generated and saved new secure AP password"); - } else { - LOG_E(TAG, "Failed to save generated AP password"); - } } // Web server settings @@ -181,27 +175,20 @@ bool load(WebServerSettings& settings) { settings.webServerUsername = (webserver_username != map.end()) ? webserver_username->second : ""; settings.webServerPassword = (webserver_password != map.end()) ? webserver_password->second : ""; - // Security: If auth is enabled but credentials are empty, - // generate strong random credentials and persist them immediately. - // Note: We only auto-generate for EMPTY credentials, allowing users to set their own. + // Security: If auth is enabled but credentials are empty, generate strong random + // credentials in memory. Note: We only auto-generate for EMPTY credentials, allowing + // users to set their own. + // This is a read-only function: the generated credentials are NOT persisted here — + // callers that want them saved (so they're consistent across reboots) must call + // save() explicitly. if (settings.webServerAuthEnabled && (isEmptyCredential(settings.webServerUsername) || isEmptyCredential(settings.webServerPassword))) { - LOG_I(TAG, "Auth enabled with empty credentials - generating secure random credentials"); + LOG_I(TAG, "Auth enabled with empty credentials - generating secure random credentials (not persisted)"); // Generate 12-character random credentials (alphanumeric, ~71 bits of entropy each) settings.webServerUsername = generateRandomCredential(12); settings.webServerPassword = generateRandomCredential(12); - - // Persist the generated credentials immediately - // We need to save these to the file so they're consistent across reboots - map[KEY_WEBSERVER_USERNAME] = settings.webServerUsername; - map[KEY_WEBSERVER_PASSWORD] = settings.webServerPassword; - if (file::savePropertiesFile(getSettingsFilePath(), map)) { - LOG_I(TAG, "Generated and saved new secure credentials"); - } else { - LOG_E(TAG, "Failed to save generated credentials - auth may be inconsistent across reboots"); - } } return true; @@ -228,14 +215,10 @@ WebServerSettings loadOrGetDefault() { bool loadedFromFlash = load(settings); if (!loadedFromFlash) { - // First boot - use defaults (WiFi OFF, WebServer OFF) + // No properties file yet (e.g. first boot) - use defaults in memory (WiFi OFF, + // WebServer OFF). Read-only function: does NOT persist these defaults — callers + // that want them saved must call save() explicitly. settings = getDefault(); - // Save defaults to flash so toggle states persist - if (save(settings)) { - LOG_I(TAG, "First boot - saved default settings (WiFi OFF WebServer OFF)"); - } else { - LOG_W(TAG, "First boot - failed to save default settings to flash"); - } } return settings;