forked from SmartDropLabs/smartdrop-backend
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapiKeyAuditLog.js
More file actions
100 lines (93 loc) · 2.52 KB
/
Copy pathapiKeyAuditLog.js
File metadata and controls
100 lines (93 loc) · 2.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
const knex = require('knex');
const config = require('../config');
const logger = require('../logger');
let db = null;
function getDb() {
if (!db) {
db = knex({
client: 'pg',
connection: config.databaseUrl,
pool: { min: 2, max: 10 },
});
}
return db;
}
/**
* Log API key usage to audit trail
*
* @param {object} options
* @param {string} options.keyId - The API key ID
* @param {string} options.endpoint - The endpoint accessed (e.g., "GET /api/prices")
* @param {string} options.ipAddress - Client IP address
* @param {number} options.statusCode - HTTP response status code
* @param {number} options.responseTimeMs - Request duration in milliseconds
*/
async function logUsage({ keyId, endpoint, ipAddress, statusCode, responseTimeMs }) {
try {
if (!keyId || keyId === 'admin') {
// Skip logging for admin key or missing key
return;
}
await getDb()('api_key_audit_logs').insert({
key_id: keyId,
endpoint,
ip_address: ipAddress,
status_code: statusCode,
response_time_ms: responseTimeMs,
created_at: new Date(),
});
} catch (err) {
// Log the error but don't fail the request
logger.error('Failed to log API key audit trail', {
keyId,
endpoint,
error: err.message,
});
}
}
/**
* Get audit log entries for a specific API key
*
* @param {string} keyId - The API key ID
* @param {number} limit - Maximum number of entries to return
* @param {number} offset - Number of entries to skip
* @returns {Promise<Array>} Audit log entries
*/
async function getKeyAuditLog(keyId, limit = 100, offset = 0) {
try {
return await getDb()('api_key_audit_logs')
.where('key_id', keyId)
.orderBy('created_at', 'desc')
.limit(limit)
.offset(offset);
} catch (err) {
logger.error('Failed to fetch API key audit log', {
keyId,
error: err.message,
});
return [];
}
}
/**
* Get recent audit log entries for all keys (admin only)
*
* @param {number} limit - Maximum number of entries to return
* @param {number} offset - Number of entries to skip
* @returns {Promise<Array>} Audit log entries
*/
async function getAllAuditLogs(limit = 100, offset = 0) {
try {
return await getDb()('api_key_audit_logs')
.orderBy('created_at', 'desc')
.limit(limit)
.offset(offset);
} catch (err) {
logger.error('Failed to fetch all API key audit logs', { error: err.message });
return [];
}
}
module.exports = {
logUsage,
getKeyAuditLog,
getAllAuditLogs,
};