// Configuration API
const API_URL = 'http://localhost:4001/api';
// State
let currentUser = null;
let isAuthenticated = false;
// Initialisation
document.addEventListener('DOMContentLoaded', () => {
checkAuth();
});
// Vérifier l'authentification
async function checkAuth() {
try {
const response = await fetch(`${API_URL}/auth/check`, {
credentials: 'include'
});
const data = await response.json();
if (data.authenticated) {
currentUser = data.user;
isAuthenticated = true;
showDashboard();
} else {
showLoginPage();
}
} catch (e) {
console.error('Erreur vérification auth:', e);
showLoginPage();
}
}
// Afficher la page de connexion
function showLoginPage() {
document.getElementById('app').innerHTML = `
`;
// Vérifier s'il y a déjà un admin
checkIfAdminExists();
}
// Vérifier si un admin existe
async function checkIfAdminExists() {
try {
const response = await fetch(`${API_URL}/auth/check`, {
credentials: 'include'
});
// Si pas connecté, afficher le formulaire d'enregistrement si c'est la première fois
setTimeout(() => {
const regForm = document.getElementById('registerForm');
const loginForm = document.getElementById('loginForm');
if (regForm && loginForm) {
// Pour la première connexion, montrer le formulaire d'enregistrement
regForm.style.display = 'block';
loginForm.style.display = 'none';
}
}, 100);
} catch (e) {
console.error('Erreur:', e);
}
}
// Connexion
async function handleLogin() {
const username = document.getElementById('username').value;
const password = document.getElementById('password').value;
if (!username || !password) {
showMessage('Veuillez remplir tous les champs', 'error', 'loginMessage');
return;
}
try {
const response = await fetch(`${API_URL}/auth/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
body: JSON.stringify({ username, password })
});
const data = await response.json();
if (response.ok) {
currentUser = data.user;
isAuthenticated = true;
showDashboard();
} else {
showMessage(data.error || 'Erreur de connexion', 'error', 'loginMessage');
}
} catch (e) {
console.error('Erreur connexion:', e);
showMessage('Erreur serveur', 'error', 'loginMessage');
}
}
// Enregistrement
async function handleRegister() {
const username = document.getElementById('regUsername').value;
const password = document.getElementById('regPassword').value;
const mcUsername = document.getElementById('mcUsername').value;
if (!username || !password || !mcUsername) {
showMessage('Veuillez remplir tous les champs', 'error', 'loginMessage');
return;
}
try {
const response = await fetch(`${API_URL}/auth/register`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
body: JSON.stringify({ username, password, mcUsername })
});
const data = await response.json();
if (response.ok) {
showMessage('Compte créé! Connectez-vous maintenant.', 'success', 'loginMessage');
setTimeout(() => {
document.getElementById('registerForm').style.display = 'none';
document.getElementById('loginForm').style.display = 'block';
document.getElementById('username').value = username;
document.getElementById('password').value = '';
}, 1000);
} else {
showMessage(data.error || 'Erreur d\'enregistrement', 'error', 'loginMessage');
}
} catch (e) {
console.error('Erreur enregistrement:', e);
showMessage('Erreur serveur', 'error', 'loginMessage');
}
}
// Afficher le dashboard
function showDashboard() {
document.getElementById('app').innerHTML = `
${getDashboardHTML()}
${getConsoleHTML()}
${getLogsHTML()}
${getPlayersHTML()}
${getWhitelistHTML()}
${getBackupsHTML()}
${getSettingsHTML()}
`;
// Charger les données
loadDashboardData();
}
// Changer d'onglet
function switchTab(tabName) {
// Masquer tous les onglets
document.querySelectorAll('.content-section').forEach(el => {
el.classList.remove('active');
});
// Afficher l'onglet sélectionné
document.getElementById(tabName).classList.add('active');
// Mettre à jour les boutons
document.querySelectorAll('.nav-tabs button').forEach(btn => {
btn.classList.remove('active');
});
event.target.classList.add('active');
// Charger les données spécifiques
if (tabName === 'console') loadConsoleData();
if (tabName === 'logs') loadLogsData();
if (tabName === 'players') loadPlayersData();
if (tabName === 'whitelist') loadWhitelistData();
if (tabName === 'backups') loadBackupsData();
if (tabName === 'settings') loadSettingsData();
}
// ========== DASHBOARD ==========
function getDashboardHTML() {
return `
🎮 Contrôle du Serveur
`;
}
async function loadDashboardData() {
try {
const response = await fetch(`${API_URL}/server`, {
credentials: 'include'
});
const data = await response.json();
if (data.properties) {
const table = document.getElementById('quickInfoTable');
table.innerHTML = `
| Nom Serveur | ${data.properties['motd'] || 'NationsGlory'} |
| Mode Jeu | ${data.properties['gamemode'] || 'Survival'} |
| Difficulté | ${data.properties['difficulty'] || '2'} |
| PvP | ${data.properties['pvp'] === 'true' ? 'Activé' : 'Désactivé'} |
| Port | ${data.properties['server-port'] || '25565'} |
| Max Joueurs | ${data.properties['max-players'] || '20'} |
`;
}
} catch (e) {
console.error('Erreur chargement dashboard:', e);
}
}
// ========== CONSOLE RCON ==========
function getConsoleHTML() {
return `
⌨️ Console RCON
Exécutez des commandes directement sur le serveur
Historique
`;
}
async function loadConsoleData() {
try {
const response = await fetch(`${API_URL}/rcon/history`, {
credentials: 'include'
});
const history = await response.json();
const container = document.getElementById('historyContainer');
container.innerHTML = history.map(h => `
${h.command}
${new Date(h.timestamp).toLocaleTimeString()}
`).join('') || 'Aucun historique
';
} catch (e) {
console.error('Erreur historique:', e);
}
}
async function sendRconCommand() {
const commandInput = document.getElementById('commandInput');
const command = commandInput.value.trim();
if (!command) return;
const output = document.getElementById('consoleOutput');
output.innerHTML += `$ ${command}
`;
commandInput.value = '';
try {
const response = await fetch(`${API_URL}/rcon/command`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
body: JSON.stringify({ command })
});
const data = await response.json();
if (response.ok) {
output.innerHTML += `${data.response}
`;
showMessage('Commande exécutée', 'success', 'dashboardMessage');
} else {
output.innerHTML += `Erreur: ${data.error}
`;
showMessage(data.error, 'error', 'dashboardMessage');
}
output.scrollTop = output.scrollHeight;
} catch (e) {
console.error('Erreur envoi commande:', e);
output.innerHTML += `Erreur serveur
`;
showMessage('Erreur serveur', 'error', 'dashboardMessage');
}
}
// ========== LOGS ==========
function getLogsHTML() {
return `
📜 Logs
`;
}
async function loadLogsData() {
try {
const response = await fetch(`${API_URL}/logs?lines=200`, {
credentials: 'include'
});
const data = await response.json();
const container = document.getElementById('logsContainer');
container.innerHTML = data.logs.map((line, idx) => {
let className = '';
if (line.includes('ERROR')) className = 'error';
else if (line.includes('WARN')) className = 'warning';
return `${escapeHtml(line)}
`;
}).join('');
container.scrollTop = container.scrollHeight;
} catch (e) {
console.error('Erreur chargement logs:', e);
document.getElementById('logsContainer').innerHTML = 'Erreur chargement
';
}
}
async function reloadLogs() {
showMessage('Rechargement...', 'success', 'dashboardMessage');
await loadLogsData();
showMessage('Logs rechargés', 'success', 'dashboardMessage');
}
function openSearchLogsModal() {
const query = prompt('Chercher dans les logs:');
if (query) searchLogs(query);
}
async function searchLogs(query) {
try {
const response = await fetch(`${API_URL}/logs/search?query=${encodeURIComponent(query)}`, {
credentials: 'include'
});
const data = await response.json();
const container = document.getElementById('logsContainer');
container.innerHTML = data.results.map((r, idx) => `
[${r.index}] ${escapeHtml(r.line)}
`).join('');
} catch (e) {
console.error('Erreur recherche:', e);
}
}
// ========== JOUEURS ==========
function getPlayersHTML() {
return `
👥 Joueurs Connectés
Liste des joueurs qui se sont connectés
| Nom |
UUID |
Dernière Connexion |
| Chargement... |
`;
}
async function loadPlayersData() {
try {
const response = await fetch(`${API_URL}/players`, {
credentials: 'include'
});
const data = await response.json();
const table = document.getElementById('playersTable');
if (data.players.length > 0) {
table.innerHTML = data.players.map(p => `
| ${p.name} |
${p.uuid} |
${new Date(p.lastPlayed).toLocaleString()} |
`).join('');
} else {
table.innerHTML = '| Aucun joueur |
';
}
} catch (e) {
console.error('Erreur joueurs:', e);
document.getElementById('playersTable').innerHTML = '| Erreur |
';
}
}
// ========== WHITELIST ==========
function getWhitelistHTML() {
return `
✅ Whitelist
| Joueur |
Actions |
| Chargement... |
`;
}
async function loadWhitelistData() {
try {
const response = await fetch(`${API_URL}/whitelist`, {
credentials: 'include'
});
const data = await response.json();
const table = document.getElementById('whitelistTable');
if (data.whitelist && data.whitelist.length > 0) {
const players = data.whitelist.map(w => typeof w === 'string' ? w : w.name);
table.innerHTML = players.map(p => `
| ${p} |
|
`).join('');
} else {
table.innerHTML = '| Whitelist vide |
';
}
} catch (e) {
console.error('Erreur whitelist:', e);
document.getElementById('whitelistTable').innerHTML = '| Erreur |
';
}
}
function openAddWhitelistModal() {
const username = prompt('Nom du joueur à ajouter:');
if (username) addToWhitelist(username);
}
async function addToWhitelist(username) {
try {
const response = await fetch(`${API_URL}/whitelist/add`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
body: JSON.stringify({ username })
});
const data = await response.json();
if (response.ok) {
showMessage(`${username} ajouté à la whitelist`, 'success', 'dashboardMessage');
loadWhitelistData();
} else {
showMessage(data.error, 'error', 'dashboardMessage');
}
} catch (e) {
console.error('Erreur:', e);
showMessage('Erreur serveur', 'error', 'dashboardMessage');
}
}
async function removeFromWhitelist(username) {
if (!confirm(`Confirmer la suppression de ${username}?`)) return;
try {
const response = await fetch(`${API_URL}/whitelist/remove`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
body: JSON.stringify({ username })
});
const data = await response.json();
if (response.ok) {
showMessage(`${username} retiré de la whitelist`, 'success', 'dashboardMessage');
loadWhitelistData();
} else {
showMessage(data.error, 'error', 'dashboardMessage');
}
} catch (e) {
console.error('Erreur:', e);
showMessage('Erreur serveur', 'error', 'dashboardMessage');
}
}
async function reloadWhitelist() {
showMessage('Rechargement...', 'success', 'dashboardMessage');
await loadWhitelistData();
showMessage('Whitelist rechargée', 'success', 'dashboardMessage');
}
// ========== BACKUPS ==========
function getBackupsHTML() {
return `
💾 Backups
| Nom |
Taille |
Date |
Actions |
| Chargement... |
`;
}
async function loadBackupsData() {
try {
const response = await fetch(`${API_URL}/backup`, {
credentials: 'include'
});
const data = await response.json();
const table = document.getElementById('backupsTable');
if (Array.isArray(data) && data.length > 0) {
table.innerHTML = data.map(b => `
| ${b.name} |
${b.size} |
${new Date(b.created).toLocaleString()} |
|
`).join('');
} else {
table.innerHTML = '| Aucun backup |
';
}
} catch (e) {
console.error('Erreur backups:', e);
document.getElementById('backupsTable').innerHTML = '| Erreur |
';
}
}
async function createBackup() {
if (!confirm('Créer un nouveau backup? (cela peut prendre du temps)')) return;
showMessage('Création du backup en cours...', 'success', 'dashboardMessage');
try {
const response = await fetch(`${API_URL}/backup/create`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
body: JSON.stringify({})
});
const data = await response.json();
if (response.ok) {
showMessage(data.message, 'success', 'dashboardMessage');
setTimeout(() => loadBackupsData(), 2000);
} else {
showMessage(data.error, 'error', 'dashboardMessage');
}
} catch (e) {
console.error('Erreur:', e);
showMessage('Erreur serveur', 'error', 'dashboardMessage');
}
}
async function deleteBackup(filename) {
if (!confirm(`Confirmer la suppression du backup ${filename}?`)) return;
try {
const response = await fetch(`${API_URL}/backup/delete/${filename}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
body: JSON.stringify({})
});
const data = await response.json();
if (response.ok) {
showMessage('Backup supprimé', 'success', 'dashboardMessage');
loadBackupsData();
} else {
showMessage(data.error, 'error', 'dashboardMessage');
}
} catch (e) {
console.error('Erreur:', e);
showMessage('Erreur serveur', 'error', 'dashboardMessage');
}
}
async function reloadBackups() {
showMessage('Rechargement...', 'success', 'dashboardMessage');
await loadBackupsData();
showMessage('Backups rechargés', 'success', 'dashboardMessage');
}
// ========== PARAMÈTRES ==========
function getSettingsHTML() {
return `
⚙️ Paramètres du Serveur
| Paramètre |
Valeur |
| Chargement... |
`;
}
async function loadSettingsData() {
try {
const response = await fetch(`${API_URL}/server`, {
credentials: 'include'
});
const data = await response.json();
const table = document.getElementById('settingsTable');
const tbody = table.querySelector('tbody');
if (data.properties) {
const keys = Object.keys(data.properties).sort();
tbody.innerHTML = keys.map(k => `
| ${k} |
${escapeHtml(data.properties[k])} |
`).join('');
}
} catch (e) {
console.error('Erreur paramètres:', e);
}
}
// ========== ACTIONS ==========
async function restartServer() {
if (!confirm('⚠️ Redémarrer le serveur? Les joueurs seront déconnectés.')) return;
showMessage('Redémarrage du serveur...', 'success', 'dashboardMessage');
try {
const response = await fetch(`${API_URL}/rcon/restart`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
body: JSON.stringify({})
});
const data = await response.json();
if (response.ok) {
showMessage(data.message, 'success', 'dashboardMessage');
} else {
showMessage(data.error, 'error', 'dashboardMessage');
}
} catch (e) {
console.error('Erreur:', e);
showMessage('Erreur serveur', 'error', 'dashboardMessage');
}
}
async function saveServer() {
showMessage('Sauvegarde du serveur...', 'success', 'dashboardMessage');
try {
const response = await fetch(`${API_URL}/rcon/save`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
body: JSON.stringify({})
});
const data = await response.json();
if (response.ok) {
showMessage(data.message, 'success', 'dashboardMessage');
} else {
showMessage(data.error, 'error', 'dashboardMessage');
}
} catch (e) {
console.error('Erreur:', e);
showMessage('Erreur serveur', 'error', 'dashboardMessage');
}
}
function openChangeRconPasswordModal() {
const oldPassword = prompt('Ancien mot de passe RCON:');
if (!oldPassword) return;
const newPassword = prompt('Nouveau mot de passe RCON:');
if (!newPassword) return;
changeRconPassword(oldPassword, newPassword);
}
async function changeRconPassword(oldPassword, newPassword) {
try {
const response = await fetch(`${API_URL}/auth/change-rcon-password`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
body: JSON.stringify({ oldPassword, newPassword })
});
const data = await response.json();
if (response.ok) {
showMessage(data.message, 'success', 'dashboardMessage');
} else {
showMessage(data.error, 'error', 'dashboardMessage');
}
} catch (e) {
console.error('Erreur:', e);
showMessage('Erreur serveur', 'error', 'dashboardMessage');
}
}
// ========== UTILITAIRES ==========
function showMessage(text, type, elementId) {
const element = document.getElementById(elementId);
if (element) {
element.textContent = text;
element.className = `message show ${type}`;
setTimeout(() => {
element.classList.remove('show');
}, 4000);
}
}
function escapeHtml(text) {
const map = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
};
return text.replace(/[&<>"']/g, m => map[m]);
}
// Déconnexion
async function handleLogout() {
try {
await fetch(`${API_URL}/auth/logout`, {
method: 'POST',
credentials: 'include'
});
checkAuth();
} catch (e) {
console.error('Erreur:', e);
}
}