const express = require('express'); const router = express.Router(); const db = require('../database'); const bcrypt = require('bcrypt'); const jwt = require('jsonwebtoken'); // Usa a chave JWT existente, ou um valor de fallback seguro se não configurado const JWT_SECRET = process.env.JWT_SECRET || 'fallback_secret_dental_2026_super_secure'; // ============================================================== // 1. LOGIN DO CLIENTE (APP DESKTOP) // ============================================================== router.post('/login', async (req, res) => { const { email, password, machine_token } = req.body; if (!email || !password || !machine_token) { return res.status(400).json({ success: false, message: 'Email, Senha e Token da Máquina são obrigatórios' }); } try { // 1. Buscar o dispositivo pelo Token const device = await db.get(`SELECT * FROM clinics_devices WHERE machine_token = ?`, [machine_token]); if (!device) { return res.status(401).json({ success: false, message: 'Token da máquina inválido ou inexistente' }); } // 2. Verificar se o acesso está ativo if (!device.is_active) { return res.status(403).json({ success: false, message: 'O acesso desta máquina foi desativado pelo administrador' }); } // 3. Verificar o Email if (device.email !== email) { return res.status(401).json({ success: false, message: 'Email incorreto para esta máquina' }); } // 4. Verificar a Senha const validPassword = await bcrypt.compare(password, device.password_hash); if (!validPassword) { return res.status(401).json({ success: false, message: 'Senha incorreta' }); } // Atualizar último IP conectado const clientIp = req.headers['x-forwarded-for'] || req.socket.remoteAddress; await db.run(`UPDATE clinics_devices SET last_ip = ? WHERE id = ?`, [clientIp, device.id]); // 5. Gerar Token JWT de Sessão // O Token vale por 2 horas, obrigando o cliente a re-logar ou pedir refresh const sessionToken = jwt.sign( { clinicId: device.id, clinicName: device.clinic_name, pcName: device.pc_name, role: 'client_device' }, JWT_SECRET, { expiresIn: '2h' } ); res.json({ success: true, message: 'Login aprovado', token: sessionToken, clinic: { name: device.clinic_name, pc: device.pc_name } }); } catch (error) { console.error('Erro no login do cliente:', error); res.status(500).json({ success: false, message: 'Erro interno de servidor' }); } }); // ============================================================== // 2. MIDDLEWARE DE VALIDAÇÃO (Para usar nas rotas de Upload) // ============================================================== const requireClientAuth = (req, res, next) => { const authHeader = req.headers.authorization; if (!authHeader || !authHeader.startsWith('Bearer ')) { return res.status(401).json({ success: false, message: 'Token JWT não fornecido' }); } const token = authHeader.split(' ')[1]; try { const decoded = jwt.verify(token, JWT_SECRET); if (decoded.role !== 'client_device') { return res.status(403).json({ success: false, message: 'Acesso negado: Perfil inválido' }); } // Anexar info ao request para uso posterior req.clientDevice = decoded; next(); } catch (error) { if (error.name === 'TokenExpiredError') { return res.status(401).json({ success: false, message: 'Sessão expirada. Faça login novamente.', expired: true }); } return res.status(401).json({ success: false, message: 'Token JWT inválido' }); } }; module.exports = { router, requireClientAuth, JWT_SECRET };