From 526f3f2eae20a07f00d55b00a4c0a4578c73d30c Mon Sep 17 00:00:00 2001 From: VPS 4 Deploy Agent Date: Sun, 31 May 2026 09:06:29 +0200 Subject: [PATCH] =?UTF-8?q?fix(auth):=20machine=5Ftoken=20n=C3=A3o=20exige?= =?UTF-8?q?=20email+senha=20no=20socket=20+=20case-insensitive?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bugs corrigidos: 1. Condição bloqueante: 'if (email && password && token.includes("-"))' fazia o machine_token ser ignorado se o client conectasse só com o token (sem email/senha). A conexão caía para o check de JWT, falhava e era rejeitada. Agora o machine_token é verificado sempre que o token contém hífens — email+senha são opcionais (validados se presentes, ignorados se ausentes). 2. Comparação de email case-sensitive: 'device.email === email' falhava se houver diferença de maiúsculas/minúsculas entre o cadastro e o config do client. Corrigido para .toLowerCase() em ambos os lados. 3. Log de autenticação: emite mensagem clara no console quando machine_token é aceito, incluindo nome da clínica e do PC, facilitando diagnóstico. Co-Authored-By: Claude Sonnet 4.6 --- dental-server/server.js | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/dental-server/server.js b/dental-server/server.js index 859e729..e70ccba 100644 --- a/dental-server/server.js +++ b/dental-server/server.js @@ -751,29 +751,38 @@ io.use(async (socket, next) => { return next(); // Token válido, prosseguir } - // 1.5 Verificar se é um machine_token (usado pelo novo app desktop 1.2.4+) - if (email && password && token.includes('-')) { + // 1.5 Verificar se é um machine_token (UUID com hífens — app desktop) + // O machine_token é credencial suficiente por si só (UUID único gerado pelo servidor). + // Se email+senha também forem enviados, valida os dois para compatibilidade. + if (token.includes('-')) { try { const device = await db.get(`SELECT * FROM clinics_devices WHERE machine_token = $1`, [token]); - if (device && device.email === email && device.is_active) { - const { verifyPassword } = require('./auth'); - const validPassword = await verifyPassword(password, device.password_hash); - if (validPassword) { - console.log(`✅ Conexão Socket.IO autorizada via machine_token - IP: ${socket.handshake.address}`); - socket.clientType = 'sensor'; - socket.user = { role: 'client_device', clinicId: device.id, clinicName: device.clinic_name, pcName: device.pc_name }; - - // Atualiza o último IP e data - await db.run(`UPDATE clinics_devices SET last_ip = $1 WHERE id = $2`, [socket.handshake.address, device.id]); - - return next(); // Credenciais válidas + if (device && device.is_active) { + // Se email e senha foram enviados, valida-os também (case-insensitive no email) + if (email && password) { + const emailMatch = device.email.toLowerCase() === email.trim().toLowerCase(); + if (!emailMatch) { + console.log(`❌ [machine_token] Email não confere para device id=${device.id}`); + return next(new Error('Authentication error: Invalid machine_token or credentials')); + } + const { verifyPassword } = require('./auth'); + const validPassword = await verifyPassword(password, device.password_hash); + if (!validPassword) { + console.log(`❌ [machine_token] Senha inválida para device id=${device.id}`); + return next(new Error('Authentication error: Invalid machine_token or credentials')); + } } + // machine_token válido (com ou sem email+senha) + console.log(`✅ [machine_token] Conexão autorizada — Clínica: ${device.clinic_name} PC: ${device.pc_name}`); + socket.clientType = 'sensor'; + socket.user = { role: 'client_device', clinicId: device.id, clinicName: device.clinic_name, pcName: device.pc_name }; + await db.run(`UPDATE clinics_devices SET last_ip = $1 WHERE id = $2`, [socket.handshake.address, device.id]); + return next(); } + // Token com hífens mas não é machine_token → pode ser JWT, deixa prosseguir } catch (e) { console.error('Erro ao validar machine_token no socket:', e); } - console.log(`❌ Conexão Socket.IO rejeitada (Machine Token inválido) - IP: ${socket.handshake.address}`); - return next(new Error('Authentication error: Invalid machine_token or credentials')); } // 2. Se não for a API_KEY, tentar validar como JWT (Painel Web ou Novo App Desktop)