Actualizar server.js

This commit is contained in:
2026-03-14 17:03:26 +00:00
parent c9605c9497
commit 3720a709d8

View File

@@ -905,6 +905,77 @@ async function procesarConIA(ownerId, mensajeCliente, datosExpediente) {
}
}
// ==========================================
// 🔐 OTP PARA CLIENTES (VERIFICACIÓN WHATSAPP)
// ==========================================
// 1. Solicitar el código de 4 cifras
app.post("/public/auth/request-otp", async (req, res) => {
try {
const { phone, owner_id } = req.body;
if (!phone) return res.status(400).json({ ok: false });
const targetOwnerId = owner_id || 1;
const cleanPhone = phone.replace(/\D/g, "");
// Generar código de 4 cifras (ej: 4829)
const code = String(Math.floor(1000 + Math.random() * 9000));
const hash = await bcrypt.hash(code, 10);
// Guardamos el código (dejamos user_id nulo porque es un cliente externo)
await pool.query(`
INSERT INTO login_codes (phone, code_hash, purpose, expires_at)
VALUES ($1, $2, 'client_portal', NOW() + INTERVAL '15 minutes')
`, [cleanPhone, hash]);
// Enviar el WhatsApp
const msg = `🔐 Tu código de acceso para solicitar asistencia es: *${code}*\n\nSi no has solicitado este código, ignora este mensaje.`;
sendWhatsAppAuto("34" + cleanPhone, msg, `cliente_${targetOwnerId}`, false).catch(console.error);
res.json({ ok: true });
} catch(e) {
console.error("Error OTP Request:", e);
res.status(500).json({ ok: false });
}
});
// 2. Verificar el código y comprobar si el cliente existe
app.post("/public/auth/verify-otp", async (req, res) => {
try {
const { phone, code, owner_id } = req.body;
const cleanPhone = phone.replace(/\D/g, "");
const targetOwnerId = owner_id || 1;
// Buscamos el último código válido
const q = await pool.query(`
SELECT id, code_hash FROM login_codes
WHERE phone = $1 AND purpose = 'client_portal' AND consumed_at IS NULL AND expires_at > NOW()
ORDER BY created_at DESC LIMIT 1
`, [cleanPhone]);
if (q.rowCount === 0) return res.status(400).json({ ok: false, error: "Código inválido o caducado" });
// Comparamos el código que ha puesto el cliente con el de la BBDD
const valid = await bcrypt.compare(code, q.rows[0].code_hash);
if (!valid) return res.status(400).json({ ok: false, error: "Código incorrecto" });
// Lo marcamos como usado
await pool.query("UPDATE login_codes SET consumed_at = NOW() WHERE id = $1", [q.rows[0].id]);
// VERIFICAMOS SI EL CLIENTE YA EXISTE EN NUESTRA BASE DE DATOS
const qClient = await pool.query("SELECT id, full_name, addresses, portal_token FROM clients WHERE phone LIKE $1 AND owner_id = $2 LIMIT 1", [`%${cleanPhone}%`, targetOwnerId]);
if (qClient.rowCount > 0) {
res.json({ ok: true, exists: true, client: qClient.rows[0] });
} else {
res.json({ ok: true, exists: false });
}
} catch(e) {
console.error("Error OTP Verify:", e);
res.status(500).json({ ok: false });
}
});
// ==========================================
// 🌐 EMBUDO PÚBLICO DE ENTRADA DE CLIENTES
// ==========================================