diff --git a/dental-server/auth.js b/dental-server/auth.js index 1b16349..b4e2730 100644 --- a/dental-server/auth.js +++ b/dental-server/auth.js @@ -68,6 +68,7 @@ function generateToken(user, expiresIn = JWT_EXPIRES_IN) { { id: user.id, username: user.username, + email: user.email, is_admin: user.is_admin }, JWT_SECRET, diff --git a/dental-server/public/admin-clinics.js b/dental-server/public/admin-clinics.js index 4c8441d..ba1d897 100644 --- a/dental-server/public/admin-clinics.js +++ b/dental-server/public/admin-clinics.js @@ -44,13 +44,20 @@ document.addEventListener('DOMContentLoaded', () => { try { const response = await fetch(API_URL, fetchOptions); - // Se recebeu 401 ou 403, token expirou — vai para login - if (response.status === 401 || response.status === 403) { + // Se recebeu 401, token expirou ou é inválido — vai para login + if (response.status === 401) { localStorage.removeItem('auth_token'); window.location.href = '/login'; return; } + // Se recebeu 403, acesso proibido (não admin) — volta para a home + if (response.status === 403) { + alert('Acesso negado. Esta área é restrita a administradores.'); + window.location.href = '/'; + return; + } + // Verificar se a resposta é realmente JSON (evita erro com HTML) const contentType = response.headers.get('content-type') || ''; if (!contentType.includes('application/json')) { diff --git a/dental-server/public/app.js b/dental-server/public/app.js index 569680e..8a81160 100644 --- a/dental-server/public/app.js +++ b/dental-server/public/app.js @@ -55,6 +55,8 @@ async function verifyAuth() { if (data.valid) { const isAdmin = !!data.user.is_admin; localStorage.setItem('is_admin', isAdmin ? 'true' : 'false'); + localStorage.setItem('username', data.user.username || ''); + localStorage.setItem('email', data.user.email || ''); // Controle de visibilidade de itens de menu updateAdminMenuVisibility(isAdmin); @@ -1122,9 +1124,10 @@ function openSettingsModal() { const modal = document.getElementById('settingsModal'); if (modal) modal.style.display = 'block'; - // Limpar form + // Limpar form e carregar valores atuais document.getElementById('currentPassword').value = ''; - document.getElementById('newUsername').value = ''; + document.getElementById('newUsername').value = localStorage.getItem('username') || ''; + document.getElementById('newEmail').value = localStorage.getItem('email') || ''; document.getElementById('newPassword').value = ''; } @@ -1138,6 +1141,7 @@ async function updateCredentials(event) { const currentPassword = document.getElementById('currentPassword').value; const newUsername = document.getElementById('newUsername').value.trim(); + const newEmail = document.getElementById('newEmail').value.trim(); const newPassword = document.getElementById('newPassword').value; if (!currentPassword) { @@ -1145,8 +1149,8 @@ async function updateCredentials(event) { return; } - if (!newUsername && !newPassword) { - showToast('Preencha um novo usuário ou nova senha.', 'error'); + if (!newUsername && !newEmail && !newPassword) { + showToast('Preencha um novo usuário, e-mail ou nova senha.', 'error'); return; } @@ -1163,7 +1167,7 @@ async function updateCredentials(event) { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, - body: JSON.stringify({ currentPassword, newUsername, newPassword }) + body: JSON.stringify({ currentPassword, newUsername, newEmail, newPassword }) }); const data = await res.json(); @@ -1178,6 +1182,11 @@ async function updateCredentials(event) { // Atualizar token no localStorage se tiver um novo if (data.token) { localStorage.setItem('auth_token', data.token); + // Salvar novos dados locais decodificando token ou usando retorno + if (data.user) { + localStorage.setItem('username', data.user.username || ''); + localStorage.setItem('email', data.user.email || ''); + } } closeSettingsModal(); @@ -1208,6 +1217,8 @@ function openUserManagementModal() { document.getElementById('new_username').value = ''; document.getElementById('new_email').value = ''; document.getElementById('new_password').value = ''; + const isCheck = document.getElementById('new_is_admin'); + if (isCheck) isCheck.checked = false; loadUsersList(); } @@ -1275,6 +1286,8 @@ async function createUser(event) { const username = document.getElementById('new_username').value.trim(); const email = document.getElementById('new_email').value.trim(); const password = document.getElementById('new_password').value; + const isCheck = document.getElementById('new_is_admin'); + const is_admin = isCheck ? isCheck.checked : false; if (!username || !email || !password) { showToast('Todos os campos obrigatórios.', 'error'); @@ -1294,7 +1307,7 @@ async function createUser(event) { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, - body: JSON.stringify({ username, email, password }) + body: JSON.stringify({ username, email, password, is_admin }) }); const data = await res.json(); @@ -1306,6 +1319,7 @@ async function createUser(event) { document.getElementById('new_username').value = ''; document.getElementById('new_email').value = ''; document.getElementById('new_password').value = ''; + if (isCheck) isCheck.checked = false; // Atualizar lista loadUsersList(); diff --git a/dental-server/public/clients.html b/dental-server/public/clients.html index 12c816c..86e4cc7 100644 --- a/dental-server/public/clients.html +++ b/dental-server/public/clients.html @@ -287,8 +287,25 @@ } async function loadClients() { + const token = localStorage.getItem('auth_token') || ''; try { - const response = await fetch('/api/socket/status'); + const response = await fetch('/api/socket/status', { + headers: { + 'Authorization': `Bearer ${token}` + } + }); + + if (response.status === 401) { + localStorage.removeItem('auth_token'); + window.location.href = '/login'; + return; + } + if (response.status === 403) { + alert('Acesso negado. Esta área é restrita a administradores.'); + window.location.href = '/'; + return; + } + const data = await response.json(); // Atualizar stats @@ -404,6 +421,8 @@ testBtn.disabled = true; testBtn.innerHTML = ' Testando...'; + const token = localStorage.getItem('auth_token') || ''; + try { // Limpar resultados anteriores testResults = {}; @@ -413,10 +432,22 @@ const response = await fetch('/api/socket/test-connection', { method: 'POST', headers: { - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${token}` } }); + if (response.status === 401) { + localStorage.removeItem('auth_token'); + window.location.href = '/login'; + return; + } + if (response.status === 403) { + alert('Acesso negado. Esta área é restrita a administradores.'); + window.location.href = '/'; + return; + } + const result = await response.json(); // Processar resultados diff --git a/dental-server/public/index.html b/dental-server/public/index.html index c96672b..ba09666 100644 --- a/dental-server/public/index.html +++ b/dental-server/public/index.html @@ -311,7 +311,12 @@ -