feat: enhance cybersecurity features and add ticket management components

- Introduced new components for managing tickets, including TicketForm, TicketCard, and TicketTimeline, to streamline the ticketing process.
- Added a new SlaChart component for visualizing SLA data.
- Implemented a CybersecurityWizcard component for enhanced security monitoring and reporting.
- Updated routing to replace the "Solicitar Acesso" page with "Abrir Chamado" for improved user navigation.
- Integrated rate limiting functionality to enhance security measures.
- Added a comprehensive test report for the cybersecurity system, detailing various attack simulations and their outcomes.
- Included new scripts for security testing and environment setup to facilitate automated security assessments.
This commit is contained in:
2025-11-17 16:54:43 -03:00
67 changed files with 14784 additions and 4084 deletions

View File

@@ -7,6 +7,119 @@ export const simboloTipo = v.union(
);
export type SimboloTipo = Infer<typeof simboloTipo>;
export const ataqueCiberneticoTipo = v.union(
v.literal("phishing"),
v.literal("malware"),
v.literal("ransomware"),
v.literal("brute_force"),
v.literal("credential_stuffing"),
v.literal("sql_injection"),
v.literal("xss"),
v.literal("path_traversal"),
v.literal("command_injection"),
v.literal("nosql_injection"),
v.literal("xxe"),
v.literal("man_in_the_middle"),
v.literal("ddos"),
v.literal("engenharia_social"),
v.literal("cve_exploit"),
v.literal("apt"),
v.literal("zero_day"),
v.literal("supply_chain"),
v.literal("fileless_malware"),
v.literal("polymorphic_malware"),
v.literal("ransomware_lateral"),
v.literal("deepfake_phishing"),
v.literal("adversarial_ai"),
v.literal("side_channel"),
v.literal("firmware_bootloader"),
v.literal("bec"),
v.literal("botnet"),
v.literal("ot_ics"),
v.literal("quantum_attack")
);
export type AtaqueCiberneticoTipo = Infer<typeof ataqueCiberneticoTipo>;
export const severidadeSeguranca = v.union(
v.literal("informativo"),
v.literal("baixo"),
v.literal("moderado"),
v.literal("alto"),
v.literal("critico")
);
export type SeveridadeSeguranca = Infer<typeof severidadeSeguranca>;
export const statusEventoSeguranca = v.union(
v.literal("detectado"),
v.literal("investigando"),
v.literal("contido"),
v.literal("falso_positivo"),
v.literal("escalado"),
v.literal("resolvido")
);
export type StatusEventoSeguranca = Infer<typeof statusEventoSeguranca>;
export const sensorSegurancaTipo = v.union(
v.literal("network"),
v.literal("endpoint"),
v.literal("application"),
v.literal("gateway"),
v.literal("ot"),
v.literal("honeypot")
);
export type SensorSegurancaTipo = Infer<typeof sensorSegurancaTipo>;
export const sensorSegurancaStatus = v.union(
v.literal("ativo"),
v.literal("inativo"),
v.literal("degradado"),
v.literal("manutencao")
);
export type SensorSegurancaStatus = Infer<typeof sensorSegurancaStatus>;
export const threatIntelTipo = v.union(
v.literal("open_source"),
v.literal("commercial"),
v.literal("internal"),
v.literal("gov"),
v.literal("research")
);
export const threatIntelFormato = v.union(
v.literal("json"),
v.literal("stix"),
v.literal("csv"),
v.literal("text"),
v.literal("custom")
);
export const acaoIncidenteTipo = v.union(
v.literal("block_ip"),
v.literal("unblock_ip"),
v.literal("block_port"),
v.literal("liberar_porta"),
v.literal("notificar"),
v.literal("isolar_host"),
v.literal("gerar_relatorio"),
v.literal("criar_ticket"),
v.literal("ajuste_regra"),
v.literal("custom")
);
export const acaoIncidenteStatus = v.union(
v.literal("pendente"),
v.literal("executando"),
v.literal("concluido"),
v.literal("falhou")
);
export const reportStatus = v.union(
v.literal("pendente"),
v.literal("processando"),
v.literal("concluido"),
v.literal("falhou")
);
export default defineSchema({
todos: defineTable({
text: v.string(),
@@ -320,9 +433,12 @@ export default defineSchema({
nome: v.string(),
descricao: v.optional(v.string()),
gestorId: v.id("usuarios"),
gestorSuperiorId: v.optional(v.id("usuarios")),
ativo: v.boolean(),
cor: v.optional(v.string()), // Cor para identificação visual
}).index("by_gestor", ["gestorId"]),
})
.index("by_gestor", ["gestorId"])
.index("by_gestor_superior", ["gestorSuperiorId"]),
timesMembros: defineTable({
timeId: v.id("times"),
@@ -688,7 +804,8 @@ export default defineSchema({
v.literal("nova_mensagem"),
v.literal("mencao"),
v.literal("grupo_criado"),
v.literal("adicionado_grupo")
v.literal("adicionado_grupo"),
v.literal("alerta_seguranca")
),
conversaId: v.optional(v.id("conversas")),
mensagemId: v.optional(v.id("mensagens")),
@@ -787,4 +904,446 @@ export default defineSchema({
.index("by_timestamp", ["timestamp"])
.index("by_status", ["status"])
.index("by_config", ["configId", "timestamp"]),
tickets: defineTable({
numero: v.string(),
titulo: v.string(),
descricao: v.string(),
tipo: v.union(
v.literal("reclamacao"),
v.literal("elogio"),
v.literal("sugestao"),
v.literal("chamado")
),
categoria: v.optional(v.string()),
status: v.union(
v.literal("aberto"),
v.literal("em_andamento"),
v.literal("aguardando_usuario"),
v.literal("resolvido"),
v.literal("encerrado"),
v.literal("cancelado")
),
prioridade: v.union(
v.literal("baixa"),
v.literal("media"),
v.literal("alta"),
v.literal("critica")
),
solicitanteId: v.id("usuarios"),
solicitanteNome: v.string(),
solicitanteEmail: v.string(),
responsavelId: v.optional(v.id("usuarios")),
setorResponsavel: v.optional(v.string()),
slaConfigId: v.optional(v.id("slaConfigs")),
conversaId: v.optional(v.id("conversas")),
prazoResposta: v.optional(v.number()),
prazoConclusao: v.optional(v.number()),
prazoEncerramento: v.optional(v.number()),
timeline: v.optional(
v.array(
v.object({
etapa: v.string(),
status: v.union(
v.literal("pendente"),
v.literal("em_andamento"),
v.literal("concluido"),
v.literal("vencido")
),
prazo: v.optional(v.number()),
concluidoEm: v.optional(v.number()),
observacao: v.optional(v.string()),
})
)
),
alertasEmitidos: v.optional(
v.array(
v.object({
tipo: v.union(
v.literal("resposta"),
v.literal("conclusao"),
v.literal("encerramento")
),
emitidoEm: v.number(),
})
)
),
anexos: v.optional(
v.array(
v.object({
arquivoId: v.id("_storage"),
nome: v.optional(v.string()),
tipo: v.optional(v.string()),
tamanho: v.optional(v.number()),
})
)
),
tags: v.optional(v.array(v.string())),
canalOrigem: v.optional(v.string()),
ultimaInteracaoEm: v.number(),
criadoEm: v.number(),
atualizadoEm: v.number(),
})
.index("by_numero", ["numero"])
.index("by_status", ["status"])
.index("by_solicitante", ["solicitanteId", "status"])
.index("by_responsavel", ["responsavelId", "status"])
.index("by_setor", ["setorResponsavel", "status"]),
ticketInteractions: defineTable({
ticketId: v.id("tickets"),
autorId: v.optional(v.id("usuarios")),
origem: v.union(
v.literal("usuario"),
v.literal("ti"),
v.literal("sistema")
),
tipo: v.union(
v.literal("mensagem"),
v.literal("status"),
v.literal("anexo"),
v.literal("alerta")
),
conteudo: v.string(),
anexos: v.optional(
v.array(
v.object({
arquivoId: v.id("_storage"),
nome: v.optional(v.string()),
tipo: v.optional(v.string()),
tamanho: v.optional(v.number()),
})
)
),
statusAnterior: v.optional(
v.union(
v.literal("aberto"),
v.literal("em_andamento"),
v.literal("aguardando_usuario"),
v.literal("resolvido"),
v.literal("encerrado"),
v.literal("cancelado")
)
),
statusNovo: v.optional(
v.union(
v.literal("aberto"),
v.literal("em_andamento"),
v.literal("aguardando_usuario"),
v.literal("resolvido"),
v.literal("encerrado"),
v.literal("cancelado")
)
),
visibilidade: v.union(
v.literal("publico"),
v.literal("interno")
),
criadoEm: v.number(),
})
.index("by_ticket", ["ticketId"])
.index("by_ticket_type", ["ticketId", "tipo"])
.index("by_autor", ["autorId"]),
slaConfigs: defineTable({
nome: v.string(),
descricao: v.optional(v.string()),
prioridade: v.optional(
v.union(
v.literal("baixa"),
v.literal("media"),
v.literal("alta"),
v.literal("critica")
)
),
tempoRespostaHoras: v.number(),
tempoConclusaoHoras: v.number(),
tempoEncerramentoHoras: v.optional(v.number()),
alertaAntecedenciaHoras: v.number(),
ativo: v.boolean(),
criadoPor: v.id("usuarios"),
atualizadoPor: v.optional(v.id("usuarios")),
criadoEm: v.number(),
atualizadoEm: v.number(),
})
.index("by_ativo", ["ativo"])
.index("by_prioridade", ["prioridade", "ativo"])
.index("by_nome", ["nome"]),
ticketAssignments: defineTable({
ticketId: v.id("tickets"),
responsavelId: v.id("usuarios"),
atribuidoPor: v.id("usuarios"),
motivo: v.optional(v.string()),
ativo: v.boolean(),
criadoEm: v.number(),
encerradoEm: v.optional(v.number()),
})
.index("by_ticket", ["ticketId", "ativo"])
.index("by_responsavel", ["responsavelId", "ativo"]),
// Sistema de Segurança Cibernética
networkSensors: defineTable({
nome: v.string(),
tipo: sensorSegurancaTipo,
status: sensorSegurancaStatus,
escopo: v.optional(v.string()),
ipMonitorado: v.optional(v.string()),
hostname: v.optional(v.string()),
regioes: v.optional(v.array(v.string())),
portasMonitoradas: v.optional(v.array(v.number())),
protocolos: v.optional(v.array(v.string())),
capacidades: v.optional(v.array(v.string())),
ultimaSincronizacao: v.number(),
ultimoHeartbeat: v.optional(v.number()),
latenciaMs: v.optional(v.number()),
errosConsecutivos: v.optional(v.number()),
agenteVersao: v.optional(v.string()),
notas: v.optional(v.string()),
})
.index("by_tipo", ["tipo"])
.index("by_status", ["status"])
.index("by_hostname", ["hostname"]),
ipReputation: defineTable({
indicador: v.string(),
categoria: v.union(
v.literal("ip"),
v.literal("dominio"),
v.literal("hash"),
v.literal("email")
),
reputacao: v.number(), // -100 (malicioso) até 100 (confiável)
severidadeMax: severidadeSeguranca,
whitelist: v.boolean(),
blacklist: v.boolean(),
ocorrencias: v.number(),
primeiroRegistro: v.number(),
ultimoRegistro: v.number(),
bloqueadoAte: v.optional(v.number()),
origem: v.optional(v.string()),
comentarios: v.optional(v.string()),
classificacoes: v.optional(v.array(v.string())),
ultimaAcaoId: v.optional(v.id("incidentActions")),
})
.index("by_indicador", ["indicador"])
.index("by_reputacao", ["reputacao"])
.index("by_blacklist", ["blacklist"])
.index("by_whitelist", ["whitelist"]),
portRules: defineTable({
porta: v.number(),
protocolo: v.union(
v.literal("tcp"),
v.literal("udp"),
v.literal("icmp"),
v.literal("quic"),
v.literal("any")
),
acao: v.union(
v.literal("permitir"),
v.literal("bloquear"),
v.literal("monitorar"),
v.literal("rate_limit")
),
temporario: v.boolean(),
severidadeMin: severidadeSeguranca,
duracaoSegundos: v.optional(v.number()),
expiraEm: v.optional(v.number()),
criadoPor: v.id("usuarios"),
atualizadoPor: v.optional(v.id("usuarios")),
criadoEm: v.number(),
atualizadoEm: v.number(),
notas: v.optional(v.string()),
tags: v.optional(v.array(v.string())),
listaReferencia: v.optional(v.id("ipReputation")),
})
.index("by_porta_protocolo", ["porta", "protocolo"])
.index("by_acao", ["acao"])
.index("by_expiracao", ["expiraEm"]),
threatIntelFeeds: defineTable({
nomeFonte: v.string(),
tipo: threatIntelTipo,
formato: threatIntelFormato,
url: v.optional(v.string()),
ativo: v.boolean(),
prioridade: v.union(
v.literal("baixa"),
v.literal("media"),
v.literal("alta"),
v.literal("critica")
),
ultimaSincronizacao: v.optional(v.number()),
entradasProcessadas: v.optional(v.number()),
errosConsecutivos: v.optional(v.number()),
autenticacaoNecessaria: v.optional(v.boolean()),
configuracao: v.optional(
v.object({
tokenId: v.optional(v.id("_storage")),
escopo: v.optional(v.string()),
})
),
criadoPor: v.id("usuarios"),
atualizadoPor: v.optional(v.id("usuarios")),
criadoEm: v.number(),
atualizadoEm: v.number(),
})
.index("by_tipo", ["tipo"])
.index("by_ativo", ["ativo"])
.index("by_prioridade", ["prioridade"]),
securityEvents: defineTable({
referencia: v.string(),
timestamp: v.number(),
tipoAtaque: ataqueCiberneticoTipo,
severidade: severidadeSeguranca,
status: statusEventoSeguranca,
descricao: v.string(),
origemIp: v.optional(v.string()),
origemRegiao: v.optional(v.string()),
origemAsn: v.optional(v.string()),
destinoIp: v.optional(v.string()),
destinoPorta: v.optional(v.number()),
protocolo: v.optional(v.string()),
transporte: v.optional(v.string()),
sensorId: v.optional(v.id("networkSensors")),
detectadoPor: v.optional(v.string()),
mitreTechnique: v.optional(v.string()),
geolocalizacao: v.optional(
v.object({
pais: v.optional(v.string()),
regiao: v.optional(v.string()),
cidade: v.optional(v.string()),
latitude: v.optional(v.number()),
longitude: v.optional(v.number()),
})
),
fingerprint: v.optional(
v.object({
userAgent: v.optional(v.string()),
deviceId: v.optional(v.string()),
ja3: v.optional(v.string()),
tlsVersion: v.optional(v.string()),
})
),
indicadores: v.optional(
v.array(
v.object({
tipo: v.string(),
valor: v.string(),
confianca: v.optional(v.number()),
})
)
),
metricas: v.optional(
v.object({
pps: v.optional(v.number()),
bps: v.optional(v.number()),
rpm: v.optional(v.number()),
errosPorSegundo: v.optional(v.number()),
hostsAfetados: v.optional(v.number()),
})
),
correlacoes: v.optional(v.array(v.id("securityEvents"))),
referenciasExternas: v.optional(v.array(v.string())),
tags: v.optional(v.array(v.string())),
criadoPor: v.optional(v.id("usuarios")),
atualizadoEm: v.number(),
})
.index("by_referencia", ["referencia"])
.index("by_timestamp", ["timestamp"])
.index("by_tipo", ["tipoAtaque", "timestamp"])
.index("by_severidade", ["severidade", "timestamp"])
.index("by_status", ["status", "timestamp"]),
incidentActions: defineTable({
eventoId: v.id("securityEvents"),
tipo: acaoIncidenteTipo,
origem: v.union(v.literal("automatico"), v.literal("manual")),
status: acaoIncidenteStatus,
executadoPor: v.optional(v.id("usuarios")),
detalhes: v.optional(v.string()),
resultado: v.optional(v.string()),
relacionadoA: v.optional(v.id("ipReputation")),
criadoEm: v.number(),
atualizadoEm: v.number(),
})
.index("by_evento", ["eventoId", "status"])
.index("by_tipo", ["tipo", "status"]),
reportRequests: defineTable({
solicitanteId: v.id("usuarios"),
filtros: v.object({
dataInicio: v.number(),
dataFim: v.number(),
severidades: v.optional(v.array(severidadeSeguranca)),
tiposAtaque: v.optional(v.array(ataqueCiberneticoTipo)),
incluirIndicadores: v.optional(v.boolean()),
incluirMetricas: v.optional(v.boolean()),
incluirAcoes: v.optional(v.boolean()),
}),
status: reportStatus,
resultadoId: v.optional(v.id("_storage")),
observacoes: v.optional(v.string()),
criadoEm: v.number(),
atualizadoEm: v.number(),
concluidoEm: v.optional(v.number()),
erro: v.optional(v.string()),
})
.index("by_status", ["status"])
.index("by_solicitante", ["solicitanteId", "status"])
.index("by_criado_em", ["criadoEm"]),
rateLimitConfig: defineTable({
nome: v.string(),
tipo: v.union(
v.literal("ip"),
v.literal("usuario"),
v.literal("endpoint"),
v.literal("global")
),
identificador: v.optional(v.string()),
limite: v.number(),
janelaSegundos: v.number(),
estrategia: v.union(
v.literal("fixed_window"),
v.literal("sliding_window"),
v.literal("token_bucket")
),
acaoExcedido: v.union(
v.literal("bloquear"),
v.literal("throttle"),
v.literal("alertar")
),
bloqueioTemporarioSegundos: v.optional(v.number()),
ativo: v.boolean(),
prioridade: v.number(),
criadoPor: v.id("usuarios"),
atualizadoPor: v.optional(v.id("usuarios")),
criadoEm: v.number(),
atualizadoEm: v.number(),
notas: v.optional(v.string()),
tags: v.optional(v.array(v.string()))
})
.index("by_tipo_identificador", ["tipo", "identificador"])
.index("by_ativo", ["ativo"])
.index("by_prioridade", ["prioridade"])
,
alertConfigs: defineTable({
nome: v.string(),
canais: v.object({
email: v.boolean(),
chat: v.boolean(),
}),
emails: v.array(v.string()),
chatUsers: v.array(v.string()),
severidadeMin: severidadeSeguranca,
tiposAtaque: v.optional(v.array(ataqueCiberneticoTipo)),
reenvioMin: v.number(),
criadoPor: v.id("usuarios"),
criadoEm: v.number(),
atualizadoEm: v.number(),
})
.index("by_criadoEm", ["criadoEm"])
});