107 lines
2.6 KiB
JavaScript
107 lines
2.6 KiB
JavaScript
// services/auditLogger.js
|
|
/**
|
|
* Audit Logging Service
|
|
*
|
|
* Logs all API requests with user context, action, route, status, and timestamp
|
|
* Logs both success and failure cases
|
|
*/
|
|
|
|
// In-memory log store (for development/testing)
|
|
// In production, you should integrate with a logging service (e.g., Winston, Bunyan, CloudWatch, etc.)
|
|
const auditLogs = [];
|
|
|
|
/**
|
|
* Audit Logger Class
|
|
*/
|
|
class AuditLogger {
|
|
constructor(req) {
|
|
this.req = req;
|
|
this.userId = req.user?.userId || null;
|
|
this.clientIp = req.clientIp || 'unknown';
|
|
this.userAgent = req.userAgent || 'unknown';
|
|
this.requestId = req.requestId;
|
|
this.route = req.path;
|
|
this.method = req.method;
|
|
}
|
|
|
|
/**
|
|
* Log an audit event
|
|
*
|
|
* @param {Object} params
|
|
* @param {string} params.action - Action being performed
|
|
* @param {string} params.status - Status ('success', 'failed', 'forbidden', etc.)
|
|
* @param {Object} params.meta - Additional metadata
|
|
*/
|
|
log({ action, status = 'success', meta = {} }) {
|
|
const auditEntry = {
|
|
timestamp: new Date().toISOString(),
|
|
requestId: this.requestId,
|
|
userId: this.userId,
|
|
action,
|
|
route: this.route,
|
|
method: this.method,
|
|
status,
|
|
clientIp: this.clientIp,
|
|
userAgent: this.userAgent,
|
|
meta,
|
|
};
|
|
|
|
// In production, send to logging service (e.g., CloudWatch, Elasticsearch, etc.)
|
|
// For now, log to console and store in memory
|
|
console.log('[AUDIT]', JSON.stringify(auditEntry));
|
|
|
|
auditLogs.push(auditEntry);
|
|
|
|
// Keep only last 1000 logs in memory
|
|
if (auditLogs.length > 1000) {
|
|
auditLogs.shift();
|
|
}
|
|
|
|
// TODO: Integrate with external logging service
|
|
// Example:
|
|
// if (process.env.LOGGING_SERVICE_URL) {
|
|
// axios.post(process.env.LOGGING_SERVICE_URL + '/audit', auditEntry).catch(err => {
|
|
// console.error('Failed to send audit log:', err);
|
|
// });
|
|
// }
|
|
}
|
|
|
|
/**
|
|
* Log successful request
|
|
*/
|
|
logSuccess(action, meta = {}) {
|
|
this.log({ action, status: 'success', meta });
|
|
}
|
|
|
|
/**
|
|
* Log failed request
|
|
*/
|
|
logFailure(action, reason, meta = {}) {
|
|
this.log({ action, status: 'failed', meta: { ...meta, reason } });
|
|
}
|
|
|
|
/**
|
|
* Log forbidden access
|
|
*/
|
|
logForbidden(action, reason, meta = {}) {
|
|
this.log({ action, status: 'forbidden', meta: { ...meta, reason } });
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Middleware to attach audit logger to request
|
|
*/
|
|
export function auditLoggerMiddleware(req, res, next) {
|
|
req.auditLogger = new AuditLogger(req);
|
|
next();
|
|
}
|
|
|
|
/**
|
|
* Get audit logs (for debugging/admin purposes)
|
|
*/
|
|
export function getAuditLogs(limit = 100) {
|
|
return auditLogs.slice(-limit);
|
|
}
|
|
|
|
export default AuditLogger;
|