Improvements and fixes (#595)

- Fix BluetoothSettings app not updating when toggling on Bluetooth on
- Fix BluetoothSettings app crash when closing while scanning
- Fix BluetoothSettings app crash when turning BT off while scanning
- WebServer doesn't save config anymore as a side-effect of reading the config
- Add missing license headers
- Use TactilityKernel's time and delay functions instead of TactilityFreeRtos ones
This commit is contained in:
Ken Van Hoeylandt
2026-07-28 18:38:23 +02:00
committed by GitHub
parent e6e1dcd0ca
commit bd108cc3c4
33 changed files with 215 additions and 112 deletions
+14 -31
View File
@@ -144,23 +144,17 @@ bool load(WebServerSettings& settings) {
? static_cast<uint8_t>(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;