From 0d3ce93e325f89f12c0b491d324c3a6f81ae2e15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Faleiros?= Date: Fri, 6 Mar 2026 16:15:16 -0300 Subject: [PATCH] fix: populate slugs for old users and include slug/team_id in jwt token --- backend/index.js | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/backend/index.js b/backend/index.js index ca182a8..feca531 100644 --- a/backend/index.js +++ b/backend/index.js @@ -210,8 +210,8 @@ apiRouter.post('/auth/login', async (req, res) => { const valid = await bcrypt.compare(password, user.password_hash); if (!valid) return res.status(401).json({ error: 'Credenciais inválidas.' }); - const token = jwt.sign({ id: user.id, tenant_id: user.tenant_id, role: user.role }, JWT_SECRET, { expiresIn: '24h' }); - res.json({ token, user: { id: user.id, name: user.name, email: user.email, role: user.role, tenant_id: user.tenant_id } }); + const token = jwt.sign({ id: user.id, tenant_id: user.tenant_id, role: user.role, team_id: user.team_id, slug: user.slug }, JWT_SECRET, { expiresIn: '24h' }); + res.json({ token, user: { id: user.id, name: user.name, email: user.email, role: user.role, tenant_id: user.tenant_id, team_id: user.team_id, slug: user.slug } }); } catch (error) { res.status(500).json({ error: error.message }); } @@ -328,12 +328,13 @@ apiRouter.post('/users', requireRole(['admin', 'owner', 'super_admin']), async ( if (existing.length > 0) return res.status(400).json({ error: 'E-mail já cadastrado.' }); const uid = `u_${crypto.randomUUID().split('-')[0]}`; + const slug = `${name.toLowerCase().replace(/[^a-z0-9]+/g, '-')}-${crypto.randomBytes(4).toString('hex')}`; const placeholderHash = 'pending_setup'; // Usuário não pode logar com isso // 2. Criar Usuário await pool.query( - 'INSERT INTO users (id, tenant_id, team_id, name, email, password_hash, role, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?)', - [uid, effectiveTenantId, team_id || null, name, email, placeholderHash, role || 'agent', 'active'] + 'INSERT INTO users (id, tenant_id, team_id, name, email, password_hash, slug, role, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)', + [uid, effectiveTenantId, team_id || null, name, email, placeholderHash, slug, role || 'agent', 'active'] ); // 3. Gerar Token de Setup de Senha (reusando lógica de reset) @@ -607,8 +608,9 @@ apiRouter.post('/tenants', requireRole(['super_admin']), async (req, res) => { const [existingUser] = await connection.query('SELECT id FROM users WHERE email = ?', [admin_email]); if (existingUser.length === 0) { const uid = `u_${crypto.randomUUID().split('-')[0]}`; + const userSlug = `admin-${crypto.randomBytes(4).toString('hex')}`; const placeholderHash = 'pending_setup'; - await connection.query('INSERT INTO users (id, tenant_id, name, email, password_hash, role) VALUES (?, ?, ?, ?, ?, ?)', [uid, tid, 'Admin', admin_email, placeholderHash, 'admin']); + await connection.query('INSERT INTO users (id, tenant_id, name, email, password_hash, slug, role) VALUES (?, ?, ?, ?, ?, ?, ?)', [uid, tid, 'Admin', admin_email, placeholderHash, userSlug, 'admin']); const token = crypto.randomBytes(32).toString('hex'); // Adicionar aos pending_registrations em vez de criar um usuário direto se quisermos que eles completem o cadastro. @@ -713,6 +715,13 @@ const provisionSuperAdmin = async (retries = 10, delay = 10000) => { if (err.code !== 'ER_DUP_FIELDNAME') console.log('Schema update note (slug):', err.message); } + // Populate empty slugs + try { + await connection.query(`UPDATE users SET slug = CONCAT(LOWER(REPLACE(name, ' ', '-')), '-', SUBSTRING(MD5(RAND()), 1, 8)) WHERE slug IS NULL`); + } catch (err) { + console.log('Schema update note (populate slugs):', err.message); + } + // Update origin enum try { await connection.query("ALTER TABLE attendances MODIFY COLUMN origin ENUM('WhatsApp','Instagram','Website','LinkedIn','Indicação') NOT NULL"); @@ -732,10 +741,11 @@ const provisionSuperAdmin = async (retries = 10, delay = 10000) => { if (existing.length === 0) { const uid = `u_${crypto.randomUUID().split('-')[0]}`; const placeholderHash = 'pending_setup'; + const superAdminSlug = 'suporte-blyzer'; await pool.query( - 'INSERT INTO users (id, tenant_id, name, email, password_hash, role, status) VALUES (?, ?, ?, ?, ?, ?, ?)', - [uid, 'system', 'Blyzer Suporte', email, placeholderHash, 'super_admin', 'active'] + 'INSERT INTO users (id, tenant_id, name, email, password_hash, slug, role, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?)', + [uid, 'system', 'Blyzer Suporte', email, placeholderHash, superAdminSlug, 'super_admin', 'active'] ); }