"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.trackApiUsage = trackApiUsage; exports.checkRateLimit = checkRateLimit; const migrate_1 = require("../db/migrate"); async function trackApiUsage(req, res, next) { // Only track if authenticated via API token if (!req.apiToken) { return next(); } const startTime = Date.now(); req.startTime = startTime; // Get request size const requestSize = req.headers['content-length'] ? parseInt(req.headers['content-length']) : 0; // Capture original res.json to measure response const originalJson = res.json.bind(res); let responseSize = 0; res.json = function (body) { responseSize = JSON.stringify(body).length; return originalJson(body); }; // Track after response is sent res.on('finish', async () => { const responseTime = Date.now() - startTime; try { await migrate_1.pool.query(` INSERT INTO api_token_usage ( token_id, endpoint, method, status_code, response_time_ms, request_size, response_size, ip_address, user_agent ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) `, [ req.apiToken.id, req.path, req.method, res.statusCode, responseTime, requestSize, responseSize, req.ip, req.headers['user-agent'] || null ]); // Update last_used_at await migrate_1.pool.query('UPDATE api_tokens SET last_used_at = CURRENT_TIMESTAMP WHERE id = $1', [req.apiToken.id]); } catch (error) { console.error('Error tracking API usage:', error); } }); next(); } // Rate limiting check async function checkRateLimit(req, res, next) { if (!req.apiToken) { return next(); } const { id, rate_limit } = req.apiToken; try { // Count requests in the last minute const result = await migrate_1.pool.query(` SELECT COUNT(*) as request_count FROM api_token_usage WHERE token_id = $1 AND created_at > NOW() - INTERVAL '1 minute' `, [id]); const requestCount = parseInt(result.rows[0].request_count); if (requestCount >= rate_limit) { return res.status(429).json({ error: 'Rate limit exceeded', limit: rate_limit, current: requestCount, retry_after: 60 }); } // Add rate limit headers res.setHeader('X-RateLimit-Limit', rate_limit.toString()); res.setHeader('X-RateLimit-Remaining', (rate_limit - requestCount).toString()); res.setHeader('X-RateLimit-Reset', new Date(Date.now() + 60000).toISOString()); next(); } catch (error) { console.error('Error checking rate limit:', error); next(); } }