diff --git a/ESTADO_ATUAL_E_PROXIMOS_PASSOS.md b/ESTADO_ATUAL_E_PROXIMOS_PASSOS.md index ea613cb..af8a548 100644 --- a/ESTADO_ATUAL_E_PROXIMOS_PASSOS.md +++ b/ESTADO_ATUAL_E_PROXIMOS_PASSOS.md @@ -414,3 +414,4 @@ Conseguimos: **Descanse bem! Amanhã finalizamos! 🚀** + diff --git a/backend/routes/mdm.js b/backend/routes/mdm.js index c5950df..85cdaa3 100644 --- a/backend/routes/mdm.js +++ b/backend/routes/mdm.js @@ -1,8 +1,7 @@ // Rotas MDM para cliente Windows buscar e executar comandos const express = require('express'); const router = express.Router(); -const { Pool } = require('pg'); -const pool = new Pool({ connectionString: process.env.DATABASE_URL }); +const { query } = require('../config/database'); // Cliente busca comandos pendentes router.post('/commands/poll', async (req, res) => { @@ -189,17 +188,17 @@ router.get('/templates', async (req, res) => { try { const { category } = req.query; - let query = 'SELECT * FROM policy_templates'; + let sqlQuery = 'SELECT * FROM policy_templates'; const params = []; if (category) { - query += ' WHERE category = $1'; + sqlQuery += ' WHERE category = $1'; params.push(category); } - query += ' ORDER BY category, name'; + sqlQuery += ' ORDER BY category, name'; - const result = await pool.query(query, params); + const result = await query(sqlQuery, params); res.json({ success: true, templates: result.rows }); } catch (error) { diff --git a/backend/routes/policies.js b/backend/routes/policies.js index 0962ea9..27a1997 100644 --- a/backend/routes/policies.js +++ b/backend/routes/policies.js @@ -1,13 +1,12 @@ // Rotas para gerenciamento de políticas MDM const express = require('express'); const router = express.Router(); -const { Pool } = require('pg'); -const pool = new Pool({ connectionString: process.env.DATABASE_URL }); +const { query } = require('../config/database'); // Listar todas as políticas router.get('/', async (req, res) => { try { - const result = await pool.query(` + const result = await query(` SELECT p.*, COUNT(DISTINCT dp.device_id) as devices_count, @@ -40,7 +39,7 @@ router.post('/', async (req, res) => { priority } = req.body; - const result = await pool.query(` + const result = await query(` INSERT INTO policies ( name, description, type, config, enabled, schedule, priority ) VALUES ($1, $2, $3, $4, $5, $6, $7) @@ -69,7 +68,7 @@ router.put('/:id', async (req, res) => { priority } = req.body; - const result = await pool.query(` + const result = await query(` UPDATE policies SET name = $1, description = $2, @@ -101,10 +100,10 @@ router.delete('/:id', async (req, res) => { const { id } = req.params; // Remover associações com dispositivos - await pool.query('DELETE FROM device_policies WHERE policy_id = $1', [id]); + await query('DELETE FROM device_policies WHERE policy_id = $1', [id]); // Remover política - const result = await pool.query('DELETE FROM policies WHERE id = $1 RETURNING *', [id]); + const result = await query('DELETE FROM policies WHERE id = $1 RETURNING *', [id]); if (result.rows.length === 0) { return res.status(404).json({ success: false, message: 'Política não encontrada' }); @@ -130,7 +129,7 @@ router.post('/:id/devices', async (req, res) => { // Inserir associações const values = device_ids.map(device_id => `('${device_id}', ${id})`).join(','); - await pool.query(` + await query(` INSERT INTO device_policies (device_id, policy_id) VALUES ${values} ON CONFLICT (device_id, policy_id) DO NOTHING @@ -154,7 +153,7 @@ router.delete('/:id/devices', async (req, res) => { return res.status(400).json({ success: false, message: 'device_ids deve ser um array não vazio' }); } - const result = await pool.query(` + const result = await query(` DELETE FROM device_policies WHERE policy_id = $1 AND device_id = ANY($2) `, [id, device_ids]); @@ -174,7 +173,7 @@ router.post('/:id/execute', async (req, res) => { const { device_ids } = req.body; // Se não fornecido, executa em todos os dispositivos com a política // Buscar política - const policyResult = await pool.query('SELECT * FROM policies WHERE id = $1', [id]); + const policyResult = await query('SELECT * FROM policies WHERE id = $1', [id]); if (policyResult.rows.length === 0) { return res.status(404).json({ success: false, message: 'Política não encontrada' }); } @@ -184,13 +183,13 @@ router.post('/:id/execute', async (req, res) => { // Buscar dispositivos let devicesQuery; if (device_ids && device_ids.length > 0) { - devicesQuery = await pool.query(` + devicesQuery = await query(` SELECT DISTINCT d.device_id, d.device_name FROM devices d WHERE d.device_id = ANY($1) AND d.status = 'online' `, [device_ids]); } else { - devicesQuery = await pool.query(` + devicesQuery = await query(` SELECT DISTINCT d.device_id, d.device_name FROM devices d INNER JOIN device_policies dp ON d.device_id = dp.device_id @@ -208,7 +207,7 @@ router.post('/:id/execute', async (req, res) => { // Criar comandos de execução para cada dispositivo const commands = []; for (const device of devicesQuery.rows) { - const commandResult = await pool.query(` + const commandResult = await query(` INSERT INTO policy_commands ( device_id, policy_id, @@ -249,7 +248,7 @@ router.get('/:id/executions', async (req, res) => { const { id } = req.params; const { limit = 50, offset = 0 } = req.query; - const result = await pool.query(` + const result = await query(` SELECT pe.*, d.device_name, @@ -261,7 +260,7 @@ router.get('/:id/executions', async (req, res) => { LIMIT $2 OFFSET $3 `, [id, limit, offset]); - const countResult = await pool.query( + const countResult = await query( 'SELECT COUNT(*) FROM policy_executions WHERE policy_id = $1', [id] ); @@ -282,7 +281,7 @@ router.get('/:id/devices', async (req, res) => { try { const { id } = req.params; - const result = await pool.query(` + const result = await query(` SELECT d.*, dp.assigned_at, diff --git a/backend/setup_mdm.js b/backend/setup_mdm.js new file mode 100644 index 0000000..3c857ec --- /dev/null +++ b/backend/setup_mdm.js @@ -0,0 +1,137 @@ +// Script para criar tabelas MDM +const { query } = require('./config/database'); + +async function setupMDM() { + try { + console.log('🔧 Configurando Sistema MDM...\n'); + + // 1. Criar tabela policies + console.log('[1/5] Criando tabela policies...'); + await query(` + CREATE TABLE IF NOT EXISTS policies ( + id SERIAL PRIMARY KEY, + name VARCHAR(255) NOT NULL, + description TEXT, + type VARCHAR(50) NOT NULL, + config JSONB NOT NULL DEFAULT '{}', + enabled BOOLEAN DEFAULT true, + schedule VARCHAR(100), + priority INTEGER DEFAULT 5, + created_at TIMESTAMP DEFAULT NOW(), + updated_at TIMESTAMP DEFAULT NOW() + ) + `); + console.log(' ✅ policies criada'); + + // 2. Criar tabela device_policies + console.log('[2/5] Criando tabela device_policies...'); + await query(` + CREATE TABLE IF NOT EXISTS device_policies ( + id SERIAL PRIMARY KEY, + device_id VARCHAR(255) NOT NULL, + policy_id INTEGER NOT NULL, + assigned_at TIMESTAMP DEFAULT NOW(), + UNIQUE(device_id, policy_id) + ) + `); + console.log(' ✅ device_policies criada'); + + // 3. Criar tabela policy_commands + console.log('[3/5] Criando tabela policy_commands...'); + await query(` + CREATE TABLE IF NOT EXISTS policy_commands ( + id SERIAL PRIMARY KEY, + device_id VARCHAR(255) NOT NULL, + policy_id INTEGER NOT NULL, + command_type VARCHAR(50) NOT NULL, + command_data JSONB NOT NULL DEFAULT '{}', + status VARCHAR(20) DEFAULT 'pending', + priority INTEGER DEFAULT 5, + created_at TIMESTAMP DEFAULT NOW(), + sent_at TIMESTAMP, + completed_at TIMESTAMP, + result JSONB, + error_message TEXT, + retry_count INTEGER DEFAULT 0, + max_retries INTEGER DEFAULT 3 + ) + `); + console.log(' ✅ policy_commands criada'); + + // 4. Criar tabela policy_executions + console.log('[4/5] Criando tabela policy_executions...'); + await query(` + CREATE TABLE IF NOT EXISTS policy_executions ( + id SERIAL PRIMARY KEY, + device_id VARCHAR(255) NOT NULL, + policy_id INTEGER NOT NULL, + command_id INTEGER, + status VARCHAR(20) NOT NULL, + executed_at TIMESTAMP DEFAULT NOW(), + duration_seconds INTEGER, + result JSONB, + error_message TEXT, + details TEXT + ) + `); + console.log(' ✅ policy_executions criada'); + + // 5. Criar tabela policy_templates + console.log('[5/5] Criando tabela policy_templates...'); + await query(` + CREATE TABLE IF NOT EXISTS policy_templates ( + id SERIAL PRIMARY KEY, + name VARCHAR(255) NOT NULL, + description TEXT, + category VARCHAR(50), + type VARCHAR(50) NOT NULL, + default_config JSONB NOT NULL DEFAULT '{}', + icon VARCHAR(100), + created_at TIMESTAMP DEFAULT NOW() + ) + `); + console.log(' ✅ policy_templates criada'); + + // Inserir templates + console.log('\n📦 Inserindo templates pré-configurados...'); + + const templates = [ + { name: 'Forçar Windows Update', category: 'updates', type: 'windows_update', + config: { action: 'force_check_and_install', reboot_if_required: true, reboot_delay_minutes: 30 }}, + { name: 'Instalar Software', category: 'software', type: 'software_install', + config: { software_name: '', download_url: '', install_args: '/S' }}, + { name: 'Executar Script PowerShell', category: 'configuration', type: 'powershell_script', + config: { script: '', run_as_admin: true, timeout_minutes: 30 }}, + { name: 'Reiniciar Dispositivo', category: 'maintenance', type: 'reboot', + config: { delay_minutes: 5, force: false }}, + { name: 'Limpar Arquivos Temporários', category: 'maintenance', type: 'cleanup', + config: { clear_temp: true, clear_browser_cache: true }} + ]; + + for (const t of templates) { + await query(` + INSERT INTO policy_templates (name, category, type, default_config) + VALUES ($1, $2, $3, $4) + ON CONFLICT DO NOTHING + `, [t.name, t.category, t.type, JSON.stringify(t.config)]); + } + + const count = await query('SELECT COUNT(*) FROM policy_templates'); + console.log(' ✅', count.rows[0].count, 'templates disponíveis'); + + console.log('\n🎉 Sistema MDM configurado com sucesso!'); + console.log(''); + console.log('Teste agora:'); + console.log(' curl http://localhost:3005/api/mdm/templates'); + console.log(' curl http://localhost:3005/api/policies'); + + process.exit(0); + } catch (err) { + console.error('\n❌ Erro:', err.message); + console.error(err.stack); + process.exit(1); + } +} + +setupMDM(); +