diff --git a/apps/web/src/lib/components/ti/CybersecurityWizcard.svelte b/apps/web/src/lib/components/ti/CybersecurityWizcard.svelte index feca7b3..ecfd7fb 100644 --- a/apps/web/src/lib/components/ti/CybersecurityWizcard.svelte +++ b/apps/web/src/lib/components/ti/CybersecurityWizcard.svelte @@ -58,14 +58,20 @@ return Array.from(set).slice(0, 16); }); function adicionarEmailSugestao(email: string) { - const linhas = alertEmails.split('\n').map((s) => s.trim()).filter(Boolean); + const linhas = alertEmails + .split('\n') + .map((s) => s.trim()) + .filter(Boolean); if (!linhas.includes(email)) { linhas.push(email); alertEmails = linhas.join('\n'); } } function adicionarChatSugestao(user: string) { - const linhas = alertUsersChat.split('\n').map((s) => s.trim()).filter(Boolean); + const linhas = alertUsersChat + .split('\n') + .map((s) => s.trim()) + .filter(Boolean); if (!linhas.includes(user)) { linhas.push(user); alertUsersChat = linhas.join('\n'); @@ -88,7 +94,7 @@ emails: parseLinhasParaArray(alertEmails), chatUsers: parseLinhasParaArray(alertUsersChat), severidadeMin: alertSeveridadeMin, - tiposAtaque: (alertTiposAtaque as AtaqueCiberneticoTipo[]), + tiposAtaque: alertTiposAtaque as AtaqueCiberneticoTipo[], reenvioMin: alertReenvioMin, criadoPor: obterUsuarioId() }); @@ -257,7 +263,7 @@ // Efeito: observar chegada de novos eventos e acionar toast/contador $effect(() => { - const lista = (eventos?.data ?? []); + const lista = eventos?.data ?? []; if (!lista.length) return; // conta apenas eventos com timestamp maior que o último visto const novos = lista.filter((e) => e.timestamp > ultimoTsVisto).length; @@ -316,10 +322,7 @@ return buckets; }); const maxBucketTotal = $derived.by(() => - Math.max( - 1, - ...timelineBuckets.map((b) => Object.values(b.counts).reduce((a, n) => a + n, 0)) - ) + Math.max(1, ...timelineBuckets.map((b) => Object.values(b.counts).reduce((a, n) => a + n, 0))) ); function maxSeriesValue(dataset: Array>): number { @@ -517,7 +520,7 @@ if (!win) return; let conteudo: string; try { - const data = r.observacoes ? JSON.parse(r.observacoes) as any : null; + const data = r.observacoes ? (JSON.parse(r.observacoes) as any) : null; const total = data?.total ?? '—'; const porSeveridade = data?.porSeveridade ?? {}; const porAtaque = data?.porAtaque ?? {}; @@ -528,7 +531,9 @@ .map(([k, v]) => `${k}${v as number}`) .join(''); const criadoStr = new Date(r.criadoEm).toLocaleString('pt-BR', { hour12: false }); - const concluidoStr = r.concluidoEm ? new Date(r.concluidoEm).toLocaleString('pt-BR', { hour12: false }) : '—'; + const concluidoStr = r.concluidoEm + ? new Date(r.concluidoEm).toLocaleString('pt-BR', { hour12: false }) + : '—'; const agoraStr = new Date().toLocaleString('pt-BR', { hour12: false }); conteudo = '' + @@ -547,15 +552,25 @@ '' + '
' + '

Relatório de Segurança

' + - '
Status: ' + r.status + ' · Criado: ' + criadoStr + ' · Concluído: ' + concluidoStr + '
' + + '
Status: ' + + r.status + + ' · Criado: ' + + criadoStr + + ' · Concluído: ' + + concluidoStr + + '
' + '

Resumo

' + - '

Total de eventos no período: ' + total + '

' + + '

Total de eventos no período: ' + + total + + '

' + '

Por Severidade

' + (linhasSev || '') + '
SeveridadeQtde

Por Tipo de Ataque

' + (linhasAtk || '') + '
TipoQtde
' + - '' + + '' + ''; } catch { const obs = (r.observacoes ?? '').replace(/Relatório' + - '
' + obs + '
' + - scriptOpen + 'window.print()' + scriptClose; + '
' +
+				obs +
+				'
' + + scriptOpen + + 'window.print()' + + scriptClose; } win.document.open(); win.document.write(conteudo); @@ -763,167 +782,20 @@ - -
-

Alertas e Notificações

-

Configure destinatários, níveis e tipos de alarme e reenvio.

-
- -
-

Emails de destino

- - {#if sugestoesEmails.length} -
- {#each sugestoesEmails as s (s)} - - {/each} -
- {/if} -
- - -
-
- - -
- - - -
- -
-

Alertas por Chat

- - - {#if sugestoesChatUsers.length} -
- {#each sugestoesChatUsers as s (s)} - - {/each} -
- {/if} -
- - -
- - -
-
-
-

Configurações salvas

- {#if alertConfigs?.data?.length} -
- {#each alertConfigs.data as cfg (cfg._id)} -
-
-
-

{cfg.nome}

-

- Canais: {cfg.canais.email ? 'Email' : ''}{cfg.canais.email && cfg.canais.chat ? ' + ' : ''}{cfg.canais.chat ? 'Chat' : ''} - • Sev. mínima: {severityLabels[cfg.severidadeMin]} - • Reenvio: {cfg.reenvioMin} min -

- {#if cfg.emails.length} -

Emails: {cfg.emails.join(', ')}

- {/if} - {#if cfg.chatUsers.length} -

Chat: {cfg.chatUsers.join(', ')}

- {/if} -
-
- - -
-
-
- {/each} -
- {:else} -

Nenhuma configuração salva.

- {/if} -
- +
-

Layerchart Threat Matrix

+

Threat Matrix

Correlação temporal entre DDoS, SQLi, ataques avançados e bloqueios automáticos.

{#if health?.data}
- + {health.data.ok ? 'Saúde OK' : 'Instável'} · Pendentes: {health.data.pendingReports}
{/if} @@ -997,17 +869,30 @@
{#each timelineBuckets as b}
-
+
{#each tiposParaChart as t} {#if b.counts[t] > 0} -
a + n, 0))) * 100}%; background:${coresTipo[t]}`} - title={`${t}: ${b.counts[t]}`}>
+
a + n, 0) + )) * + 100 + }%; background:${coresTipo[t]}`} + title={`${t}: ${b.counts[t]}`} + >
{/if} {/each}
- {new Date(b.inicio).toLocaleTimeString('pt-BR', { hour12: false, hour: '2-digit', minute: '2-digit' })} + {new Date(b.inicio).toLocaleTimeString('pt-BR', { + hour12: false, + hour: '2-digit', + minute: '2-digit' + })}
{/each} @@ -1020,7 +905,7 @@

Top destinos (IP · protocolo)

- +
@@ -1029,12 +914,10 @@ - {#each [...new Map( - timelineBuckets - .map((b) => Object.entries(b.topDestinos)) - .flat() - .reduce((acc, [k, v]) => acc.set(k, (acc.get(k) ?? 0) + (v as number)), new Map()) - )].slice(0, 8) as item} + {#each [...new Map(timelineBuckets + .map((b) => Object.entries(b.topDestinos)) + .flat() + .reduce((acc, [k, v]) => acc.set(k, (acc.get(k) ?? 0) + (v as number)), new Map()))].slice(0, 8) as item} {#key item[0]} {@const partes = item[0].split('|')} @@ -1193,7 +1076,9 @@ class="btn btn-xs btn-warning" onclick={async () => { try { - const resultado = await client.mutation(api.security.criarEventosTeste, { quantidade: 10 }); + const resultado = await client.mutation(api.security.criarEventosTeste, { + quantidade: 10 + }); feedback = { tipo: 'success', mensagem: `✅ ${resultado.eventosCriados} eventos de teste criados com sucesso!` @@ -1241,7 +1126,9 @@ {/each} -
6 ? 'max-h-[28rem] overflow-auto pr-2' : ''}`}> +
6 ? 'max-h-[28rem] overflow-auto pr-2' : ''}`} + > {#if eventosFiltrados.length === 0}

Nenhum evento correspondente aos filtros.

{:else} @@ -1335,7 +1222,11 @@

Lista Negra Inteligente

-
    +
      {#if ipCriticos.length === 0}
    • Nenhum IP crítico listado.
    • {:else} @@ -1361,9 +1252,11 @@
-
+

Regras de Portas Monitoradas

-
+
{#if regras.length === 0}

Nenhuma regra cadastrada.

{:else} @@ -1432,7 +1325,7 @@
-
+

Relatórios refinados

Destino
+
@@ -1487,7 +1380,11 @@ {r.status} - +
Status {new Date(r.criadoEm).toLocaleString('pt-BR', { hour12: false })}{r.concluidoEm ? new Date(r.concluidoEm).toLocaleString('pt-BR', { hour12: false }) : '-'}{r.concluidoEm + ? new Date(r.concluidoEm).toLocaleString('pt-BR', { hour12: false }) + : '-'} {r.observacoes ?? '-'}
@@ -1790,6 +1687,215 @@ {/if}
+ + +
+

Alertas e Notificações

+

+ Configure destinatários, níveis e tipos de alarme e reenvio. +

+
+ +
+

Emails de destino

+ + {#if sugestoesEmails.length} +
+ {#each sugestoesEmails as s (s)} + + {/each} +
+ {/if} +
+ + +
+
+ + +
+ + + +
+ +
+

Alertas por Chat

+ + + {#if sugestoesChatUsers.length} +
+ {#each sugestoesChatUsers as s (s)} + + {/each} +
+ {/if} +
+ + +
+ + +
+
+
+

Configurações salvas

+ {#if alertConfigs?.data?.length} +
+ {#each alertConfigs.data as cfg (cfg._id)} +
+
+
+

{cfg.nome}

+

+ Canais: {cfg.canais.email ? 'Email' : ''}{cfg.canais.email && cfg.canais.chat + ? ' + ' + : ''}{cfg.canais.chat ? 'Chat' : ''} + • Sev. mínima: {severityLabels[cfg.severidadeMin]} + • Reenvio: {cfg.reenvioMin} min +

+ {#if cfg.emails.length} +

Emails: {cfg.emails.join(', ')}

+ {/if} + {#if cfg.chatUsers.length} +

Chat: {cfg.chatUsers.join(', ')}

+ {/if} +
+
+ + +
+
+
+ {/each} +
+ {:else} +

Nenhuma configuração salva.

+ {/if} +