1.0.1 • Published 6 months ago
nestjs-database-audit-log v1.0.1
NestJS Database Audit Log
A comprehensive database auditing solution for NestJS applications that automatically tracks all database changes, user actions, and provides rollback capabilities.
Features
- 🔍 Automatic tracking of all database changes (INSERT, UPDATE, DELETE)
- 👤 User action logging (including login attempts)
- 🔄 Rollback capability to any previous version
- 📝 Detailed change tracking with before/after values
- 🌐 IP address logging
- 📊 Comprehensive audit history viewing
- 🔒 Role-based access control for rollbacks
Installation
npm install nestjs-database-audit-log
Quick Start
Import AuditLogModule
in your app.module.ts
:
import { AuditLogModule } from 'nestjs-database-audit-log';
import { Module } from '@nestjs/common';
@Module({
imports: [
AuditLogModule,
// ... other modules
],
})
export class AppModule {}
Module Setup
// news.module.ts
import { Module } from '@nestjs/common';
import { AuditLogModule } from 'nestjs-database-audit-log';
import { TypeOrmModule } from '@nestjs/typeorm';
import { News } from './news.entity';
import { NewsService } from './news.service';
import { NewsController } from './news.controller';
@Module({
imports: [
TypeOrmModule.forFeature([News]),
AuditLogModule,
],
providers: [NewsService],
controllers: [NewsController],
})
export class NewsModule {}
Service Integration Examples
1. Create Operation
// news.service.ts
@Injectable()
export class NewsService {
constructor(
@InjectRepository(News)
private newsRepository: Repository<News>,
private auditLogService: AuditLogService,
) {}
async create(createNewsDto: CreateNewsDto, author: User, ipAddress: string) {
const savedNews = await this.newsRepository.save(createNewsDto);
await this.auditLogService.createAuditLog({
userId: author.id,
action: 'INSERT',
entityType: 'news',
entityId: savedNews.id,
newData: savedNews,
ipAddress,
});
return savedNews;
}
}
2. Update Operation
async update(id: number, updateDto: UpdateNewsDto, user: User, ipAddress: string) {
const oldData = await this.newsRepository.findOne(id);
const updated = await this.newsRepository.update(id, updateDto);
await this.auditLogService.createAuditLog({
userId: user.id,
action: 'UPDATE',
entityType: 'news',
entityId: id,
oldData,
newData: updated,
ipAddress,
});
return updated;
}
3. Delete Operation
async remove(id: number, user: User, ipAddress: string) {
const existingData = await this.newsRepository.findOne(id);
await this.newsRepository.delete(id);
await this.auditLogService.createAuditLog({
userId: user.id,
action: 'DELETE',
entityType: 'news',
entityId: id,
oldData: existingData,
ipAddress,
});
}
4. Login Tracking
async logUserLogin(user: User, ipAddress: string, success: boolean) {
await this.auditLogService.createAuditLog({
userId: user.id,
action: 'LOGIN',
entityType: 'auth',
entityId: user.id,
newData: {
username: user.username,
success,
timestamp: new Date().toISOString(),
},
ipAddress,
});
}
View Audit History
@Get('history/:entityId')
async getHistory(
@Param('entityId') id: number,
@Query('entityType') entityType: string
) {
return this.auditLogService.getAuditLogsByEntityId(id, entityType);
}
Rollback Feature
@Post('rollback/:id')
@UseGuards(AdminGuard)
async rollback(@Param('id') auditLogId: number) {
return this.auditLogService.rollbackToVersion(auditLogId);
}
Interface Reference
interface AuditLogParams {
userId: number;
action: 'INSERT' | 'UPDATE' | 'DELETE' | 'LOGIN';
entityType: string;
entityId: number;
oldData?: any;
newData?: any;
ipAddress: string;
}
Getting IP Address
@Post()
async create(
@Body() dto: CreateNewsDto,
@Request() req,
@User() user: User
) {
const ipAddress = req.ip || req.connection.remoteAddress;
return this.newsService.create(dto, user, ipAddress);
}
Best Practices
try {
await this.auditLogService.createAuditLog({...});
} catch (error) {
this.logger.error(`Audit log failed: ${error.message}`);
}
- ✅ Regular cleanup of old audit logs
- ✅ Index important columns for better performance
- ✅ Use proper access controls for viewing audit logs
Troubleshooting
Common issues and solutions:
Missing audit logs
- Verify interceptor is properly configured
- Check database connectivity
- Ensure proper permissions
Rollback failures
- Verify admin permissions
- Check entity exists
- Ensure data integrity
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT
Author
Support
For support, please create an issue in the GitHub repository or contact the author.
Last Updated: 2025-02-05
1.0.1
6 months ago