@imexs/audit-trail
v1.0.3
Published
Enterprise-grade Audit Trail Plugin for Node.js with TypeScript - Performance Monitoring, System Integration Audit, Data Accountability & User Activity Tracking with Advanced Security Features
Downloads
139
Maintainers
Readme
audit-trail
Enterprise-grade Audit Trail Plugin for Node.js + TypeScript with Advanced Security Features
Features
Core Logging
- User Activity Tracking - Monitor user actions (CREATE, UPDATE, DELETE, READ)
- System Integration Audit - Log external API calls and third-party services
- Data Accountability - Track data access for GDPR/compliance
- Performance Monitoring - Track response times, memory, CPU usage
Security (Enterprise-Grade)
- AES-256-GCM Encryption - Data encryption at rest
- RBAC - Role-based access control (4 roles, 6 permissions)
- Rate Limiting - DoS protection (per user & IP)
- Input Validation - SQL injection & XSS prevention
- Integrity Checking - HMAC-based tamper detection
- IP Whitelisting - Restrict admin operations
Production-Ready
- Retry Mechanism - Exponential backoff for failed operations
- Circuit Breaker - Prevent cascading failures
- Batch Logging - Queue-based batch insert (100x faster)
- Health Checks - Kubernetes liveness/readiness probes
- Metrics - Prometheus-compatible metrics export
- Graceful Shutdown - Zero data loss on shutdown
Developer Experience
- Zero Configuration - Auto-creates tables on first run
- TypeScript - Full type definitions
- Express Middleware - Auto-log HTTP requests (Express 4.x & 5.x compatible)
- Axios Interceptor - Auto-log API calls
Installation
npm install @imexs/audit-trailPeer Dependencies
npm install knex pg uuid
# For Express users (v4.x or v5.x)
npm install express
# For Axios users
npm install axiosNote: This package supports both Express 4.x and Express 5.1.0+
Quick Start
Setup in Your Project
1. Setup Environment
Create .env:
DB_HOST=localhost
DB_PORT=5432
DB_NAME=audit_trail_db
DB_USER=postgres
DB_PASSWORD=your_password
APP_NAME=example-app
# Security
AUDIT_ENCRYPTION_KEY= # openssl rand -hex 32
AUDIT_HASH_SALT= # openssl rand -hex 32
AUDIT_INTEGRITY_KEY= # openssl rand -hex 32
# Rate Limiting
AUDIT_RATE_LIMIT_POINTS=100
AUDIT_RATE_LIMIT_DURATION=60
# Batch Logging
AUDIT_BATCH_SIZE=100
AUDIT_FLUSH_INTERVAL=50002. Initialize
const auditTrail = require('@imexs/audit-trail');
// Tables auto-created on first use
auditTrail.ConfigManager.getInstance(
appName: process.env.APP_NAME || 'example-app',
enabled: process.env.AUDIT_ENABLED || true,
database: {
host: process.env.DB_HOST,
port: process.env.DB_PORT,
database: process.env.DB_NAME,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
ssl: process.env.DB_SSL || false
},
maskedFields: ['password', 'token', 'credit_card', 'cvv', 'pin'],
autoFlush: true,
flushInterval: 5000
);3. Start Logging
const express = require('express');
const app = express();
// This function will log all API requests.
app.use(auditTrail.createHttpLogger({
captureBody: true,
captureHeaders: true,
excludePaths: [
'/health',
'/api/audit' // Skip all endpoint /api/audit/*
],
userId: 'SYSTEM' // You can change it to your own or from JWT token
}));User Activity
You can put this function anywhere if you want to record user activity.
// CREATE
await auditTrail.setUserActivity({
user_id: req.userId,
action: 'CREATE',
entity: 'order',
platform: 'web',
service_name: 'orders',
entity_id: 'ORD123',
after: { total: 100 }
});
// UPDATE
await auditTrail.setUserActivity({
user_id: req.userId,
action: 'UPDATE',
entity: 'product',
platform: 'mobile',
service_name: 'inventory',
before: { price: 99 },
after: { price: 79 }
});
// DELETE
await auditTrail.setUserActivity({
user_id: req.userId,
action: 'DELETE',
entity: 'product',
platform: 'web',
service_name: 'inventory',
entity_id: 'ORD123'
});
// READ
await auditTrail.setUserActivity({
user_id: req.userId,
action: 'READ',
entity: 'product',
platform: 'web',
service_name: 'inventory',
entity_id: 'ORD123'
});System Integration
await auditTrail.setSystemIntegration({
integration_name: 'SAP',
endpoint: '/api/sap/push-to-sap',
method: 'POST',
user_id: 'SYSTEM',
platform: 'api',
service_name: 'confirm-storage',
entity_id: 'ORD123',
before: { price: 99 },
after: { price: 79 }
});Data Accountability
await auditTrail.setDataAccountability({
user_id: 'SYSTEM',
action: 'READ',
entity: 'product',
platform: 'web',
service_name: 'inventory',
entity_id: 'ORD123'
});Security Features
Encryption
const { getEncryptionInstance } = require('@imexs/audit-trail');
const encryption = getEncryptionInstance();
const encrypted = encryption.encrypt('sensitive data');
const decrypted = encryption.decrypt(encrypted.encrypted, encrypted.iv, encrypted.authTag);Rate Limiting
- Membatasi jumlah request yang bisa dilakukan user/IP dalam waktu tertentu.
- Mencegah DoS Attack, Melindungi Database, Fair Usage
const { getUserRateLimiter } = require('@imexs/audit-trail');
const limiter = getUserRateLimiter();
await limiter.checkLimit(req.userId);RBAC (Role-Based Access Control)
- Mencegah akses ke API yang tidak diizinkan
- Mengatur siapa boleh akses apa berdasarkan role.
const { AuditAuthorizationMiddleware, AuditPermission } = require('@imexs/audit-trail');
app.get('/api/audit/logs',
AuditAuthorizationMiddleware.checkPermission(AuditPermission.READ_ALL),
async (req, res) => {
const logs = await auditTrail.query({});
res.json(logs);
}
);Other Features
Health Checks
const { getHealthCheck } = require('@imexs/audit-trail');
const health = getHealthCheck();
app.get('/health/live', async (req, res) => {
res.json(await health.liveness());
});
app.get('/health/ready', async (req, res) => {
const status = await health.readiness();
res.status(status.ready ? 200 : 503).json(status);
});Metrics
const { getMetrics } = require('@imexs/audit-trail');
const metrics = getMetrics();
app.get('/metrics', (req, res) => {
res.set('Content-Type', 'text/plain');
res.send(metrics.toPrometheus());
});Graceful Shutdown
const { initializeGracefulShutdown } = require('@imexs/audit-trail');
initializeGracefulShutdown();
// Automatic cleanup on SIGTERM/SIGINTOther Get Data
- You can use this function or you can create your own query to get audit-trail data.
// Performance API Metrics (with pagination & keyword search)
const filters = {
date: new Date(req.body.date),
time: req.body.time || null, // Optional: HH:mm format (24h Jakarta time)
platform: req.body.platform || null, // Optional: Filter by platform
status: req.body.status || null, // Optional: Filter by status (Success/Failed)
keyword: req.body.keyword || null, // Optional: Search in service_name, endpoint
limit: req.body.limit || 100, // Optional: Pagination limit (default: 100)
offset: req.body.offset || 0 // Optional: Pagination offset (default: 0)
};
const result = await auditTrail.PerformanceApi().getPerformanceApiMetrics(filters);
// Response: { data: [...], pagination: { total, limit, offset, totalPages, currentPage } }
// Performance Server Metrics (with pagination & keyword search)
const filters = {
date: new Date(req.body.date),
time: req.body.time || null, // Optional: HH:mm format (24h Jakarta time)
platform: req.body.platform || null, // Optional: Filter by platform
status: req.body.status || null, // Optional: Filter by status (Success/Failed)
keyword: req.body.keyword || null, // Optional: Search in service_name, action, endpoint
limit: req.body.limit || 100, // Optional: Pagination limit (default: 100)
offset: req.body.offset || 0 // Optional: Pagination offset (default: 0)
};
const result = await auditTrail.PerformanceApi().getPerformanceServerMetrics(filters);
// Response: { data: [...], pagination: { total, limit, offset, totalPages, currentPage } }
// Performance User Activity (with pagination & keyword search)
const filters = {
date: new Date(req.body.date),
time: req.body.time || null, // Optional: HH:mm format (24h Jakarta time)
platform: req.body.platform || null, // Optional: Filter by platform
status: req.body.status || null, // Optional: Filter by status (Success/Failed)
keyword: req.body.keyword || null, // Optional: Search in service_name, action
limit: req.body.limit || 100, // Optional: Pagination limit (default: 100)
offset: req.body.offset || 0 // Optional: Pagination offset (default: 0)
};
const result = await auditTrail.PerformanceApi().getPerformanceUserActivity(filters);
// Response: { data: [...], pagination: { total, limit, offset, totalPages, currentPage } }
// Get All Logs
const filters = {
actor_user_id: req.query.user_id,
action: req.query.action,
entity: req.query.entity,
endpoint: req.query.endpoint,
platform: req.query.platform,
service_name: req.query.service,
request_status: req.query.status,
severity: req.query.severity,
start_date: req.query.start_date ? new Date(req.query.start_date) : undefined,
end_date: req.query.end_date ? new Date(req.query.end_date) : undefined,
min_response_time: req.query.min_response_time ? parseInt(req.query.min_response_time) : undefined,
max_response_time: req.query.max_response_time ? parseInt(req.query.max_response_time) : undefined
};
const options = {
limit: parseInt(req.query.limit) || 100,
offset: parseInt(req.query.offset) || 0,
orderBy: req.query.order_by || 'timestamp',
orderDirection: req.query.order_dir || 'desc'
};
const result = await auditTrailApi.getAllLogs(filters, options);
// Get performance summary
const filters = {
start_date: req.query.start_date ? new Date(req.query.start_date) : undefined,
end_date: req.query.end_date ? new Date(req.query.end_date) : undefined
};
const result = await auditTrailApi.getEndpointStats(filters);
// Get health metrics
const filters = {
date: new Date(req.body.date),
shift: req.body.shift || undefined, // Optional: 'morning' or 'night'
start_time: req.body.start_time || undefined, // Optional: HH:mm format
end_time: req.body.end_time || undefined // Optional: HH:mm format
};
const result = await auditTrailApi.HealthApi().getSummaryHealth(filters);
// Get system load summary
const filters = {
date: new Date(req.body.date),
time: req.body.time || undefined // Optional: HH:mm format (24h Jakarta time)
};
const result = await auditTrailApi.getSummarySystemLoad(filters);
// Get top 5 slowest APIs
const filters = {
date: new Date(req.body.date),
time: req.body.time || undefined // Optional: HH:mm format (24h Jakarta time)
};
const result = await auditTrailApi.getTop5SlowApi(filters);
// Get CPU usage summary (POST)
const filters = {
date: new Date(req.body.date),
time: req.body.time || undefined // Optional: HH:mm format (24h Jakarta time)
};
const result = await auditTrailApi.getSummaryCpuUsage(filters);
// Get Memory usage summary (POST)
const filters = {
date: new Date(req.body.date),
time: req.body.time || undefined // Optional: HH:mm format (24h Jakarta time)
};
const result = await auditTrailApi.getSummaryMemoryUsage(filters);
// Get active users with top 3 (POST)
const filters = {
date: new Date(req.body.date),
time: req.body.time || undefined // Optional: HH:mm format (24h Jakarta time)
};
const result = await auditTrailApi.getActiveUsers(filters);
Compliance
- GDPR - Data protection & privacy
- SOC 2 - Security controls & audit trails
- HIPAA - Healthcare data security
- PCI DSS - Payment data security
- ISO 27001 - Information security management
API Reference
Core Functions
- `setUserActivity(input)` - Log user actions
- `setSystemIntegration(input)` - Log API calls
- `setDataAccountability(input)` - Log data access
- `setPerformance(input)` - Log performance metrics
Security Functions
- `getEncryptionInstance()` - Get encryption service
- `getUserRateLimiter()` - Get rate limiter
- `getIntegrityChecker()` - Get integrity checker
- `AuditInputValidator` - Input validation utilities
Other Functions
- `getRetryPolicy()` - Get retry mechanism
- `getCircuitBreaker()` - Get circuit breaker
- `getBatchLogger()` - Get batch logger
- `getHealthCheck()` - Get health check service
- `getMetrics()` - Get metrics collector
- `initializeGracefulShutdown()` - Setup graceful shutdown
Contributing
Contributions welcome! See CONTRIBUTING.md
License
MIT © IMEXS
Links
Made with ❤️ by IMEXS
