Actualizar server.js

This commit is contained in:
2026-03-08 18:01:07 +00:00
parent 53c38c07e2
commit 2bc71b80b7

103
server.js
View File

@@ -461,6 +461,109 @@ app.get("/auth/me", authMiddleware, async (req, res) => {
} }
}); });
// ==========================================
// 📝 REGISTRO DE NUEVAS EMPRESAS (SAAS)
// ==========================================
app.post("/auth/register", async (req, res) => {
try {
const { fullName, email, phone, password, dni, address } = req.body;
if (!email || !password || !fullName || !phone) {
return res.status(400).json({ ok: false, error: "Faltan datos obligatorios" });
}
const p = normalizePhone(phone);
// 1. Verificamos si el email o teléfono ya están en uso
const check = await pool.query("SELECT id FROM users WHERE email = $1 OR phone = $2", [email, p]);
if (check.rowCount > 0) {
return res.status(400).json({ ok: false, error: "El email o teléfono ya están registrados" });
}
const hash = await bcrypt.hash(password, 10);
// 2. Creamos al usuario como ADMIN (dueño de su propia empresa/instancia)
// Lo creamos como NO verificado hasta que ponga el código
const insert = await pool.query(`
INSERT INTO users (full_name, email, phone, password_hash, dni, address, role, status, is_verified)
VALUES ($1, $2, $3, $4, $5, $6, 'admin', 'active', FALSE)
RETURNING id
`, [fullName, email, p, hash, dni || null, address || null]);
const newUserId = insert.rows[0].id;
// 3. Le asignamos su propio ID como owner_id (es el jefe de su panel)
await pool.query("UPDATE users SET owner_id = $1 WHERE id = $2", [newUserId, newUserId]);
// 4. Generamos el código de 6 dígitos para el WhatsApp
const code = genCode6();
const codeHash = await bcrypt.hash(code, 10);
await pool.query(`
INSERT INTO login_codes (user_id, phone, code_hash, purpose, expires_at)
VALUES ($1, $2, $3, 'register_verify', NOW() + INTERVAL '15 minutes')
`, [newUserId, p, codeHash]);
// 5. Enviamos el WhatsApp usando la instancia principal (Aviso en consola por si Evolution no está listo)
console.log(`🔐 [SISTEMA] Código de verificación para ${p}: ${code}`);
const msg = `👋 *¡Bienvenido a IntegraRepara!*\n\nTu código de verificación es: *${code}*\n\nTiene una validez de 15 minutos.`;
// Intentamos enviarlo si la variable EVOLUTION_INSTANCE existe
if (process.env.EVOLUTION_INSTANCE) {
sendWhatsAppAuto(p, msg, process.env.EVOLUTION_INSTANCE, false).catch(console.error);
}
res.json({ ok: true, message: "Código enviado" });
} catch (e) {
console.error("Error en Registro:", e);
res.status(500).json({ ok: false, error: "Error interno del servidor" });
}
});
// ==========================================
// ✅ VERIFICACIÓN DEL CÓDIGO (OTP)
// ==========================================
app.post("/auth/verify", async (req, res) => {
try {
const { phone, code } = req.body;
const p = normalizePhone(phone);
// Buscamos códigos pendientes para ese teléfono
const q = await pool.query(`
SELECT c.*, u.id as u_id, u.full_name, u.role, u.owner_id
FROM login_codes c
JOIN users u ON c.user_id = u.id
WHERE c.phone = $1 AND c.consumed_at IS NULL AND c.expires_at > NOW()
ORDER BY c.created_at DESC LIMIT 1
`, [p]);
if (q.rowCount === 0) return res.status(400).json({ ok: false, error: "Código inválido o caducado" });
const codeRecord = q.rows[0];
const valid = await bcrypt.compare(code, codeRecord.code_hash);
if (!valid) return res.status(400).json({ ok: false, error: "Código incorrecto" });
// Marcamos código como usado y usuario como verificado
await pool.query("UPDATE login_codes SET consumed_at = NOW() WHERE id = $1", [codeRecord.id]);
await pool.query("UPDATE users SET is_verified = TRUE WHERE id = $1", [codeRecord.u_id]);
// Generamos su token de sesión para que entre directo
const token = signToken({
id: codeRecord.u_id,
email: codeRecord.email, // Aquí si usaras email en el token
phone: codeRecord.phone,
role: codeRecord.role,
owner_id: codeRecord.owner_id
});
res.json({ ok: true, token, user: { id: codeRecord.u_id, full_name: codeRecord.full_name, role: codeRecord.role } });
} catch (e) {
console.error("Error en Verificación:", e);
res.status(500).json({ ok: false, error: "Error en el servidor" });
}
});
// ========================================== // ==========================================
// 🕵️ ROBOT NOTARIO (TRAZABILIDAD TOTAL) // 🕵️ ROBOT NOTARIO (TRAZABILIDAD TOTAL)