UNPKG

@pulzar/core

Version:

Next-generation Node.js framework for ultra-fast web applications with zero-reflection DI, GraphQL, WebSockets, events, and edge runtime support

196 lines 6.28 kB
import { EventEmitter } from "events"; import { logger } from "../../utils/logger"; import { randomUUID } from "crypto"; export class AuthEventEmitter extends EventEmitter { auditLog = []; maxLogSize; constructor(maxLogSize = 1000) { super(); this.maxLogSize = maxLogSize; this.setupDefaultListeners(); } /** * Setup default event listeners for logging */ setupDefaultListeners() { this.on("auth.login", (event, context) => { logger.info("User login attempt", { userId: event.userId, success: event.success, error: event.error, traceId: context?.traceId, requestId: context?.requestId, timestamp: event.timestamp, }); }); this.on("auth.logout", (event, context) => { logger.info("User logout", { userId: event.userId, sessionId: event.sessionId, traceId: context?.traceId, requestId: context?.requestId, timestamp: event.timestamp, }); }); this.on("auth.token_refresh", (event, context) => { logger.debug("Token refresh", { userId: event.userId, success: event.success, traceId: context?.traceId, requestId: context?.requestId, timestamp: event.timestamp, }); }); this.on("auth.security_violation", (event, context) => { logger.warn("Security violation detected", { userId: event.userId, type: event.type, error: event.error, metadata: event.metadata, traceId: context?.traceId, requestId: context?.requestId, ipAddress: context?.ipAddress, userAgent: context?.userAgent, timestamp: event.timestamp, }); }); this.on("auth.lockout", (event, context) => { logger.warn("User account locked", { userId: event.userId, metadata: event.metadata, traceId: context?.traceId, requestId: context?.requestId, timestamp: event.timestamp, }); }); } /** * Emit auth event with automatic audit logging */ emitAuthEvent(type, data, context) { const event = { type, timestamp: new Date(), ...data, }; // Add to audit log this.addToAuditLog(event); // Emit the event this.emit(`auth.${type}`, event, context); this.emit("auth.*", event, context); // Wildcard listener } /** * Add event to audit log with size management */ addToAuditLog(event) { const auditEntry = { id: randomUUID(), event, createdAt: new Date(), }; this.auditLog.push(auditEntry); // Maintain max log size if (this.auditLog.length > this.maxLogSize) { this.auditLog.shift(); } } /** * Get audit log entries */ getAuditLog(filters) { let filtered = this.auditLog; if (filters) { if (filters.userId) { filtered = filtered.filter((entry) => entry.event.userId === filters.userId); } if (filters.type) { filtered = filtered.filter((entry) => entry.event.type === filters.type); } if (filters.success !== undefined) { filtered = filtered.filter((entry) => entry.event.success === filters.success); } if (filters.since) { filtered = filtered.filter((entry) => entry.event.timestamp >= filters.since); } if (filters.limit) { filtered = filtered.slice(-filters.limit); } } return filtered; } /** * Get auth statistics */ getStats() { const totalEvents = this.auditLog.length; const eventsByType = {}; let successfulEvents = 0; const oneHourAgo = new Date(Date.now() - 60 * 60 * 1000); let recentFailures = 0; for (const entry of this.auditLog) { const type = entry.event.type; eventsByType[type] = (eventsByType[type] || 0) + 1; if (entry.event.success) { successfulEvents++; } if (!entry.event.success && entry.event.timestamp >= oneHourAgo) { recentFailures++; } } return { totalEvents, eventsByType, successRate: totalEvents > 0 ? successfulEvents / totalEvents : 0, recentFailures, }; } /** * Clear audit log */ clearAuditLog() { this.auditLog = []; } /** * Export audit log as JSON */ exportAuditLog() { return JSON.stringify(this.auditLog, null, 2); } } // Global auth event emitter instance export const authEvents = new AuthEventEmitter(); // Helper functions for common events export function emitLoginEvent(userId, success, context, error, metadata) { authEvents.emitAuthEvent("login", { userId, success, error, metadata, ipAddress: context?.ipAddress, userAgent: context?.userAgent, }, context); } export function emitLogoutEvent(userId, sessionId, context) { authEvents.emitAuthEvent("logout", { userId, sessionId, success: true, ipAddress: context?.ipAddress, userAgent: context?.userAgent, }, context); } export function emitSecurityViolation(userId, violationType, context, metadata) { authEvents.emitAuthEvent("login", { // Using login type for violations userId, success: false, error: `Security violation: ${violationType}`, metadata: { violationType, ...metadata, }, ipAddress: context?.ipAddress, userAgent: context?.userAgent, }, context); } //# sourceMappingURL=auth-events.js.map