Squelette d'application web pour ESP32 avec implémentations de fonctions basiques telles que : -Authentification -Responsive design -Mise à jour OTA -Paramétrage
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

251 lines
10 KiB

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Paramètres - ESP32 Webapp</title>
<link rel="stylesheet" href="/css/styles.css">
</head>
<body>
<nav class="navbar">
<div class="nav-brand">🔔 ESP32 Webapp</div>
<div class="nav-menu">
<a href="/index.html">Tableau de bord</a>
<a href="/settings.html" class="active">Paramètres</a>
<a href="/update.html">Mise à jour</a>
<a href="/logout">Déconnexion</a>
</div>
</nav>
<div class="container">
<h1>Paramètres</h1>
<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" 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">
</div>
<button type="submit" class="btn btn-primary">Enregistrer WiFi</button>
</form>
</div>
<div class="card">
<h2>Configuration système</h2>
<form id="systemForm">
<div class="form-group">
<label for="hostname">Nom d'hôte</label>
<input type="text" id="hostname" name="hostname">
</div>
<div class="form-group">
<label for="session_timeout">Timeout de session (minutes)</label>
<input type="number" id="session_timeout" name="session_timeout" min="1" max="1440">
</div>
<button type="submit" class="btn btn-primary">Enregistrer système</button>
</form>
</div>
<div class="card">
<h2>Changer le mot de passe</h2>
<form id="passwordForm">
<div class="form-group">
<label for="current_password">Mot de passe actuel</label>
<input type="password" id="current_password" name="current_password" required>
</div>
<div class="form-group">
<label for="new_password">Nouveau mot de passe</label>
<input type="password" id="new_password" name="new_password" required>
</div>
<div class="form-group">
<label for="confirm_password">Confirmer le mot de passe</label>
<input type="password" id="confirm_password" name="confirm_password" required>
</div>
<button type="submit" class="btn btn-primary">Changer le mot de passe</button>
</form>
</div>
<div id="message" class="message"></div>
</div>
<script src="/js/api.js"></script>
<script src="/js/crypto-js.min.js"></script>
<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 || '';
document.getElementById('session_timeout').value = config.system.session_timeout || 60;
} catch (error) {
showMessage('Erreur de chargement de la configuration', 'error');
}
}
function showMessage(text, type = 'info') {
const messageDiv = document.getElementById('message');
messageDiv.className = `message ${type}`;
messageDiv.textContent = text;
setTimeout(() => {
messageDiv.className = 'message';
messageDiv.textContent = '';
}, 5000);
}
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;
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;
if (apPassword) {
config.wifi.ap_password = apPassword;
}
try {
await api.setConfig(config);
showMessage('Configuration WiFi enregistrée. Redémarrage...', 'success');
} catch (error) {
showMessage('Erreur d\'enregistrement', 'error');
}
});
document.getElementById('wifi_security').addEventListener('change', toggleWifiSecurityFields);
document.getElementById('systemForm').addEventListener('submit', async (e) => {
e.preventDefault();
config.system.hostname = document.getElementById('hostname').value;
config.system.session_timeout = parseInt(document.getElementById('session_timeout').value);
try {
await api.setConfig(config);
showMessage('Configuration système enregistrée. Redémarrage...', 'success');
} catch (error) {
showMessage('Erreur d\'enregistrement', 'error');
}
});
document.getElementById('passwordForm').addEventListener('submit', async (e) => {
e.preventDefault();
const currentPassword = document.getElementById('current_password').value;
const newPassword = document.getElementById('new_password').value;
const confirmPassword = document.getElementById('confirm_password').value;
if (newPassword !== confirmPassword) {
showMessage('Les mots de passe ne correspondent pas', 'error');
return;
}
if (newPassword.length < 4) {
showMessage('Le mot de passe doit contenir au moins 4 caractères', 'error');
return;
}
// Calculer le hash SHA-256 du nouveau mot de passe avec CryptoJS
const hashHex = CryptoJS.SHA256(newPassword).toString();
const passwordConfig = {
auth: {
old_password: currentPassword,
password_hash: hashHex
}
};
try {
await api.changePassword(passwordConfig);
showMessage('Mot de passe changé avec succès. Redémarrage...', 'success');
setTimeout(() => {
window.location.href = '/logout';
}, 2000);
} catch (error) {
if (error.message.includes('401')) {
showMessage('Mot de passe actuel incorrect', 'error');
} else {
showMessage('Erreur de changement de mot de passe: ' + error.message, 'error');
}
}
});
loadConfig();
</script>
</body>
</html>