feat: Introduce structured table definitions in convex/tables for various entities and remove the todos example table.
This commit is contained in:
330
packages/backend/convex/tables/security.ts
Normal file
330
packages/backend/convex/tables/security.ts
Normal file
@@ -0,0 +1,330 @@
|
||||
import { defineTable } from 'convex/server';
|
||||
import { 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('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 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'])
|
||||
};
|
||||
Reference in New Issue
Block a user