35 lines
1.3 KiB
JavaScript
35 lines
1.3 KiB
JavaScript
|
|
const { getDb } = require('../db/database');
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Log a security-sensitive action to the audit_log table.
|
||
|
|
* @param {Object} params
|
||
|
|
* @param {number|null} params.user_id - User ID (null for anonymous/failed attempts)
|
||
|
|
* @param {string} params.action - Action type (e.g., 'login.success', 'login.failure', 'password.change', 'role.change', 'session.invalidate')
|
||
|
|
* @param {string} [params.entity_type] - Entity type (e.g., 'user', 'session', 'bill')
|
||
|
|
* @param {number} [params.entity_id] - Entity ID
|
||
|
|
* @param {Object} [params.details] - Additional details (stored as JSON)
|
||
|
|
* @param {string} [params.ip_address] - Request IP
|
||
|
|
* @param {string} [params.user_agent] - Request user-agent
|
||
|
|
*/
|
||
|
|
function logAudit({ user_id, action, entity_type, entity_id, details, ip_address, user_agent }) {
|
||
|
|
const db = getDb();
|
||
|
|
try {
|
||
|
|
db.prepare(
|
||
|
|
`INSERT INTO audit_log (user_id, action, entity_type, entity_id, details_json, ip_address, user_agent)
|
||
|
|
VALUES (?, ?, ?, ?, ?, ?, ?)`
|
||
|
|
).run(
|
||
|
|
user_id || null,
|
||
|
|
action,
|
||
|
|
entity_type || null,
|
||
|
|
entity_id || null,
|
||
|
|
details ? JSON.stringify(details) : null,
|
||
|
|
ip_address || null,
|
||
|
|
user_agent || null
|
||
|
|
);
|
||
|
|
} catch (err) {
|
||
|
|
// Audit logging should never crash the app
|
||
|
|
console.error('[audit-error] Failed to log audit event:', err.message);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
module.exports = { logAudit };
|