feat(security): add security policy management and IP intelligence operations to the ops UI
This commit is contained in:
@@ -5,6 +5,7 @@ import type {
|
||||
IIpIntelligenceRecord,
|
||||
ISecurityBlockRule,
|
||||
ISecurityCompiledPolicy,
|
||||
ISecurityPolicyAuditEvent,
|
||||
TSecurityBlockRuleMatchMode,
|
||||
TSecurityBlockRuleType,
|
||||
} from '../../ts_interfaces/data/security-policy.js';
|
||||
@@ -44,7 +45,7 @@ export class SecurityPolicyManager {
|
||||
await Promise.allSettled(uniqueIps.map((ip) => this.observeIp(ip)));
|
||||
}
|
||||
|
||||
public async observeIp(ipAddress: string): Promise<void> {
|
||||
public async observeIp(ipAddress: string, options: { force?: boolean } = {}): Promise<void> {
|
||||
const ip = this.normalizeIp(ipAddress);
|
||||
if (!ip || !this.isPublicIp(ip) || this.inFlightObservations.has(ip)) {
|
||||
return;
|
||||
@@ -54,7 +55,7 @@ export class SecurityPolicyManager {
|
||||
try {
|
||||
const now = Date.now();
|
||||
let doc = await IpIntelligenceDoc.findByIp(ip);
|
||||
if (doc && now - doc.updatedAt < this.intelligenceRefreshMs) {
|
||||
if (doc && !options.force && now - doc.updatedAt < this.intelligenceRefreshMs) {
|
||||
if (now - doc.lastSeenAt > 60_000) {
|
||||
doc.lastSeenAt = now;
|
||||
doc.seenCount = (doc.seenCount || 0) + 1;
|
||||
@@ -90,7 +91,31 @@ export class SecurityPolicyManager {
|
||||
}
|
||||
|
||||
public async listIpIntelligence(): Promise<IIpIntelligenceRecord[]> {
|
||||
return (await IpIntelligenceDoc.findAll()).map((doc) => ({
|
||||
return (await IpIntelligenceDoc.findAll()).map((doc) => this.intelligenceFromDoc(doc));
|
||||
}
|
||||
|
||||
public async refreshIpIntelligence(ipAddress: string): Promise<IIpIntelligenceRecord | null> {
|
||||
const ip = this.normalizeIp(ipAddress);
|
||||
if (!ip || !this.isPublicIp(ip)) {
|
||||
return null;
|
||||
}
|
||||
await this.observeIp(ip, { force: true });
|
||||
const doc = await IpIntelligenceDoc.findByIp(ip);
|
||||
return doc ? this.intelligenceFromDoc(doc) : null;
|
||||
}
|
||||
|
||||
public async listAuditEvents(limit = 100): Promise<ISecurityPolicyAuditEvent[]> {
|
||||
return (await SecurityPolicyAuditDoc.findRecent(limit)).map((doc) => ({
|
||||
id: doc.id,
|
||||
action: doc.action,
|
||||
actor: doc.actor,
|
||||
details: doc.details,
|
||||
createdAt: doc.createdAt,
|
||||
}));
|
||||
}
|
||||
|
||||
private intelligenceFromDoc(doc: IpIntelligenceDoc): IIpIntelligenceRecord {
|
||||
return {
|
||||
ipAddress: doc.ipAddress,
|
||||
asn: doc.asn,
|
||||
asnOrg: doc.asnOrg,
|
||||
@@ -109,7 +134,7 @@ export class SecurityPolicyManager {
|
||||
lastSeenAt: doc.lastSeenAt,
|
||||
updatedAt: doc.updatedAt,
|
||||
seenCount: doc.seenCount,
|
||||
}));
|
||||
};
|
||||
}
|
||||
|
||||
public async createBlockRule(input: {
|
||||
|
||||
Reference in New Issue
Block a user