fix(auth): machine_token não exige email+senha no socket + case-insensitive
continuous-integration/webhook Deploy concluído (VPS4)
continuous-integration/webhook Deploy concluído (VPS4)
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 <noreply@anthropic.com>
This commit is contained in:
+21
-12
@@ -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) {
|
||||
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(`✅ Conexão Socket.IO autorizada via machine_token - IP: ${socket.handshake.address}`);
|
||||
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 };
|
||||
|
||||
// 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
|
||||
}
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user