344 lines
9.5 KiB
TypeScript
344 lines
9.5 KiB
TypeScript
import { defineTable } from 'convex/server';
|
|
import { type Infer, v } from 'convex/values';
|
|
|
|
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('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 const securityTables = {
|
|
// 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']),
|
|
|
|
autoBlockConfig: defineTable({
|
|
tipoAtaque: ataqueCiberneticoTipo,
|
|
bloquearAutomatico: v.boolean(),
|
|
severidadeMinima: severidadeSeguranca,
|
|
duracaoBloqueioSegundos: v.optional(v.number()),
|
|
ativo: v.boolean(),
|
|
criadoPor: v.id('usuarios'),
|
|
atualizadoPor: v.optional(v.id('usuarios')),
|
|
criadoEm: v.number(),
|
|
atualizadoEm: v.number()
|
|
})
|
|
.index('by_tipo', ['tipoAtaque'])
|
|
.index('by_ativo', ['ativo'])
|
|
};
|