refactor: 重构项目结构并优化类型定义
- 移除extension模块,将功能迁移至node-agent - 修复类型导出问题,使用export type明确类型导出 - 统一数据库连接方式,从直接导入改为使用config/database - 更新文档中的项目结构描述 - 添加多个服务的实用方法,如getForecast、getBalances等 - 修复类型错误和TS1205警告 - 优化RedisService调用方式 - 添加新的实体类型定义 - 更新审计日志格式,统一字段命名
This commit is contained in:
@@ -74,9 +74,9 @@ export class AgentTraceAuditService {
|
||||
let reasoning = 'No explicit reasoning found.';
|
||||
let decisionDetails: any = null;
|
||||
if (params.decisionId) {
|
||||
const explanation = await ExplainableAIService.getExplanation(params.decisionId, params.tenantId);
|
||||
reasoning = explanation?.explanation?.logic || reasoning;
|
||||
decisionDetails = explanation?.decision;
|
||||
const explanation = await ExplainableAIService.getExplanation(params.decisionId);
|
||||
reasoning = explanation?.reasoning || reasoning;
|
||||
decisionDetails = explanation?.inputFactors;
|
||||
}
|
||||
|
||||
// 2. 生产级合规性校验 (Zero-Mock)
|
||||
|
||||
@@ -159,4 +159,66 @@ export class PrivateAuditService {
|
||||
static async getTenantAuditHistory(tenantId: string): Promise<AuditRecord[]> {
|
||||
return db(this.AUDIT_TABLE).where({ tenant_id: tenantId }).orderBy('created_at', 'desc');
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成零知识证明 (简化版) - 重载签名
|
||||
* @description 支持多种调用方式
|
||||
*/
|
||||
static async generateProof(
|
||||
tenantIdOrParams: string | { value: number; threshold: number; type: 'GEQ' | 'LEQ' | 'EQ' },
|
||||
typeOrThreshold?: string | number,
|
||||
data?: any
|
||||
): Promise<string> {
|
||||
// 处理重载:如果第一个参数是字符串,则使用旧格式 (tenantId, type, data)
|
||||
if (typeof tenantIdOrParams === 'string') {
|
||||
const tenantId = tenantIdOrParams;
|
||||
const proofType = typeOrThreshold as string;
|
||||
const proofData = data || {};
|
||||
|
||||
logger.info(`[PrivateAudit] Generating ZKP proof for tenant: ${tenantId}, type: ${proofType}`);
|
||||
|
||||
const salt = crypto.randomBytes(16).toString('hex');
|
||||
const proof = JSON.stringify({
|
||||
version: 'zkp-v2',
|
||||
type: 'CUSTOM_PROOF',
|
||||
subtype: proofType,
|
||||
tenantId,
|
||||
data: proofData,
|
||||
salt,
|
||||
timestamp: Date.now()
|
||||
});
|
||||
|
||||
return proof;
|
||||
}
|
||||
|
||||
// 处理新格式 (params object)
|
||||
const params = tenantIdOrParams;
|
||||
logger.info(`[PrivateAudit] Generating ZKP proof for type: ${params.type}`);
|
||||
|
||||
let satisfied = false;
|
||||
switch (params.type) {
|
||||
case 'GEQ':
|
||||
satisfied = params.value >= params.threshold;
|
||||
break;
|
||||
case 'LEQ':
|
||||
satisfied = params.value <= params.threshold;
|
||||
break;
|
||||
case 'EQ':
|
||||
satisfied = params.value === params.threshold;
|
||||
break;
|
||||
}
|
||||
|
||||
const salt = crypto.randomBytes(16).toString('hex');
|
||||
const proof = JSON.stringify({
|
||||
version: 'zkp-v2',
|
||||
type: 'RANGE_PROOF',
|
||||
subtype: params.type,
|
||||
threshold: params.threshold,
|
||||
satisfied,
|
||||
salt,
|
||||
timestamp: Date.now()
|
||||
});
|
||||
|
||||
return proof;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { RedisService } from '../cache/RedisService';
|
||||
import RedisService from '../../services/RedisService';
|
||||
|
||||
export interface SecurityAuditLog {
|
||||
id: string;
|
||||
@@ -45,11 +45,10 @@ export class SecurityHardeningService {
|
||||
private auditLogs: SecurityAuditLog[] = [];
|
||||
private securityAlerts: SecurityAlert[] = [];
|
||||
private readonly maxAuditLogs = 10000;
|
||||
private securityCheckInterval: NodeJS.Timeout;
|
||||
private securityCheckInterval!: NodeJS.Timeout;
|
||||
|
||||
constructor(
|
||||
private readonly configService: ConfigService,
|
||||
private readonly redisService: RedisService,
|
||||
) {}
|
||||
|
||||
async initialize(): Promise<void> {
|
||||
@@ -167,7 +166,7 @@ export class SecurityHardeningService {
|
||||
}
|
||||
};
|
||||
|
||||
await this.redisService.set('security:rbac:roles', JSON.stringify(roles));
|
||||
await RedisService.set('security:rbac:roles', JSON.stringify(roles));
|
||||
this.logger.log('✅ RBAC configured with 7 roles');
|
||||
}
|
||||
|
||||
@@ -197,7 +196,7 @@ export class SecurityHardeningService {
|
||||
}
|
||||
};
|
||||
|
||||
await this.redisService.set('security:ratelimits', JSON.stringify(rateLimits));
|
||||
await RedisService.set('security:ratelimits', JSON.stringify(rateLimits));
|
||||
this.logger.log('✅ Rate limiting configured');
|
||||
}
|
||||
|
||||
@@ -214,7 +213,7 @@ export class SecurityHardeningService {
|
||||
safeString: /^[a-zA-Z0-9\s\-_.,!?]+$/
|
||||
};
|
||||
|
||||
await this.redisService.set('security:validation:rules', JSON.stringify(validationRules));
|
||||
await RedisService.set('security:validation:rules', JSON.stringify(validationRules));
|
||||
this.logger.log('✅ Input validation configured');
|
||||
}
|
||||
|
||||
@@ -229,7 +228,7 @@ export class SecurityHardeningService {
|
||||
json: true
|
||||
};
|
||||
|
||||
await this.redisService.set('security:encoding', JSON.stringify(encodingSettings));
|
||||
await RedisService.set('security:encoding', JSON.stringify(encodingSettings));
|
||||
this.logger.log('✅ Output encoding configured');
|
||||
}
|
||||
|
||||
@@ -250,7 +249,7 @@ export class SecurityHardeningService {
|
||||
name: 'sessionId'
|
||||
};
|
||||
|
||||
await this.redisService.set('security:session', JSON.stringify(sessionSettings));
|
||||
await RedisService.set('security:session', JSON.stringify(sessionSettings));
|
||||
this.logger.log('✅ Session security configured');
|
||||
}
|
||||
|
||||
@@ -268,7 +267,7 @@ export class SecurityHardeningService {
|
||||
}
|
||||
};
|
||||
|
||||
await this.redisService.set('security:csrf', JSON.stringify(csrfSettings));
|
||||
await RedisService.set('security:csrf', JSON.stringify(csrfSettings));
|
||||
this.logger.log('✅ CSRF protection configured');
|
||||
}
|
||||
|
||||
@@ -287,7 +286,7 @@ export class SecurityHardeningService {
|
||||
'X-Permitted-Cross-Domain-Policies': 'none'
|
||||
};
|
||||
|
||||
await this.redisService.set('security:headers', JSON.stringify(headers));
|
||||
await RedisService.set('security:headers', JSON.stringify(headers));
|
||||
this.logger.log('✅ Security headers configured');
|
||||
}
|
||||
|
||||
@@ -302,7 +301,7 @@ export class SecurityHardeningService {
|
||||
encoding: 'base64'
|
||||
};
|
||||
|
||||
await this.redisService.set('security:encryption', JSON.stringify(encryptionSettings));
|
||||
await RedisService.set('security:encryption', JSON.stringify(encryptionSettings));
|
||||
this.logger.log('✅ Data encryption configured');
|
||||
}
|
||||
|
||||
@@ -354,13 +353,13 @@ export class SecurityHardeningService {
|
||||
|
||||
private async checkSQLInjection(): Promise<boolean> {
|
||||
try {
|
||||
const patterns = [
|
||||
/('|(\\')|(;)|(\-\-)|(\s+or\s+)|(\s+and\s+)/i,
|
||||
/(union\s+select)|(drop\s+table)|(delete\s+from)|(insert\s+into)/i,
|
||||
/(exec\s*\()|(execute\s*\()|(sp_executesql)/i
|
||||
const patterns: RegExp[] = [
|
||||
new RegExp("('|(')|(;)|(--)|(\\s+or\\s+)|(\\s+and\\s+)", 'i'),
|
||||
new RegExp('(union\\s+select)|(drop\\s+table)|(delete\\s+from)|(insert\\s+into)', 'i'),
|
||||
new RegExp('(exec\\s*\\()|(execute\\s*\\()|(sp_executesql)', 'i')
|
||||
];
|
||||
|
||||
await this.redisService.set('security:check:sqlinjection', JSON.stringify({
|
||||
await RedisService.set('security:check:sqlinjection', JSON.stringify({
|
||||
status: 'passed',
|
||||
patterns: patterns.length,
|
||||
timestamp: new Date().toISOString()
|
||||
@@ -384,7 +383,7 @@ export class SecurityHardeningService {
|
||||
/<embed[^>]*>/gi
|
||||
];
|
||||
|
||||
await this.redisService.set('security:check:xss', JSON.stringify({
|
||||
await RedisService.set('security:check:xss', JSON.stringify({
|
||||
status: 'passed',
|
||||
patterns: patterns.length,
|
||||
timestamp: new Date().toISOString()
|
||||
@@ -399,10 +398,10 @@ export class SecurityHardeningService {
|
||||
|
||||
private async checkCSRF(): Promise<boolean> {
|
||||
try {
|
||||
const csrfEnabled = await this.redisService.get('security:csrf');
|
||||
const csrfEnabled = await RedisService.get('security:csrf');
|
||||
const csrfStatus = csrfEnabled ? JSON.parse(csrfEnabled).enabled : false;
|
||||
|
||||
await this.redisService.set('security:check:csrf', JSON.stringify({
|
||||
await RedisService.set('security:check:csrf', JSON.stringify({
|
||||
status: csrfStatus ? 'passed' : 'failed',
|
||||
enabled: csrfStatus,
|
||||
timestamp: new Date().toISOString()
|
||||
@@ -417,10 +416,10 @@ export class SecurityHardeningService {
|
||||
|
||||
private async checkAuthentication(): Promise<boolean> {
|
||||
try {
|
||||
const authSettings = await this.redisService.get('security:rbac:roles');
|
||||
const authSettings = await RedisService.get('security:rbac:roles');
|
||||
const hasAuth = authSettings !== null;
|
||||
|
||||
await this.redisService.set('security:check:authentication', JSON.stringify({
|
||||
await RedisService.set('security:check:authentication', JSON.stringify({
|
||||
status: hasAuth ? 'passed' : 'failed',
|
||||
hasAuthentication: hasAuth,
|
||||
timestamp: new Date().toISOString()
|
||||
@@ -435,10 +434,10 @@ export class SecurityHardeningService {
|
||||
|
||||
private async checkAuthorization(): Promise<boolean> {
|
||||
try {
|
||||
const rbacSettings = await this.redisService.get('security:rbac:roles');
|
||||
const rbacSettings = await RedisService.get('security:rbac:roles');
|
||||
const hasRBAC = rbacSettings !== null;
|
||||
|
||||
await this.redisService.set('security:check:authorization', JSON.stringify({
|
||||
await RedisService.set('security:check:authorization', JSON.stringify({
|
||||
status: hasRBAC ? 'passed' : 'failed',
|
||||
hasRBAC: hasRBAC,
|
||||
timestamp: new Date().toISOString()
|
||||
@@ -453,10 +452,10 @@ export class SecurityHardeningService {
|
||||
|
||||
private async checkDataValidation(): Promise<boolean> {
|
||||
try {
|
||||
const validationRules = await this.redisService.get('security:validation:rules');
|
||||
const validationRules = await RedisService.get('security:validation:rules');
|
||||
const hasValidation = validationRules !== null;
|
||||
|
||||
await this.redisService.set('security:check:validation', JSON.stringify({
|
||||
await RedisService.set('security:check:validation', JSON.stringify({
|
||||
status: hasValidation ? 'passed' : 'failed',
|
||||
hasValidation: hasValidation,
|
||||
timestamp: new Date().toISOString()
|
||||
@@ -471,10 +470,10 @@ export class SecurityHardeningService {
|
||||
|
||||
private async checkEncryption(): Promise<boolean> {
|
||||
try {
|
||||
const encryptionSettings = await this.redisService.get('security:encryption');
|
||||
const encryptionSettings = await RedisService.get('security:encryption');
|
||||
const hasEncryption = encryptionSettings !== null;
|
||||
|
||||
await this.redisService.set('security:check:encryption', JSON.stringify({
|
||||
await RedisService.set('security:check:encryption', JSON.stringify({
|
||||
status: hasEncryption ? 'passed' : 'failed',
|
||||
hasEncryption: hasEncryption,
|
||||
timestamp: new Date().toISOString()
|
||||
@@ -489,10 +488,10 @@ export class SecurityHardeningService {
|
||||
|
||||
private async checkSessionSecurity(): Promise<boolean> {
|
||||
try {
|
||||
const sessionSettings = await this.redisService.get('security:session');
|
||||
const sessionSettings = await RedisService.get('security:session');
|
||||
const hasSessionSecurity = sessionSettings !== null;
|
||||
|
||||
await this.redisService.set('security:check:session', JSON.stringify({
|
||||
await RedisService.set('security:check:session', JSON.stringify({
|
||||
status: hasSessionSecurity ? 'passed' : 'failed',
|
||||
hasSessionSecurity: hasSessionSecurity,
|
||||
timestamp: new Date().toISOString()
|
||||
@@ -507,11 +506,9 @@ export class SecurityHardeningService {
|
||||
|
||||
private async cacheSecurityChecks(checks: any): Promise<void> {
|
||||
try {
|
||||
await this.redisService.set(
|
||||
await RedisService.set(
|
||||
'security:checks:latest',
|
||||
JSON.stringify(checks),
|
||||
'EX',
|
||||
3600
|
||||
JSON.stringify(checks), 3600
|
||||
);
|
||||
} catch (error) {
|
||||
this.logger.warn('Failed to cache security checks', error);
|
||||
@@ -535,7 +532,7 @@ export class SecurityHardeningService {
|
||||
|
||||
private async getTotalRequests(): Promise<number> {
|
||||
try {
|
||||
const count = await this.redisService.get('security:metrics:requests');
|
||||
const count = await RedisService.get('security:metrics:requests');
|
||||
return count ? parseInt(count) : 0;
|
||||
} catch (error) {
|
||||
return 0;
|
||||
@@ -544,7 +541,7 @@ export class SecurityHardeningService {
|
||||
|
||||
private async getBlockedRequests(): Promise<number> {
|
||||
try {
|
||||
const count = await this.redisService.get('security:metrics:blocked');
|
||||
const count = await RedisService.get('security:metrics:blocked');
|
||||
return count ? parseInt(count) : 0;
|
||||
} catch (error) {
|
||||
return 0;
|
||||
@@ -553,7 +550,7 @@ export class SecurityHardeningService {
|
||||
|
||||
private async getFailedAuthAttempts(): Promise<number> {
|
||||
try {
|
||||
const count = await this.redisService.get('security:metrics:failedAuth');
|
||||
const count = await RedisService.get('security:metrics:failedAuth');
|
||||
return count ? parseInt(count) : 0;
|
||||
} catch (error) {
|
||||
return 0;
|
||||
@@ -562,7 +559,7 @@ export class SecurityHardeningService {
|
||||
|
||||
private async getSuspiciousActivities(): Promise<number> {
|
||||
try {
|
||||
const count = await this.redisService.get('security:metrics:suspicious');
|
||||
const count = await RedisService.get('security:metrics:suspicious');
|
||||
return count ? parseInt(count) : 0;
|
||||
} catch (error) {
|
||||
return 0;
|
||||
@@ -571,7 +568,7 @@ export class SecurityHardeningService {
|
||||
|
||||
private async getVulnerabilitiesFound(): Promise<number> {
|
||||
try {
|
||||
const count = await this.redisService.get('security:metrics:vulnerabilities');
|
||||
const count = await RedisService.get('security:metrics:vulnerabilities');
|
||||
return count ? parseInt(count) : 0;
|
||||
} catch (error) {
|
||||
return 0;
|
||||
@@ -580,7 +577,7 @@ export class SecurityHardeningService {
|
||||
|
||||
private async calculateComplianceScore(): Promise<number> {
|
||||
try {
|
||||
const checks = await this.redisService.get('security:checks:latest');
|
||||
const checks = await RedisService.get('security:checks:latest');
|
||||
if (!checks) return 0;
|
||||
|
||||
const checkResults = JSON.parse(checks);
|
||||
@@ -595,19 +592,17 @@ export class SecurityHardeningService {
|
||||
|
||||
private async cacheSecurityMetrics(metrics: SecurityMetrics): Promise<void> {
|
||||
try {
|
||||
await this.redisService.set(
|
||||
await RedisService.set(
|
||||
'security:metrics:latest',
|
||||
JSON.stringify(metrics),
|
||||
'EX',
|
||||
3600
|
||||
JSON.stringify(metrics), 3600
|
||||
);
|
||||
|
||||
await this.redisService.lpush(
|
||||
await RedisService.lpush(
|
||||
'security:metrics:history',
|
||||
JSON.stringify(metrics)
|
||||
);
|
||||
|
||||
await this.redisService.ltrim('security:metrics:history', 0, 999);
|
||||
await RedisService.ltrim('security:metrics:history', 0, 999);
|
||||
} catch (error) {
|
||||
this.logger.warn('Failed to cache security metrics', error);
|
||||
}
|
||||
@@ -703,20 +698,18 @@ export class SecurityHardeningService {
|
||||
private async cacheSecurityAlerts(alerts: SecurityAlert[]): Promise<void> {
|
||||
try {
|
||||
for (const alert of alerts) {
|
||||
await this.redisService.set(
|
||||
await RedisService.set(
|
||||
`security:alert:${alert.id}`,
|
||||
JSON.stringify(alert),
|
||||
'EX',
|
||||
86400
|
||||
JSON.stringify(alert), 86400
|
||||
);
|
||||
}
|
||||
|
||||
await this.redisService.lpush(
|
||||
await RedisService.lpush(
|
||||
'security:alerts:latest',
|
||||
JSON.stringify(alerts)
|
||||
);
|
||||
|
||||
await this.redisService.ltrim('security:alerts:latest', 0, 99);
|
||||
await RedisService.ltrim('security:alerts:latest', 0, 99);
|
||||
} catch (error) {
|
||||
this.logger.warn('Failed to cache security alerts', error);
|
||||
}
|
||||
@@ -737,14 +730,12 @@ export class SecurityHardeningService {
|
||||
vulnerabilities.code.length +
|
||||
vulnerabilities.configuration.length;
|
||||
|
||||
await this.redisService.set(
|
||||
await RedisService.set(
|
||||
'security:vulnerabilities:latest',
|
||||
JSON.stringify(vulnerabilities),
|
||||
'EX',
|
||||
86400
|
||||
JSON.stringify(vulnerabilities), 86400
|
||||
);
|
||||
|
||||
await this.redisService.set(
|
||||
await RedisService.set(
|
||||
'security:metrics:vulnerabilities',
|
||||
totalVulnerabilities.toString()
|
||||
);
|
||||
@@ -810,11 +801,9 @@ export class SecurityHardeningService {
|
||||
|
||||
if (outdated) {
|
||||
const outdatedPackages = JSON.parse(outdated);
|
||||
await this.redisService.set(
|
||||
await RedisService.set(
|
||||
'security:dependencies:outdated',
|
||||
JSON.stringify(outdatedPackages),
|
||||
'EX',
|
||||
86400
|
||||
JSON.stringify(outdatedPackages), 86400
|
||||
);
|
||||
|
||||
this.logger.warn(`⚠️ ${Object.keys(outdatedPackages).length} outdated packages found`);
|
||||
@@ -834,11 +823,9 @@ export class SecurityHardeningService {
|
||||
weakEncryption: 0
|
||||
};
|
||||
|
||||
await this.redisService.set(
|
||||
await RedisService.set(
|
||||
'security:code:analysis',
|
||||
JSON.stringify(securityIssues),
|
||||
'EX',
|
||||
86400
|
||||
JSON.stringify(securityIssues), 86400
|
||||
);
|
||||
|
||||
this.logger.log('✅ Code security analysis completed');
|
||||
@@ -870,19 +857,17 @@ export class SecurityHardeningService {
|
||||
|
||||
private async cacheAuditLog(auditLog: SecurityAuditLog): Promise<void> {
|
||||
try {
|
||||
await this.redisService.set(
|
||||
await RedisService.set(
|
||||
`security:audit:${auditLog.id}`,
|
||||
JSON.stringify(auditLog),
|
||||
'EX',
|
||||
2592000 // 30 days
|
||||
JSON.stringify(auditLog), 2592000 // 30 days
|
||||
);
|
||||
|
||||
await this.redisService.lpush(
|
||||
await RedisService.lpush(
|
||||
'security:audit:recent',
|
||||
JSON.stringify(auditLog)
|
||||
);
|
||||
|
||||
await this.redisService.ltrim('security:audit:recent', 0, 999);
|
||||
await RedisService.ltrim('security:audit:recent', 0, 999);
|
||||
} catch (error) {
|
||||
this.logger.warn('Failed to cache audit log', error);
|
||||
}
|
||||
@@ -890,7 +875,7 @@ export class SecurityHardeningService {
|
||||
|
||||
async getSecurityMetrics(): Promise<SecurityMetrics> {
|
||||
try {
|
||||
const metrics = await this.redisService.get('security:metrics:latest');
|
||||
const metrics = await RedisService.get('security:metrics:latest');
|
||||
return metrics ? JSON.parse(metrics) : await this.analyzeSecurityMetrics();
|
||||
} catch (error) {
|
||||
return await this.analyzeSecurityMetrics();
|
||||
@@ -899,7 +884,7 @@ export class SecurityHardeningService {
|
||||
|
||||
async getSecurityAlerts(): Promise<SecurityAlert[]> {
|
||||
try {
|
||||
const alerts = await this.redisService.lrange('security:alerts:latest', 0, 99);
|
||||
const alerts = await RedisService.lrange('security:alerts:latest', 0, 99);
|
||||
return alerts.map((alert: string) => JSON.parse(alert));
|
||||
} catch (error) {
|
||||
return [];
|
||||
@@ -908,7 +893,7 @@ export class SecurityHardeningService {
|
||||
|
||||
async getAuditLogs(limit: number = 100): Promise<SecurityAuditLog[]> {
|
||||
try {
|
||||
const logs = await this.redisService.lrange('security:audit:recent', 0, limit - 1);
|
||||
const logs = await RedisService.lrange('security:audit:recent', 0, limit - 1);
|
||||
return logs.map((log: string) => JSON.parse(log));
|
||||
} catch (error) {
|
||||
return [];
|
||||
@@ -955,9 +940,9 @@ export class SecurityHardeningService {
|
||||
clearInterval(this.securityCheckInterval);
|
||||
}
|
||||
|
||||
await this.redisService.del('security:checks:latest');
|
||||
await this.redisService.del('security:metrics:latest');
|
||||
await this.redisService.del('security:alerts:latest');
|
||||
await RedisService.del('security:checks:latest');
|
||||
await RedisService.del('security:metrics:latest');
|
||||
await RedisService.del('security:alerts:latest');
|
||||
|
||||
this.logger.log('✅ Security Hardening Service shutdown completed');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user