UNPKG

@noukha-technologies/audit-module

Version:

Comprehensive audit logging and monitoring module for NestJS applications

547 lines (441 loc) 16.1 kB
# @noukha/audit-module Comprehensive audit logging and monitoring module for NestJS applications with MongoDB support. ## Installation ```bash npm install @noukha/audit-module ``` ## Features - **Comprehensive Audit Logging**: Track all user actions, system events, and data changes - **Flexible Configuration**: Customizable audit rules and retention policies - **Real-time Monitoring**: Live audit trail with filtering and search capabilities - **Performance Tracking**: Monitor response times and system performance - **Security Auditing**: Track security events, permission changes, and access patterns - **Data Export**: Export audit logs in various formats - **Automatic Cleanup**: Configurable retention and cleanup policies - **RESTful API**: Complete REST API for audit log management - **MongoDB Integration**: Optimized for MongoDB with proper indexing - **NestJS Integration**: Seamless integration with NestJS applications ## Quick Start ### 1. Import the Module ```typescript import { AuditModule } from '@noukha/audit-module'; @Module({ imports: [ AuditModule.forRoot({ connectionString: 'mongodb://localhost:27017/audit', database: 'audit', retentionDays: 30, enableControllers: true, enableGlobalLogger: true, logLevel: 'info', autoCleanup: true, cleanupInterval: 24 * 60 * 60 * 1000, // 24 hours }) ] }) export class AppModule {} ``` ### 2. Use the Services ```typescript import { AuditLoggerService, AuditService } from '@noukha/audit-module'; @Injectable() export class MyService { constructor( private readonly auditLogger: AuditLoggerService, private readonly auditService: AuditService ) {} async createUser(userData: any) { // Your business logic here const user = await this.userRepository.create(userData); // Log the audit event await this.auditLogger.logDataCreate('user', user.id, userData, { userId: 'current-user-id', sessionId: 'session-123', ipAddress: '192.168.1.1', userAgent: 'Mozilla/5.0...', endpoint: '/api/users', method: 'POST', correlationId: 'req-123' }); return user; } async updateUser(userId: string, updateData: any) { const oldUser = await this.userRepository.findById(userId); const updatedUser = await this.userRepository.update(userId, updateData); // Log the audit event await this.auditLogger.logDataUpdate('user', userId, oldUser, updatedUser, { userId: 'current-user-id', sessionId: 'session-123', ipAddress: '192.168.1.1', userAgent: 'Mozilla/5.0...', endpoint: '/api/users/' + userId, method: 'PUT', correlationId: 'req-124' }); return updatedUser; } } ``` ### 3. Use Decorators (Optional) ```typescript import { AuditLog } from '@noukha/audit-module'; @Controller('users') export class UserController { @Post() @AuditLog({ action: 'CREATE', resource: 'user', message: 'User created' }) async createUser(@Body() userData: any) { return this.userService.create(userData); } @Put(':id') @AuditLog({ action: 'UPDATE', resource: 'user', message: 'User updated' }) async updateUser(@Param('id') id: string, @Body() updateData: any) { return this.userService.update(id, updateData); } } ``` ## API Reference ### AuditService #### Core Methods - `createAuditLog(auditOptions: AuditOptions): Promise<AuditLog>` - `createAuditLogFromDto(createAuditLogDto: CreateAuditLogDto): Promise<AuditLog>` - `findAuditLogs(searchOptions: AuditSearchOptions): Promise<PaginatedResponse<AuditLog>>` - `findAuditLogById(id: string): Promise<AuditLog>` - `updateAuditLog(id: string, updateAuditLogDto: UpdateAuditLogDto): Promise<AuditLog>` - `deleteAuditLog(id: string): Promise<void>` - `archiveAuditLog(id: string): Promise<AuditLog>` - `restoreAuditLog(id: string): Promise<AuditLog>` - `bulkArchiveAuditLogs(ids: string[]): Promise<void>` - `bulkDeleteAuditLogs(ids: string[]): Promise<void>` #### Utility Methods - `getAuditStats(startDate?: Date, endDate?: Date): Promise<any>` - `exportAuditLogs(searchOptions: AuditSearchOptions): Promise<any>` - `cleanupExpiredLogs(): Promise<number>` - `getAuditTrail(resource: string, resourceId: string): Promise<AuditLog[]>` ### AuditLoggerService #### Logging Methods - `log(options: AuditOptions): Promise<void>` - `logAction(action: string, resource: string, resourceId: string, context: any): Promise<void>` - `logError(error: Error, context: any): Promise<void>` - `logSecurity(event: string, context: any): Promise<void>` - `logPerformance(operation: string, duration: number, context: any): Promise<void>` #### Convenience Methods - `logUserLogin(userId: string, context: AuditContext): Promise<void>` - `logUserLogout(userId: string, context: AuditContext): Promise<void>` - `logDataCreate(resource: string, resourceId: string, data: any, context: AuditContext): Promise<void>` - `logDataUpdate(resource: string, resourceId: string, oldData: any, newData: any, context: AuditContext): Promise<void>` - `logDataDelete(resource: string, resourceId: string, data: any, context: AuditContext): Promise<void>` - `logPermissionChange(userId: string, targetUserId: string, permissions: any, context: AuditContext): Promise<void>` - `logRoleAssignment(userId: string, targetUserId: string, role: string, context: AuditContext): Promise<void>` ## Audit Actions ### Standard Actions - `CREATE`: Data creation - `READ`: Data retrieval - `UPDATE`: Data modification - `DELETE`: Data deletion - `LOGIN`: User login - `LOGOUT`: User logout - `EXPORT`: Data export - `IMPORT`: Data import - `BULK_UPDATE`: Bulk data updates - `BULK_DELETE`: Bulk data deletion - `SEARCH`: Search operations - `FILTER`: Filter operations - `SORT`: Sort operations - `PAGINATE`: Pagination operations - `DOWNLOAD`: File downloads - `UPLOAD`: File uploads - `APPROVE`: Approval actions - `REJECT`: Rejection actions - `PUBLISH`: Publishing actions - `UNPUBLISH`: Unpublishing actions - `ARCHIVE`: Archiving actions - `RESTORE`: Restoration actions - `SHARE`: Sharing actions - `COPY`: Copy operations - `MOVE`: Move operations - `RENAME`: Rename operations - `PERMISSION_CHANGE`: Permission changes - `ROLE_ASSIGN`: Role assignments - `ROLE_REMOVE`: Role removals - `PASSWORD_CHANGE`: Password changes - `PROFILE_UPDATE`: Profile updates - `SYSTEM_CONFIG`: System configuration changes - `CUSTOM`: Custom actions ### Audit Levels - `DEBUG`: Debug information - `INFO`: General information - `WARN`: Warning messages - `ERROR`: Error conditions - `CRITICAL`: Critical errors ### Audit Categories - `AUTHENTICATION`: Authentication events - `AUTHORIZATION`: Authorization events - `DATA_ACCESS`: Data access events - `DATA_MODIFICATION`: Data modification events - `SYSTEM_OPERATION`: System operations - `USER_ACTIVITY`: User activities - `SECURITY`: Security events - `PERFORMANCE`: Performance events - `ERROR`: Error events - `BUSINESS`: Business events - `COMPLIANCE`: Compliance events - `INTEGRATION`: Integration events - `CUSTOM`: Custom categories ### Audit Sources - `API`: API requests - `WEB`: Web interface - `MOBILE`: Mobile application - `DESKTOP`: Desktop application - `SYSTEM`: System operations - `BATCH`: Batch processes - `SCHEDULED`: Scheduled tasks - `WEBHOOK`: Webhook events - `INTEGRATION`: External integrations - `MANUAL`: Manual operations ## Configuration Options ```typescript interface AuditModuleOptions { connectionString?: string; // MongoDB connection string database?: string; // Database name (default: 'audit') collectionPrefix?: string; // Collection name prefix retentionDays?: number; // Log retention in days (default: 30) enableControllers?: boolean; // Enable REST controllers (default: true) enableGlobalLogger?: boolean; // Enable global logger (default: true) logLevel?: 'debug' | 'info' | 'warn' | 'error'; // Log level autoCleanup?: boolean; // Enable automatic cleanup (default: true) cleanupInterval?: number; // Cleanup interval in milliseconds } ``` ## REST API Endpoints ### Audit Logs - `GET /audit-logs` - Get audit logs with filtering and pagination - `GET /audit-logs/:id` - Get specific audit log - `POST /audit-logs` - Create new audit log - `PUT /audit-logs/:id` - Update audit log - `DELETE /audit-logs/:id` - Delete audit log - `PUT /audit-logs/:id/archive` - Archive audit log - `PUT /audit-logs/:id/restore` - Restore archived audit log - `POST /audit-logs/bulk/archive` - Bulk archive audit logs - `POST /audit-logs/bulk/delete` - Bulk delete audit logs - `GET /audit-logs/stats` - Get audit statistics - `GET /audit-logs/export` - Export audit logs - `GET /audit-logs/trail/:resource/:resourceId` - Get audit trail - `POST /audit-logs/cleanup` - Cleanup expired logs ### Audit Configuration - `GET /audit-configs` - Get all audit configurations - `GET /audit-configs/:id` - Get specific audit configuration - `POST /audit-configs` - Create new audit configuration - `PUT /audit-configs/:id` - Update audit configuration - `DELETE /audit-configs/:id` - Delete audit configuration - `PUT /audit-configs/:id/activate` - Activate configuration - `PUT /audit-configs/:id/deactivate` - Deactivate configuration ## Query Parameters ### Find Audit Logs - `action`: Filter by audit action - `level`: Filter by audit level - `category`: Filter by audit category - `source`: Filter by audit source - `userId`: Filter by user ID - `sessionId`: Filter by session ID - `resource`: Filter by resource type - `resourceId`: Filter by resource ID - `correlationId`: Filter by correlation ID - `parentAuditId`: Filter by parent audit ID - `tags`: Filter by tags (array) - `search`: Text search across multiple fields - `startDate`: Filter by start date - `endDate`: Filter by end date - `ipAddress`: Filter by IP address - `endpoint`: Filter by endpoint - `method`: Filter by HTTP method - `minResponseTime`: Minimum response time filter - `maxResponseTime`: Maximum response time filter - `statusCode`: Filter by HTTP status code - `isArchived`: Filter by archive status - `metadataFilters`: Filter by metadata fields - `page`: Page number (default: 1) - `limit`: Items per page (default: 10) - `sortBy`: Sort field (default: 'timestamp') - `sortOrder`: Sort order ('asc' | 'desc', default: 'desc') ## Examples ### Basic Usage ```typescript // Log a simple action await auditLogger.logAction('CREATE', 'user', 'user-123', { userId: 'admin-1', sessionId: 'session-456', ipAddress: '192.168.1.100', userAgent: 'Mozilla/5.0...', endpoint: '/api/users', method: 'POST' }); // Log an error await auditLogger.logError(new Error('Database connection failed'), { userId: 'system', sessionId: 'system', resource: 'database', resourceId: 'connection-1', metadata: { database: 'main', host: 'localhost' } }); // Log performance metrics await auditLogger.logPerformance('database-query', 150, { userId: 'user-1', sessionId: 'session-789', resource: 'database', resourceId: 'query-1', metadata: { query: 'SELECT * FROM users', table: 'users' } }); ``` ### Advanced Filtering ```typescript // Find audit logs with complex filtering const auditLogs = await auditService.findAuditLogs({ action: AuditAction.CREATE, category: AuditCategory.USER_ACTIVITY, userId: 'user-123', startDate: new Date('2024-01-01'), endDate: new Date('2024-01-31'), search: 'user creation', page: 1, limit: 20, sortBy: 'timestamp', sortOrder: 'desc' }); ``` ### Audit Trail ```typescript // Get complete audit trail for a resource const auditTrail = await auditService.getAuditTrail('user', 'user-123'); console.log(`Found ${auditTrail.length} audit events for user user-123`); ``` ### Statistics ```typescript // Get audit statistics const stats = await auditService.getAuditStats( new Date('2024-01-01'), new Date('2024-01-31') ); console.log(`Total logs: ${stats.totalLogs}`); console.log(`Unique users: ${stats.uniqueUsers}`); console.log(`Average response time: ${stats.avgResponseTime}ms`); console.log(`Error rate: ${stats.errorRate}%`); ``` ## Best Practices ### 1. Consistent Context Always provide consistent context information: ```typescript const auditContext = { userId: req.user?.id || 'anonymous', sessionId: req.sessionID || 'no-session', ipAddress: req.ip || req.connection.remoteAddress, userAgent: req.get('User-Agent') || 'unknown', endpoint: req.originalUrl, method: req.method, correlationId: req.headers['x-correlation-id'] || nanoid() }; ``` ### 2. Meaningful Messages Use descriptive messages that provide context: ```typescript // Good await auditLogger.logAction('CREATE', 'user', userId, { ...context, message: `User ${userId} created with email ${userData.email}` }); // Bad await auditLogger.logAction('CREATE', 'user', userId, { ...context, message: 'User created' }); ``` ### 3. Appropriate Log Levels Use appropriate log levels for different types of events: ```typescript // Critical security events await auditLogger.logSecurity('Failed login attempt', { ...context, level: AuditLevel.CRITICAL, metadata: { attempts: 5, locked: true } }); // Performance warnings await auditLogger.logPerformance('slow-query', 5000, { ...context, level: AuditLevel.WARN }); ``` ### 4. Data Privacy Be careful with sensitive data in audit logs: ```typescript // Remove sensitive fields before logging const sanitizedData = { ...userData }; delete sanitizedData.password; delete sanitizedData.ssn; delete sanitizedData.creditCard; await auditLogger.logDataCreate('user', userId, sanitizedData, context); ``` ### 5. Retention Policies Configure appropriate retention policies: ```typescript // Different retention for different types of logs await auditService.createAuditLog({ ...auditOptions, expiresAt: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000), // 1 year for security logs }); ``` ## Performance Considerations ### 1. Async Logging Always use async logging to avoid blocking the main application: ```typescript // Good - fire and forget this.auditLogger.logAction('CREATE', 'user', userId, context).catch(err => { console.error('Audit logging failed:', err); }); // Bad - blocking await this.auditLogger.logAction('CREATE', 'user', userId, context); ``` ### 2. Batch Operations For bulk operations, consider batching audit logs: ```typescript // Batch multiple audit logs const auditLogs = users.map(user => ({ action: AuditAction.CREATE, resource: 'user', resourceId: user.id, // ... other fields })); await Promise.all(auditLogs.map(log => auditService.createAuditLog(log))); ``` ### 3. Indexing The module automatically creates indexes for common query patterns: - `userId + timestamp` - `resource + resourceId + timestamp` - `action + category + timestamp` - `sessionId + timestamp` - `correlationId` - `expiresAt` (for TTL) ## Troubleshooting ### Common Issues 1. **High Memory Usage**: Reduce retention period or implement log rotation 2. **Slow Queries**: Check if proper indexes are created 3. **Missing Logs**: Verify audit configuration and service injection 4. **Performance Impact**: Use async logging and consider batching ### Debug Mode Enable debug logging to troubleshoot issues: ```typescript AuditModule.forRoot({ logLevel: 'debug', // ... other options }) ``` ## License MIT ## Support For support and questions, please open an issue on the GitHub repository.