From 8c23d54452ebd932c16c58403996301299421896 Mon Sep 17 00:00:00 2001 From: marsalva Date: Sun, 8 Feb 2026 11:42:30 +0000 Subject: [PATCH] Actualizar server.js --- server.js | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/server.js b/server.js index 2531537..01edc55 100644 --- a/server.js +++ b/server.js @@ -40,8 +40,8 @@ async function autoUpdateDB() { CREATE TABLE IF NOT EXISTS users ( id SERIAL PRIMARY KEY, full_name TEXT NOT NULL, - phone TEXT NOT NULL, -- ELIMINADO 'UNIQUE' EN DEFINICIÓN (Se gestiona abajo) - email TEXT UNIQUE NOT NULL, + phone TEXT NOT NULL, + email TEXT NOT NULL, -- MODIFICADO: YA NO ES UNIQUE GLOBALMENTE dni TEXT, address TEXT, password_hash TEXT NOT NULL, @@ -80,16 +80,10 @@ async function autoUpdateDB() { ); `); - // --- CORRECCIÓN MULTITENANT --- - // Eliminamos la restricción global de teléfono único si existe para permitir - // que el mismo teléfono esté en varias empresas. - try { - await client.query(`ALTER TABLE users DROP CONSTRAINT IF EXISTS users_phone_key`); - } catch (e) { - // Ignoramos si no existe o hay error menor - } + // Parches y correcciones de restricciones (Multitenancy) + try { await client.query(`ALTER TABLE users DROP CONSTRAINT IF EXISTS users_phone_key`); } catch (e) {} + try { await client.query(`ALTER TABLE users DROP CONSTRAINT IF EXISTS users_email_key`); } catch (e) {} // NUEVO: Elimina restricción global de email - // Parches await client.query(` DO $$ BEGIN IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='users' AND column_name='role') THEN @@ -165,18 +159,16 @@ app.post("/auth/register", async (req, res) => { const passwordHash = await bcrypt.hash(password, 10); await client.query('BEGIN'); - // Verificamos Email (Que debe ser único globalmente para login) - const checkUser = await client.query("SELECT * FROM users WHERE email = $1", [email]); + const checkUser = await client.query("SELECT * FROM users WHERE email = $1 OR phone = $2", [email, p]); let userId; if (checkUser.rowCount > 0) { const existing = checkUser.rows[0]; - // Si existe y ya está verificado, error. if (existing.is_verified) { await client.query('ROLLBACK'); - return res.status(409).json({ ok: false, error: "El email ya está registrado." }); + return res.status(409).json({ ok: false, error: "Usuario ya registrado." }); } - await client.query("UPDATE users SET full_name=$1, address=$2, dni=$3, password_hash=$4, phone=$5 WHERE id=$6", [fullName, address, dni, passwordHash, p, existing.id]); + await client.query("UPDATE users SET full_name=$1, address=$2, dni=$3, password_hash=$4 WHERE id=$5", [fullName, address, dni, passwordHash, existing.id]); userId = existing.id; } else { const insert = await client.query( @@ -220,12 +212,23 @@ app.post("/auth/verify", async (req, res) => { app.post("/auth/login", async (req, res) => { try { const { email, password } = req.body; + // Buscamos TODOS los usuarios con ese email (puede haber varios en distintas empresas) const q = await pool.query("SELECT * FROM users WHERE email=$1", [email]); + if (q.rowCount === 0) return res.status(401).json({ ok: false, error: "Datos incorrectos" }); - const u = q.rows[0]; - if (!(await bcrypt.compare(password, u.password_hash))) return res.status(401).json({ ok: false, error: "Datos incorrectos" }); - res.json({ ok: true, token: signToken(u) }); - } catch(e) { res.status(500).json({ ok: false, error: "Error login" }); } + + // Probamos la contraseña con cada usuario encontrado + let user = null; + for (const u of q.rows) { + if (await bcrypt.compare(password, u.password_hash)) { + user = u; + break; // ¡Encontrado el correcto! + } + } + + if (!user) return res.status(401).json({ ok: false, error: "Datos incorrectos" }); + res.json({ ok: true, token: signToken(user) }); + } catch(e) { console.error(e); res.status(500).json({ ok: false, error: "Error login" }); } }); // RECUPERAR CONTRASEÑA @@ -342,7 +345,6 @@ app.get("/admin/users", authMiddleware, async (req, res) => { } catch (e) { res.status(500).json({ ok: false, error: "Error listar users" }); } }); -// CREAR USUARIO (CORREGIDO MULTITENANT) app.post("/admin/users", authMiddleware, async (req, res) => { const client = await pool.connect(); try { @@ -373,10 +375,8 @@ app.post("/admin/users", authMiddleware, async (req, res) => { res.json({ ok: true, msg: "Usuario creado" }); } catch (e) { await client.query('ROLLBACK'); - // Mantenemos el check global de email único, pero permitimos teléfonos duplicados en distintas empresas - if (e.code === '23505' && e.constraint.includes('email')) { - return res.status(400).json({ ok: false, error: "❌ El Email ya está usado en el sistema." }); - } + // El DB ya no dará error 23505 por email/phone global porque eliminamos la restricción + console.error(e); res.status(500).json({ ok: false, error: "Error creando usuario" }); } finally { client.release(); } });