Compare commits

..

4 Commits

  1. 5
      .gitignore
  2. 68
      README.md
  3. 60
      data/settings.html
  4. 25
      platformio.ini
  5. 155
      src/main.cpp
  6. 58
      src/server.cpp
  7. 2
      src/server.h

5
.gitignore vendored

@ -22,5 +22,8 @@ Thumbs.db @@ -22,5 +22,8 @@ Thumbs.db
# Build artifacts
*.bin
*.elf
*.elf.
*.map
# Fichiers compressés
*.gz

68
README.md

@ -7,6 +7,8 @@ Squelette d'application web pour ESP32 avec interface de gestion via dashboard w @@ -7,6 +7,8 @@ Squelette d'application web pour ESP32 avec interface de gestion via dashboard w
- **Dashboard web responsive** - Interface utilisateur moderne et adaptative
- **Authentification sécurisée** - Système de login avec sessions et hash SHA-256
- **Configuration WiFi** - Mode Station et Point d'Accès automatique
- **Reconnexion WiFi automatique** - Détection de perte de connexion et reconnexion toutes les 30 secondes (WPA2-PSK et WPA2-PEAP)
- **WPA2-Enterprise PEAP** - Connexion PEAP (sans certificat) avec utilisateur/mot de passe (MSCHAPv2)
- **API REST** - Endpoints pour configuration, statistiques et changement de mot de passe
- **Gestion des mots de passe** - Changement sécurisé avec validation de l'ancien mot de passe
- **Mise à jour OTA** - Mise à jour du firmware et système de fichiers via web avec modales de confirmation
@ -69,7 +71,9 @@ platformio device monitor --environment esp32 @@ -69,7 +71,9 @@ platformio device monitor --environment esp32
1. Accédez à la page **Paramètres**
2. Section **Configuration WiFi**
3. Entrez le SSID et le mot de passe de votre réseau
3. Choisissez le type de sécurité :
- **WPA2-PSK** (classique) : SSID + mot de passe WiFi
- **WPA2-Enterprise PEAP** : SSID + utilisateur + mot de passe (sans certificat)
4. Cliquez sur **Enregistrer WiFi**
5. L'ESP32 redémarre et se connecte à votre réseau
@ -86,6 +90,13 @@ platformio device monitor --environment esp32 @@ -86,6 +90,13 @@ platformio device monitor --environment esp32
Si la connexion WiFi échoue ou n'est pas configurée, l'ESP32 démarre automatiquement en mode Point d'Accès (AP).
### Reconnexion automatique
Lorsque la connexion WiFi STA est perdue, l'ESP32 tente automatiquement de se reconnecter toutes les **30 secondes** :
- **WPA2-PSK** : `WiFi.setAutoReconnect(true)` gère la reconnexion en premier lieu ; la vérification périodique sert de fallback
- **WPA2-PEAP** : les credentials entreprise (`esp_wifi_sta_wpa2_ent_*`) sont réappliqués manuellement à chaque tentative
- En cas de succès, l'AP de secours (`<hostname>-setup`) est restauré automatiquement
## 📱 Interface Web
### Pages disponibles
@ -176,7 +187,36 @@ Tous les assets CSS, JS et HTML sont compressés automatiquement en gzip avant l @@ -176,7 +187,36 @@ Tous les assets CSS, JS et HTML sont compressés automatiquement en gzip avant l
},
"wifi": {
"ssid": "Nom_du_réseau",
"security": "wpa2",
"password": "mot_de_passe_wifi",
"eap_username": "utilisateur_peap",
"eap_password": "mot_de_passe_peap",
"ap_password": "webapp123"
},
"system": {
"hostname": "ESP32-Webapp",
"session_timeout": 60
},
"params": {
"app_name": "ESP32 Webapp"
}
}
```
### Exemple sécurisé prêt à copier (WPA2-Enterprise PEAP)
```json
{
"auth": {
"username": "admin",
"password_hash": "hash_sha256_du_mot_de_passe"
},
"wifi": {
"ssid": "Mon-SSID-Entreprise",
"security": "wpa2_peap",
"password": "",
"eap_username": "prenom.nom",
"eap_password": "",
"ap_password": "webapp123"
},
"system": {
@ -189,6 +229,18 @@ Tous les assets CSS, JS et HTML sont compressés automatiquement en gzip avant l @@ -189,6 +229,18 @@ Tous les assets CSS, JS et HTML sont compressés automatiquement en gzip avant l
}
```
Notes:
- Aucun certificat n'est requis pour ce mode PEAP.
- Le mode PEAP est configuré en auto avec authentification interne MSCHAPv2.
- Remplacez `eap_username` par votre identifiant entreprise.
- Laissez `eap_password` vide dans le fichier, puis saisissez-le uniquement dans l'interface web.
Procédure recommandée (sans secret en clair dans les fichiers):
1. Téléversez cette configuration avec `eap_password` vide.
2. Ouvrez la page Paramètres de l'ESP32.
3. Sélectionnez `WPA2-Enterprise PEAP`, saisissez l'utilisateur et le mot de passe PEAP.
4. Enregistrez : l'ESP32 redémarre et se connecte.
## 🛠 Dépendances
- **ESPAsyncWebServer** - Serveur web asynchrone
@ -204,8 +256,10 @@ Tous les assets CSS, JS et HTML sont compressés automatiquement en gzip avant l @@ -204,8 +256,10 @@ Tous les assets CSS, JS et HTML sont compressés automatiquement en gzip avant l
### L'ESP32 ne se connecte pas au WiFi
1. Vérifiez le SSID et le mot de passe dans la configuration
2. En mode WPA2-PEAP, vérifiez l'utilisateur/mot de passe PEAP
2. Assurez-vous que le réseau WiFi est en 2.4 GHz (l'ESP32 ne supporte pas le 5 GHz)
3. L'ESP32 passera automatiquement en mode AP si la connexion échoue
4. En cas de perte de connexion après démarrage, l'ESP32 retente automatiquement toutes les 30 secondes (visible dans les logs série : `WiFi déconnecté, tentative de reconnexion...`)
### Impossible de se connecter à l'interface web
@ -213,6 +267,18 @@ Tous les assets CSS, JS et HTML sont compressés automatiquement en gzip avant l @@ -213,6 +267,18 @@ Tous les assets CSS, JS et HTML sont compressés automatiquement en gzip avant l
2. En mode AP, l'adresse est toujours `192.168.4.1`
3. En mode Station, trouvez l'IP dans les logs du moniteur série
4. Désactivez le cache du navigateur (Ctrl+F5)
5. En réseau entreprise (PEAP), un filtrage « client isolation » peut bloquer ping/HTTP entre clients WiFi
6. Utilisez l'AP de secours `ESP32-Webapp-setup` (ou `<hostname>-setup`) avec l'IP `192.168.4.1`
### Diagnostic rapide réseau (2 minutes)
1. Ouvrez le moniteur série et vérifiez `Serveur web démarré sur le port 80`
2. Depuis votre PC, testez l'endpoint de santé:
- en STA: `curl -v http://<ip_sta>/api/health`
- en AP de secours: `curl -v http://192.168.4.1/api/health`
3. Vérifiez les logs série:
- si vous voyez `HTTP GET /api/health depuis ...`, le trafic arrive bien
- si rien n'apparaît, le réseau filtre la communication vers l'ESP32
### Erreur lors de la mise à jour OTA

60
data/settings.html

@ -23,16 +23,34 @@ @@ -23,16 +23,34 @@
<div class="card">
<h2>Configuration WiFi</h2>
<form id="wifiForm">
<div class="form-group">
<label for="wifi_security">Type de sécurité</label>
<select id="wifi_security" name="wifi_security">
<option value="wpa2">WPA2-PSK (classique)</option>
<option value="wpa2_peap">WPA2-Enterprise PEAP (MSCHAPv2)</option>
</select>
</div>
<div class="form-group">
<label for="wifi_ssid">SSID du réseau</label>
<input type="text" id="wifi_ssid" name="wifi_ssid">
</div>
<div class="form-group">
<div class="form-group" id="wifi_password_group">
<label for="wifi_password">Mot de passe WiFi</label>
<input type="password" id="wifi_password" name="wifi_password" placeholder="Laisser vide pour ne pas changer">
</div>
<div class="form-group" id="eap_username_group" style="display: none;">
<label for="eap_username">Utilisateur PEAP</label>
<input type="text" id="eap_username" name="eap_username" placeholder="Nom d'utilisateur" autocomplete="username">
</div>
<div class="form-group" id="eap_password_group" style="display: none;">
<label for="eap_password">Mot de passe PEAP</label>
<input type="password" id="eap_password" name="eap_password" placeholder="Laisser vide pour ne pas changer" autocomplete="current-password">
</div>
<div class="form-group">
<label for="ap_password">Mot de passe du Point d'Accès</label>
<input type="password" id="ap_password" name="ap_password" placeholder="Laisser vide pour ne pas changer">
@ -89,12 +107,23 @@ @@ -89,12 +107,23 @@
<script>
let config = {};
function toggleWifiSecurityFields() {
const security = document.getElementById('wifi_security').value;
const isPeap = security === 'wpa2_peap';
document.getElementById('wifi_password_group').style.display = isPeap ? 'none' : 'block';
document.getElementById('eap_username_group').style.display = isPeap ? 'block' : 'none';
document.getElementById('eap_password_group').style.display = isPeap ? 'block' : 'none';
}
async function loadConfig() {
try {
config = await api.getConfig();
// WiFi
document.getElementById('wifi_security').value = config.wifi.security || 'wpa2';
document.getElementById('wifi_ssid').value = config.wifi.ssid || '';
document.getElementById('eap_username').value = config.wifi.eap_username || '';
toggleWifiSecurityFields();
// Système
document.getElementById('hostname').value = config.system.hostname || '';
@ -117,11 +146,32 @@ @@ -117,11 +146,32 @@
document.getElementById('wifiForm').addEventListener('submit', async (e) => {
e.preventDefault();
config.wifi.security = document.getElementById('wifi_security').value;
config.wifi.ssid = document.getElementById('wifi_ssid').value;
const wifiPassword = document.getElementById('wifi_password').value;
if (wifiPassword) {
config.wifi.password = wifiPassword;
if (config.wifi.security === 'wpa2_peap') {
const eapUsername = document.getElementById('eap_username').value.trim();
if (!eapUsername) {
showMessage('Le nom d\'utilisateur PEAP est requis', 'error');
return;
}
config.wifi.eap_username = eapUsername;
const eapPassword = document.getElementById('eap_password').value;
if (eapPassword) {
config.wifi.eap_password = eapPassword;
}
config.wifi.password = '';
} else {
const wifiPassword = document.getElementById('wifi_password').value;
if (wifiPassword) {
config.wifi.password = wifiPassword;
}
config.wifi.eap_username = '';
config.wifi.eap_password = '';
}
const apPassword = document.getElementById('ap_password').value;
@ -137,6 +187,8 @@ @@ -137,6 +187,8 @@
}
});
document.getElementById('wifi_security').addEventListener('change', toggleWifiSecurityFields);
document.getElementById('systemForm').addEventListener('submit', async (e) => {
e.preventDefault();

25
platformio.ini

@ -12,7 +12,28 @@ lib_deps = @@ -12,7 +12,28 @@ lib_deps =
ESP32Async/AsyncTCP
bblanchon/ArduinoJson@^7.0.0
#build_flags =
# -DBOARD_HAS_PSRAM
upload_speed = 921600
[env:esp32-s3-supermini]
platform = espressif32
board = esp32-s3-devkitc-1
framework = arduino
board_upload.flash_size = 4MB
board_build.filesystem = littlefs
board_build.partitions = default.csv
extra_scripts = platformio_extra.py
monitor_speed = 115200
lib_deps =
ESP32Async/ESPAsyncWebServer
ESP32Async/AsyncTCP
bblanchon/ArduinoJson@^7.0.0
build_flags =
-DARDUINO_USB_CDC_ON_BOOT=1
-DBOARD_HAS_PSRAM
upload_speed = 921600
; Configuration ArduinoOTA pour firmware et filesystem
;upload_protocol = espota
;upload_port = 192.168.0.xx
;upload_flags =
; --auth=password

155
src/main.cpp

@ -3,6 +3,13 @@ @@ -3,6 +3,13 @@
#include <LittleFS.h>
#include <ArduinoJson.h>
#include <ArduinoOTA.h>
#if __has_include(<esp_wpa2.h>)
#include <esp_wpa2.h>
#include <esp_wifi.h>
#define HAS_LEGACY_WPA2_ENTERPRISE 1
#else
#define HAS_LEGACY_WPA2_ENTERPRISE 0
#endif
#include "auth.h"
#include "server.h"
#include "utils.h"
@ -11,8 +18,31 @@ @@ -11,8 +18,31 @@
String hostname = "ESP32-Webapp";
String wifiSSID = "";
String wifiPassword = "";
String wifiSecurity = "wpa2";
String wifiEapUsername = "";
String wifiEapPassword = "";
String apPassword = "webapp123";
void logNetworkInfo() {
logMessage(LOG_INFO, "Adresse IP: " + WiFi.localIP().toString());
logMessage(LOG_INFO, "Passerelle: " + WiFi.gatewayIP().toString());
logMessage(LOG_INFO, "Masque: " + WiFi.subnetMask().toString());
logMessage(LOG_INFO, "DNS 1: " + WiFi.dnsIP(0).toString());
logMessage(LOG_INFO, "DNS 2: " + WiFi.dnsIP(1).toString());
logMessage(LOG_INFO, "MAC STA: " + WiFi.macAddress());
}
void startFallbackAP() {
String fallbackSsid = hostname + "-setup";
WiFi.mode(WIFI_AP_STA);
if (WiFi.softAP(fallbackSsid.c_str(), apPassword.c_str())) {
logMessage(LOG_INFO, "AP de secours actif: " + fallbackSsid);
logMessage(LOG_INFO, "IP AP de secours: " + WiFi.softAPIP().toString());
} else {
logMessage(LOG_WARN, "Échec du démarrage de l'AP de secours");
}
}
void createDefaultConfig() {
logMessage(LOG_INFO, "Création de la configuration par défaut");
@ -25,6 +55,9 @@ void createDefaultConfig() { @@ -25,6 +55,9 @@ void createDefaultConfig() {
// Configuration WiFi
doc["wifi"]["ssid"] = "";
doc["wifi"]["password"] = "";
doc["wifi"]["security"] = "wpa2";
doc["wifi"]["eap_username"] = "";
doc["wifi"]["eap_password"] = "";
doc["wifi"]["ap_password"] = apPassword;
// Configuration système
@ -90,6 +123,18 @@ void loadConfig() { @@ -90,6 +123,18 @@ void loadConfig() {
wifiPassword = doc["wifi"]["password"].as<String>();
}
if (doc["wifi"]["security"]) {
wifiSecurity = doc["wifi"]["security"].as<String>();
}
if (doc["wifi"]["eap_username"]) {
wifiEapUsername = doc["wifi"]["eap_username"].as<String>();
}
if (doc["wifi"]["eap_password"]) {
wifiEapPassword = doc["wifi"]["eap_password"].as<String>();
}
if (doc["wifi"]["ap_password"]) {
apPassword = doc["wifi"]["ap_password"].as<String>();
}
@ -97,23 +142,88 @@ void loadConfig() { @@ -97,23 +142,88 @@ void loadConfig() {
logMessage(LOG_INFO, "Configuration chargée");
}
bool waitForWiFiConnection() {
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 20) {
delay(500);
Serial.print(".");
attempts++;
}
if (WiFi.status() == WL_CONNECTED) {
logMessage(LOG_INFO, "WiFi connecté");
logNetworkInfo();
return true;
}
return false;
}
bool connectWPA2PEAP() {
if (wifiEapUsername.isEmpty() || wifiEapPassword.isEmpty()) {
logMessage(LOG_WARN, "WPA2-PEAP: identifiant ou mot de passe manquant");
return false;
}
logMessage(LOG_INFO, "Connexion WPA2-PEAP au WiFi: " + wifiSSID);
logMessage(LOG_INFO, "Profil PEAP: sans certificat, domaine vide, MSCHAPv2 interne");
#if HAS_LEGACY_WPA2_ENTERPRISE
WiFi.disconnect(true, true);
delay(100);
esp_wifi_sta_wpa2_ent_set_identity((uint8_t*)wifiEapUsername.c_str(), wifiEapUsername.length());
esp_wifi_sta_wpa2_ent_set_username((uint8_t*)wifiEapUsername.c_str(), wifiEapUsername.length());
esp_wifi_sta_wpa2_ent_set_password((uint8_t*)wifiEapPassword.c_str(), wifiEapPassword.length());
#ifdef ESP_EAP_TTLS_PHASE2_MSCHAPV2
esp_wifi_sta_wpa2_ent_set_ttls_phase2_method(ESP_EAP_TTLS_PHASE2_MSCHAPV2);
#endif
esp_wifi_sta_wpa2_ent_enable();
WiFi.begin(wifiSSID.c_str());
return waitForWiFiConnection();
#elif defined(WPA2_AUTH_PEAP)
WiFi.disconnect(true, true);
delay(100);
WiFi.begin(
wifiSSID.c_str(),
WPA2_AUTH_PEAP,
wifiEapUsername.c_str(),
wifiEapUsername.c_str(),
wifiEapPassword.c_str(),
nullptr
);
return waitForWiFiConnection();
#else
logMessage(LOG_ERROR, "WPA2-PEAP non supporté par cette version du framework");
return false;
#endif
}
bool connectWPA2PSK() {
logMessage(LOG_INFO, "Connexion WPA2-PSK au WiFi: " + wifiSSID);
WiFi.begin(wifiSSID.c_str(), wifiPassword.c_str());
return waitForWiFiConnection();
}
void setupWiFi() {
if (wifiSSID.length() > 0) {
logMessage(LOG_INFO, "Connexion au WiFi: " + wifiSSID);
WiFi.mode(WIFI_STA);
WiFi.setSleep(false);
WiFi.setAutoReconnect(true);
WiFi.persistent(false);
WiFi.setHostname(hostname.c_str());
WiFi.begin(wifiSSID.c_str(), wifiPassword.c_str());
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 20) {
delay(500);
Serial.print(".");
attempts++;
bool connected = false;
if (wifiSecurity == "wpa2_peap") {
connected = connectWPA2PEAP();
} else {
connected = connectWPA2PSK();
}
if (WiFi.status() == WL_CONNECTED) {
logMessage(LOG_INFO, "WiFi connecté");
logMessage(LOG_INFO, "Adresse IP: " + WiFi.localIP().toString());
if (connected) {
startFallbackAP();
return;
}
@ -190,10 +300,35 @@ void setup() { @@ -190,10 +300,35 @@ void setup() {
}
unsigned long lastCleanup = 0;
static unsigned long lastReconnectAttempt = 0;
static const unsigned long RECONNECT_INTERVAL = 30000;
void checkWiFiConnection() {
if (wifiSSID.isEmpty()) return;
if (WiFi.status() == WL_CONNECTED) return;
unsigned long now = millis();
if (now - lastReconnectAttempt < RECONNECT_INTERVAL) return;
lastReconnectAttempt = now;
logMessage(LOG_WARN, "WiFi déconnecté, tentative de reconnexion...");
WiFi.mode(WIFI_STA);
bool connected = (wifiSecurity == "wpa2_peap") ? connectWPA2PEAP() : connectWPA2PSK();
if (connected) {
logMessage(LOG_INFO, "WiFi reconnecté");
startFallbackAP();
} else {
logMessage(LOG_WARN, "Échec de reconnexion WiFi");
}
}
void loop() {
ArduinoOTA.handle();
checkWiFiConnection();
// Nettoyer les sessions expirées toutes les minutes
unsigned long now = millis();
if (now - lastCleanup > 60000) {

58
src/server.cpp

@ -8,6 +8,23 @@ WebServerManager::WebServerManager() { @@ -8,6 +8,23 @@ WebServerManager::WebServerManager() {
server = new AsyncWebServer(80);
}
void WebServerManager::logRequest(AsyncWebServerRequest* request, const String& routeTag) {
String method = "OTHER";
if (request->method() == HTTP_GET) method = "GET";
else if (request->method() == HTTP_POST) method = "POST";
else if (request->method() == HTTP_PUT) method = "PUT";
else if (request->method() == HTTP_DELETE) method = "DELETE";
else if (request->method() == HTTP_OPTIONS) method = "OPTIONS";
else if (request->method() == HTTP_PATCH) method = "PATCH";
String remoteIp = "unknown";
if (request->client()) {
remoteIp = request->client()->remoteIP().toString();
}
logMessage(LOG_INFO, "HTTP " + method + " " + request->url() + " depuis " + remoteIp + " (" + routeTag + ")");
}
String WebServerManager::getSessionIdFromRequest(AsyncWebServerRequest* request) {
if (request->hasHeader("Cookie")) {
String cookie = request->header("Cookie");
@ -54,16 +71,25 @@ void WebServerManager::sendJsonSuccess(AsyncWebServerRequest* request, const Str @@ -54,16 +71,25 @@ void WebServerManager::sendJsonSuccess(AsyncWebServerRequest* request, const Str
void WebServerManager::setupRoutes() {
// Route de login
server->on("/login", HTTP_POST, [this](AsyncWebServerRequest* request) {
logRequest(request, "login");
this->handleLogin(request);
});
// Endpoint de diagnostic réseau (sans authentification)
server->on("/api/health", HTTP_GET, [this](AsyncWebServerRequest* request) {
logRequest(request, "health");
this->handleHealth(request);
});
// Route de logout
server->on("/logout", HTTP_GET, [this](AsyncWebServerRequest* request) {
logRequest(request, "logout");
this->handleLogout(request);
});
// API - Configuration
server->on("/api/config", HTTP_GET, [this](AsyncWebServerRequest* request) {
logRequest(request, "get_config");
if (!isAuthenticated(request)) {
sendJsonError(request, 401, "Non authentifié");
return;
@ -72,6 +98,7 @@ void WebServerManager::setupRoutes() { @@ -72,6 +98,7 @@ void WebServerManager::setupRoutes() {
});
server->on("/api/config", HTTP_POST, [this](AsyncWebServerRequest* request) {
logRequest(request, "set_config");
if (!isAuthenticated(request)) {
sendJsonError(request, 401, "Non authentifié");
return;
@ -81,6 +108,7 @@ void WebServerManager::setupRoutes() { @@ -81,6 +108,7 @@ void WebServerManager::setupRoutes() {
// API - Changement de mot de passe
server->on("/api/password", HTTP_POST, [this](AsyncWebServerRequest* request) {
logRequest(request, "change_password");
if (!isAuthenticated(request)) {
sendJsonError(request, 401, "Non authentifié");
return;
@ -90,6 +118,7 @@ void WebServerManager::setupRoutes() { @@ -90,6 +118,7 @@ void WebServerManager::setupRoutes() {
// API - Statistiques
server->on("/api/stats", HTTP_GET, [this](AsyncWebServerRequest* request) {
logRequest(request, "get_stats");
if (!isAuthenticated(request)) {
sendJsonError(request, 401, "Non authentifié");
return;
@ -100,6 +129,7 @@ void WebServerManager::setupRoutes() { @@ -100,6 +129,7 @@ void WebServerManager::setupRoutes() {
// OTA Update
server->on("/api/update", HTTP_POST,
[this](AsyncWebServerRequest* request) {
logRequest(request, "ota_update");
if (!isAuthenticated(request)) {
sendJsonError(request, 401, "Non authentifié");
return;
@ -120,7 +150,8 @@ void WebServerManager::setupRoutes() { @@ -120,7 +150,8 @@ void WebServerManager::setupRoutes() {
);
// 404
server->onNotFound([](AsyncWebServerRequest* request) {
server->onNotFound([this](AsyncWebServerRequest* request) {
logRequest(request, "not_found");
request->send(404, "text/plain", "Page non trouvée");
});
@ -128,6 +159,19 @@ void WebServerManager::setupRoutes() { @@ -128,6 +159,19 @@ void WebServerManager::setupRoutes() {
server->serveStatic("/", LittleFS, "/").setDefaultFile("login.html");
}
void WebServerManager::handleHealth(AsyncWebServerRequest* request) {
JsonDocument doc;
doc["ok"] = true;
doc["ip_sta"] = WiFi.localIP().toString();
doc["ip_ap"] = WiFi.softAPIP().toString();
doc["wifi_status"] = WiFi.status();
doc["ssid"] = WiFi.SSID();
String response;
serializeJson(doc, response);
request->send(200, "application/json", response);
}
void WebServerManager::handleLogin(AsyncWebServerRequest* request) {
if (!request->hasParam("username", true) || !request->hasParam("password", true)) {
sendJsonError(request, 400, "Paramètres manquants");
@ -183,6 +227,9 @@ void WebServerManager::handleGetConfig(AsyncWebServerRequest* request) { @@ -183,6 +227,9 @@ void WebServerManager::handleGetConfig(AsyncWebServerRequest* request) {
if (doc["wifi"]["password"]) {
doc["wifi"]["password"] = "***";
}
if (doc["wifi"]["eap_password"]) {
doc["wifi"]["eap_password"] = "***";
}
if (doc["wifi"]["ap_password"]) {
doc["wifi"]["ap_password"] = "***";
}
@ -232,6 +279,9 @@ void WebServerManager::handleSetConfig(AsyncWebServerRequest* request) { @@ -232,6 +279,9 @@ void WebServerManager::handleSetConfig(AsyncWebServerRequest* request) {
if (newDoc["wifi"]["password"] && newDoc["wifi"]["password"] != "***") {
existingDoc["wifi"]["password"] = newDoc["wifi"]["password"];
}
if (!newDoc["wifi"]["eap_password"].isNull() && newDoc["wifi"]["eap_password"] != "***") {
existingDoc["wifi"]["eap_password"] = newDoc["wifi"]["eap_password"];
}
if (newDoc["wifi"]["ap_password"] && newDoc["wifi"]["ap_password"] != "***") {
existingDoc["wifi"]["ap_password"] = newDoc["wifi"]["ap_password"];
}
@ -246,6 +296,12 @@ void WebServerManager::handleSetConfig(AsyncWebServerRequest* request) { @@ -246,6 +296,12 @@ void WebServerManager::handleSetConfig(AsyncWebServerRequest* request) {
if (newDoc["wifi"]["ssid"]) {
existingDoc["wifi"]["ssid"] = newDoc["wifi"]["ssid"];
}
if (!newDoc["wifi"]["security"].isNull()) {
existingDoc["wifi"]["security"] = newDoc["wifi"]["security"];
}
if (!newDoc["wifi"]["eap_username"].isNull()) {
existingDoc["wifi"]["eap_username"] = newDoc["wifi"]["eap_username"];
}
if (newDoc["system"]["hostname"]) {
existingDoc["system"]["hostname"] = newDoc["system"]["hostname"];
}

2
src/server.h

@ -13,6 +13,7 @@ private: @@ -13,6 +13,7 @@ private:
AsyncWebServer* server;
String getSessionIdFromRequest(AsyncWebServerRequest* request);
void logRequest(AsyncWebServerRequest* request, const String& routeTag);
bool isAuthenticated(AsyncWebServerRequest* request);
void sendJsonError(AsyncWebServerRequest* request, int code, const String& message);
void sendJsonSuccess(AsyncWebServerRequest* request, const String& message);
@ -28,6 +29,7 @@ public: @@ -28,6 +29,7 @@ public:
void handleGetConfig(AsyncWebServerRequest* request);
void handleSetConfig(AsyncWebServerRequest* request);
void handleChangePassword(AsyncWebServerRequest* request);
void handleHealth(AsyncWebServerRequest* request);
void handleGetStats(AsyncWebServerRequest* request);
void handleOTAUpdate(AsyncWebServerRequest* request, String filename, size_t index, uint8_t* data, size_t len, bool final);
};

Loading…
Cancel
Save