feat(auth): token-first — device-info endpoint + pc_name autoritativo
continuous-integration/webhook Deploy concluído (VPS4)
continuous-integration/webhook Deploy concluído (VPS4)
- GET /api/auth/device-info?token=xxx: valida machine_token e retorna clinic_name e pc_name sem exigir email/senha. Usado pelo client para preview antes de salvar e para validação no save. - client-identify: quando autenticado via machine_token, usa socket.user.pcName como nome autoritativo (ignora o que o client enviou). - server-identified: clientInfo agora inclui 'pcName' para o client manter o nome em sincronia com o cadastro do servidor. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+23
-3
@@ -458,6 +458,24 @@ TRUST_PROXY=true
|
||||
app.use('/api/auth', authRoutes);
|
||||
app.use('/api/client', clientAuthRoutes);
|
||||
|
||||
// GET /api/auth/device-info?token=xxx — valida machine_token e retorna info do dispositivo.
|
||||
// Usado pelo client para verificar o token antes de salvar (sem precisar de email/senha).
|
||||
app.get('/api/auth/device-info', async (req, res) => {
|
||||
try {
|
||||
const token = (req.query.token || '').trim();
|
||||
if (!token) return res.status(400).json({ success: false, error: 'Token obrigatório.' });
|
||||
const device = await db.get(
|
||||
'SELECT clinic_name, pc_name, email, is_active FROM clinics_devices WHERE machine_token = $1',
|
||||
[token]
|
||||
);
|
||||
if (!device) return res.status(404).json({ success: false, error: 'Token não encontrado.' });
|
||||
if (!device.is_active) return res.status(403).json({ success: false, error: 'Dispositivo desativado.' });
|
||||
res.json({ success: true, clinicName: device.clinic_name, pcName: device.pc_name });
|
||||
} catch (e) {
|
||||
res.status(500).json({ success: false, error: e.message });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// ================================================================
|
||||
// MIDDLEWARE DE VERIFICAÇÃO DE INSTALAÇÃO (APENAS PARA APIs)
|
||||
@@ -839,13 +857,14 @@ io.on('connection', (socket) => {
|
||||
console.log('👤 Cliente identificado:', data?.type || 'SEM TYPE', data?.name || 'SEM NAME');
|
||||
console.log('👤 Dados completos:', JSON.stringify(data, null, 2));
|
||||
|
||||
if (!data || !data.type || !data.name) {
|
||||
if (!data || !data.type) {
|
||||
console.error('❌ [client-identify] Dados inválidos:', data);
|
||||
socket.emit('error', { message: 'Dados de identificação inválidos' });
|
||||
return;
|
||||
}
|
||||
|
||||
const clientName = data.name.trim();
|
||||
|
||||
// Se autenticado via machine_token, o pc_name do cadastro é autoritativo
|
||||
const clientName = (socket.user?.pcName || data.name || 'PC não identificado').trim();
|
||||
const clientId = data.clientId || '';
|
||||
|
||||
// 1. Validar unicidade em relação aos clientes já conectados
|
||||
@@ -887,6 +906,7 @@ io.on('connection', (socket) => {
|
||||
type: data.type || 'unknown',
|
||||
name: clientName,
|
||||
clinicName: socket.user?.clinicName || (data.clinicName || '').trim() || 'Clínica não identificada',
|
||||
pcName: socket.user?.pcName || clientName,
|
||||
version: data.version || '1.0.0',
|
||||
system: data.system || 'unknown',
|
||||
clientId: clientId,
|
||||
|
||||
Reference in New Issue
Block a user