UNPKG

@iota-big3/sdk-security

Version:

Advanced security features including zero trust, quantum-safe crypto, and ML threat detection

254 lines 9.43 kB
"use strict"; /** * @iota-big3/sdk-security - Blockchain Audit Trail * Immutable audit logging with blockchain technology */ Object.defineProperty(exports, "__esModule", { value: true }); exports.BlockchainAuditTrail = void 0; const tslib_1 = require("tslib"); const crypto = tslib_1.__importStar(require("crypto")); const events_1 = require("events"); class BlockchainAuditTrail extends events_1.EventEmitter { constructor(config, logger) { super(); this.isEnabled = true; this.events = new Map(); this.eventBuffer = []; this.blockHeight = 0; this.lastHash = '0'; this.isInitialized = false; this.config = config; this.logger = logger; if (config.encryptionEnabled) { this.encryptionKey = crypto.randomBytes(32); } } async initialize() { if (this.isInitialized) { return; } try { this.logger.info('Initializing blockchain audit trail'); // Validate blockchain config if (this.config.blockchain?.type === 'invalid') { throw new Error('Invalid blockchain configuration'); } // Initialize blockchain connection (mock) await this.connectToBlockchain(); // Setup auto-flush interval this.flushInterval = setInterval(() => { this.flushBuffer().catch(err => this.logger.error('Buffer flush failed', err)); }, 5000); this.isInitialized = true; this.emit('audit:initialized'); } catch (error) { this.logger.error('Failed to initialize blockchain audit trail', error); this.emit('audit:error', error); throw error; } } async connectToBlockchain() { // Mock blockchain connection this.logger.debug(`Connecting to ${this.config.blockchain?.type || 'mock'} blockchain`); } async logEvent(event) { const eventId = this.generateEventId(); const timestamp = Date.now(); let eventData = { ...event, id: eventId, timestamp }; // Encrypt sensitive data if enabled if (this.config.encryptionEnabled && event.details?.sensitive) { eventData = this.encryptEventData(eventData); eventData.encrypted = true; } // Calculate hash const hash = this.calculateHash(eventData, this.lastHash); const storedEvent = { ...eventData, hash, previousHash: this.lastHash, blockHeight: this.blockHeight + 1 }; // Add to buffer this.eventBuffer.push(storedEvent); this.events.set(eventId, storedEvent); // Update state this.lastHash = hash; // Emit events this.emit('audit:event:logged', storedEvent); if (this.config.realTimeStreaming) { this.emit('audit:event:streamed', storedEvent); } return eventId; } async queryEvents(options = {}) { let events = Array.from(this.events.values()); // Filter by date range if (options.startDate) { const startTime = options.startDate.getTime(); events = events.filter(e => e.timestamp >= startTime); } if (options.endDate) { const endTime = options.endDate.getTime(); events = events.filter(e => e.timestamp <= endTime); } // Filter by event type if (options.eventTypes && options.eventTypes.length > 0) { events = events.filter(e => options.eventTypes.includes(e.eventType)); } // Filter by actor if (options.actors && options.actors.length > 0) { events = events.filter(e => options.actors.includes(e.actor.id)); } // Filter by event IDs if (options.eventIds && options.eventIds.length > 0) { events = events.filter(e => options.eventIds.includes(e.id)); } // Sort const sortOrder = options.sortOrder || 'desc'; events.sort((a, b) => { const diff = a.timestamp - b.timestamp; return sortOrder === 'asc' ? diff : -diff; }); // Pagination const offset = options.offset || 0; const limit = options.limit || events.length; return events.slice(offset, offset + limit); } async verifyEventIntegrity(eventId) { const event = this.events.get(eventId); if (!event) { return false; } // Verify hash chain const calculatedHash = this.calculateHash({ ...event, hash: undefined, previousHash: undefined }, event.previousHash || '0'); return calculatedHash === event.hash; } async exportAuditTrail(options, format) { const events = await this.queryEvents(options); switch (format) { case 'json': return JSON.stringify({ events, metadata: { exportDate: new Date(), totalEvents: events.length, blockHeight: this.blockHeight } }, null, 2); case 'csv': { const headers = 'eventId,timestamp,eventType,actor,resource,action,outcome\n'; const rows = events.map(e => `"${e.id}","${new Date(e.timestamp).toISOString()}","${e.eventType}","${e.actor.name}","${e.resource?.name || ''}","${e.action}","${e.outcome}"`).join('\n'); return headers + rows; } case 'pdf': // Mock PDF generation return Buffer.from(`Audit Trail Export\n${JSON.stringify(events, null, 2)}`); default: throw new Error(`Unsupported format: ${format}`); } } async getStatistics() { const events = Array.from(this.events.values()); const stats = { totalEvents: events.length, eventsByType: {}, eventsByOutcome: {}, eventsByActor: {} }; for (const event of events) { // By type stats.eventsByType[event.eventType] = (stats.eventsByType[event.eventType] || 0) + 1; // By outcome stats.eventsByOutcome[event.outcome] = (stats.eventsByOutcome[event.outcome] || 0) + 1; // By actor stats.eventsByActor[event.actor.id] = (stats.eventsByActor[event.actor.id] || 0) + 1; } return stats; } getMetrics() { return { blockchainConnected: this.isInitialized, eventsLogged: this.events.size, bufferSize: this.eventBuffer.length, lastBlockHeight: this.blockHeight, averageLatency: 5 // Mock latency in ms }; } async flushBuffer() { if (this.eventBuffer.length === 0) { return; } try { // Simulate writing to blockchain const eventsToFlush = [...this.eventBuffer]; this.eventBuffer = []; // Update block height this.blockHeight++; this.logger.debug(`Flushed ${eventsToFlush.length} events to blockchain`); this.emit('audit:buffer:flushed', eventsToFlush.length); } catch (error) { // Re-add events to buffer on failure this.eventBuffer.unshift(...this.eventBuffer); throw error; } } async shutdown() { if (!this.isInitialized) { return; } try { // Flush remaining events await this.flushBuffer(); // Clear interval if (this.flushInterval) { clearInterval(this.flushInterval); } // Clear data this.events.clear(); this.eventBuffer = []; this.isInitialized = false; this.emit('audit:shutdown'); } catch (error) { this.logger.error('Error during audit trail shutdown', error); throw error; } } generateEventId() { return `evt-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; } calculateHash(data, previousHash) { const content = JSON.stringify(data) + previousHash; return crypto.createHash('sha256').update(content).digest('hex'); } encryptEventData(data) { if (!this.encryptionKey) { return data; } // Simple encryption for sensitive fields const encrypted = { ...data }; if (encrypted.details?.sensitive) { const iv = crypto.randomBytes(16); const cipher = crypto.createCipheriv('aes-256-cbc', this.encryptionKey, iv); let encryptedData = cipher.update(JSON.stringify(encrypted.details.sensitive), 'utf8', 'hex'); encryptedData += cipher.final('hex'); encrypted.details = { ...encrypted.details, sensitive: undefined, encrypted: { data: encryptedData, iv: iv.toString('hex') } }; } return encrypted; } } exports.BlockchainAuditTrail = BlockchainAuditTrail; //# sourceMappingURL=blockchain-audit.js.map