@noukha-technologies/audit-module
Version:
Comprehensive audit logging and monitoring module for NestJS applications
547 lines (441 loc) • 16.1 kB
Markdown
# @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.