// SOC Page - carrega dentro do backup panel // Abas: Visão Geral, Segurança, IPs, Database, SQL, CRUD, Serviços, Auditoria let socToken = localStorage.getItem('soc_token_backup'); let socPage = 'overview'; async function socApi(path, opts = {}) { const headers = { 'Content-Type': 'application/json' }; if (socToken) headers['X-Soc-Token'] = socToken; const r = await fetch('/api/soc' + path, { ...opts, headers }); if (r.status === 401) { socToken = null; localStorage.removeItem('soc_token_backup'); return null; } return r.json(); } function socLoginPage() { return `

🔐 Login SOC

Credenciais do SOC (dashboardvps.veloregroup.cloud)

`; } async function socDoLogin() { const r = await socApi('/auth/login', { method: 'POST', body: JSON.stringify({ username: document.getElementById('soc-user').value, password: document.getElementById('soc-pass').value }) }); if (r && r.token) { socToken = r.token; localStorage.setItem('soc_token_backup', socToken); renderSOC(); } else alert(r?.error || 'Falha no login SOC'); } async function renderSOC() { if (!socToken) { document.getElementById('page-content').innerHTML = socLoginPage(); return; } const tabs = [ { id: 'overview', label: '📊 Visão Geral' }, { id: 'security', label: '🛡️ Segurança' }, { id: 'ips', label: '🌐 IPs' }, { id: 'database', label: '🗄️ Database' }, { id: 'sql', label: '💻 SQL' }, { id: 'crud', label: '📋 CRUD' }, { id: 'services', label: '⚙️ Serviços' }, { id: 'audit', label: '📝 Auditoria' }, ]; document.getElementById('page-content').innerHTML = `
${tabs.map(t => ``).join('')}
Carregando...
`; if (socPage === 'overview') await socRenderOverview(); else if (socPage === 'security') await socRenderSecurity(); else if (socPage === 'ips') await socRenderIPs(); else if (socPage === 'database') await socRenderDatabase(); else if (socPage === 'sql') socRenderSQL(); else if (socPage === 'crud') await socRenderCRUD(); else if (socPage === 'services') await socRenderServices(); else if (socPage === 'audit') await socRenderAudit(); } async function socRenderOverview() { const [status, procs, conns] = await Promise.all([socApi('/status'), socApi('/status/processes'), socApi('/status/conns')]); const m = status?.current || {}; document.getElementById('soc-content').innerHTML = `
CPU
${m.cpu_pct != null ? m.cpu_pct.toFixed(1) + '%' : '—'}
RAM
${m.mem_pct != null ? m.mem_pct.toFixed(1) + '%' : '—'}
Disco
${m.disk_pct != null ? m.disk_pct + '%' : '—'}
Uptime
${m.uptime_s ? Math.round(m.uptime_s / 3600) + 'h' : '—'}

Top Processos

${(procs || []).slice(0, 10).map(p => ``).join('')}
PIDProcessoCPURAM
${p.pid}${p.comm}${p.cpu?.toFixed(1) || '—'}${p.mem?.toFixed(1) || '—'}

Conexões

${(conns || []).slice(0, 30).map(c => `
${c}
`).join('')}
`; } async function socRenderSecurity() { const [events, summary, alerts] = await Promise.all([socApi('/events?limit=50'), socApi('/events/summary'), socApi('/alerts')]); const total = summary?.bySource?.reduce((a, b) => a + Number(b.count), 0) || 0; document.getElementById('soc-content').innerHTML = `
Eventos 24h
${total}
Alertas Abertos
${alerts?.length || 0}
Críticos
${summary?.bySeverity?.find(s => s.severity === 'critical')?.count || 0}

Eventos

${(Array.isArray(events) ? events : []).slice(0, 30).map(e => ``).join('')}
DataFonteSeveridadeIPMensagem
${new Date(e.created_at).toLocaleString('pt-BR')} ${e.source} ${e.severity} ${e.ip || '—'} ${e.message || '—'}
`; } async function socRenderIPs() { const ips = await socApi('/ips?limit=50'); document.getElementById('soc-content').innerHTML = `

IPs

${(Array.isArray(ips) ? ips : []).map(ip => ``).join('')}
IPPaísCidadeISPFonteHits
${ip.ip} ${ip.country || '—'} ${ip.country_code ? '(' + ip.country_code + ')' : ''} ${ip.city || '—'} ${ip.isp || '—'} ${ip.source} ${ip.hits}
`; } async function socRenderDatabase() { const tables = await socApi('/crud-meta'); const tableDefs = tables?.tables || {}; const cats = {}; Object.entries(tableDefs).forEach(([k, v]) => { const c = v.category || 'Outros'; if (!cats[c]) cats[c] = []; cats[c].push({ key: k, def: v }); }); document.getElementById('soc-content').innerHTML = `

Tabelas

${Object.entries(cats).map(([cat, items]) => `
${cat}
${items.map(i => ``).join('')}
`).join('')}

Selecione uma tabela

`; } async function socLoadTable(name) { const d = await socApi('/crud/' + name + '?limit=50'); const rows = Array.isArray(d) ? d : d?.rows || []; const cols = rows[0] ? Object.keys(rows[0]).slice(0, 6) : []; document.getElementById('soc-table-data').innerHTML = `

${name}

${cols.map(c => ``).join('')} ${rows.map(r => `${cols.map(c => ``).join('')}`).join('')}
${c}
${String(r[c] ?? '').slice(0, 40)}
`; } function socRenderSQL() { document.getElementById('soc-content').innerHTML = `

Resultado aparece aqui

`; } async function socRunSQL() { const sql = document.getElementById('soc-sql').value; const r = await socApi('/sql', { method: 'POST', body: JSON.stringify({ sql }) }); if (r?.error) { document.getElementById('soc-sql-result').innerHTML = `
Erro: ${r.error}
`; return; } const cols = r?.columns || []; const rows = r?.rows || []; document.getElementById('soc-sql-result').innerHTML = `
${r?.command} · ${r?.rowCount} linhas
${cols.map(c => ``).join('')} ${rows.map(r => `${cols.map(c => ``).join('')}`).join('')}
${c}
${String(r[c] ?? '').slice(0, 50)}
`; } async function socRenderCRUD() { const tables = await socApi('/crud-meta'); const tableDefs = tables?.tables || {}; const cats = {}; Object.entries(tableDefs).forEach(([k, v]) => { const c = v.category || 'Outros'; if (!cats[c]) cats[c] = []; cats[c].push({ key: k, def: v }); }); document.getElementById('soc-content').innerHTML = `

CRUD

${Object.entries(cats).map(([cat, items]) => `
${cat}
${items.map(i => ``).join('')}
`).join('')}

Selecione uma tabela

`; } async function socRenderServices() { const services = await socApi('/services'); document.getElementById('soc-content').innerHTML = `

systemd

${(services?.systemd || []).map(s => ``).join('')}
ServiçoStatus
${s.name}${s.status}

PM2

${(services?.pm2 || []).map(a => ``).join('')}
AppStatusCPURAM
${a.name}${a.status}${a.cpu || 0}%${formatSize(a.mem || 0)}
`; } async function socRenderAudit() { const logs = await socApi('/audit?limit=50'); document.getElementById('soc-content').innerHTML = `

Auditoria

${(Array.isArray(logs) ? logs : []).map(l => ``).join('')}
DataUsuárioAçãoDetalheIP
${new Date(l.created_at).toLocaleString('pt-BR')} ${l.username} ${l.action} ${l.detail || '—'} ${l.ip || '—'}
`; }