"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const express_1 = require("express"); const middleware_1 = require("../auth/middleware"); const migrate_1 = require("../db/migrate"); const crypto_1 = __importDefault(require("crypto")); const router = (0, express_1.Router)(); router.use(middleware_1.authMiddleware); // Generate secure random token function generateToken() { return crypto_1.default.randomBytes(32).toString('hex'); } // Get all API tokens router.get('/', (0, middleware_1.requireRole)('superadmin', 'admin'), async (req, res) => { try { const result = await migrate_1.pool.query(` SELECT t.*, u.email as created_by_email, ( SELECT COUNT(*) FROM api_token_usage WHERE token_id = t.id AND created_at > NOW() - INTERVAL '24 hours' ) as requests_24h, ( SELECT COUNT(*) FROM api_token_usage WHERE token_id = t.id AND created_at > NOW() - INTERVAL '7 days' ) as requests_7d, ( SELECT COUNT(*) FROM api_token_usage WHERE token_id = t.id ) as total_requests FROM api_tokens t LEFT JOIN users u ON t.user_id = u.id ORDER BY t.created_at DESC `); res.json({ tokens: result.rows }); } catch (error) { console.error('Error fetching API tokens:', error); res.status(500).json({ error: 'Failed to fetch API tokens' }); } }); // Get single API token router.get('/:id', (0, middleware_1.requireRole)('superadmin', 'admin'), async (req, res) => { try { const { id } = req.params; const result = await migrate_1.pool.query(` SELECT t.*, u.email as created_by_email FROM api_tokens t LEFT JOIN users u ON t.user_id = u.id WHERE t.id = $1 `, [id]); if (result.rows.length === 0) { return res.status(404).json({ error: 'Token not found' }); } res.json({ token: result.rows[0] }); } catch (error) { console.error('Error fetching API token:', error); res.status(500).json({ error: 'Failed to fetch API token' }); } }); // Create new API token router.post('/', (0, middleware_1.requireRole)('superadmin', 'admin'), async (req, res) => { try { const { name, description, rate_limit, allowed_endpoints, expires_at } = req.body; const userId = req.user.userId; if (!name) { return res.status(400).json({ error: 'Name is required' }); } const token = generateToken(); const result = await migrate_1.pool.query(` INSERT INTO api_tokens ( name, token, description, user_id, rate_limit, allowed_endpoints, expires_at ) VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING * `, [ name, token, description || null, userId, rate_limit || 100, allowed_endpoints || null, expires_at || null ]); res.status(201).json({ token: result.rows[0], message: 'API token created successfully. Save this token securely - it cannot be retrieved later.' }); } catch (error) { console.error('Error creating API token:', error); res.status(500).json({ error: 'Failed to create API token' }); } }); // Update API token router.put('/:id', (0, middleware_1.requireRole)('superadmin', 'admin'), async (req, res) => { try { const { id } = req.params; const { name, description, active, rate_limit, allowed_endpoints, expires_at } = req.body; const result = await migrate_1.pool.query(` UPDATE api_tokens SET name = COALESCE($1, name), description = COALESCE($2, description), active = COALESCE($3, active), rate_limit = COALESCE($4, rate_limit), allowed_endpoints = COALESCE($5, allowed_endpoints), expires_at = COALESCE($6, expires_at) WHERE id = $7 RETURNING * `, [name, description, active, rate_limit, allowed_endpoints, expires_at, id]); if (result.rows.length === 0) { return res.status(404).json({ error: 'Token not found' }); } res.json({ token: result.rows[0] }); } catch (error) { console.error('Error updating API token:', error); res.status(500).json({ error: 'Failed to update API token' }); } }); // Delete API token router.delete('/:id', (0, middleware_1.requireRole)('superadmin'), async (req, res) => { try { const { id } = req.params; const result = await migrate_1.pool.query('DELETE FROM api_tokens WHERE id = $1 RETURNING *', [id]); if (result.rows.length === 0) { return res.status(404).json({ error: 'Token not found' }); } res.json({ message: 'API token deleted successfully' }); } catch (error) { console.error('Error deleting API token:', error); res.status(500).json({ error: 'Failed to delete API token' }); } }); // Get token usage statistics router.get('/:id/usage', (0, middleware_1.requireRole)('superadmin', 'admin'), async (req, res) => { try { const { id } = req.params; const { days = 7 } = req.query; // Get hourly usage for the past N days const hourlyUsage = await migrate_1.pool.query(` SELECT DATE_TRUNC('hour', created_at) as hour, COUNT(*) as requests, AVG(response_time_ms) as avg_response_time, SUM(CASE WHEN status_code >= 200 AND status_code < 300 THEN 1 ELSE 0 END) as successful_requests, SUM(CASE WHEN status_code >= 400 THEN 1 ELSE 0 END) as failed_requests FROM api_token_usage WHERE token_id = $1 AND created_at > NOW() - INTERVAL '${parseInt(days)} days' GROUP BY hour ORDER BY hour DESC `, [id]); // Get endpoint usage const endpointUsage = await migrate_1.pool.query(` SELECT endpoint, method, COUNT(*) as requests, AVG(response_time_ms) as avg_response_time FROM api_token_usage WHERE token_id = $1 AND created_at > NOW() - INTERVAL '${parseInt(days)} days' GROUP BY endpoint, method ORDER BY requests DESC LIMIT 20 `, [id]); // Get recent requests const recentRequests = await migrate_1.pool.query(` SELECT endpoint, method, status_code, response_time_ms, ip_address, created_at FROM api_token_usage WHERE token_id = $1 ORDER BY created_at DESC LIMIT 100 `, [id]); res.json({ hourly_usage: hourlyUsage.rows, endpoint_usage: endpointUsage.rows, recent_requests: recentRequests.rows }); } catch (error) { console.error('Error fetching token usage:', error); res.status(500).json({ error: 'Failed to fetch token usage' }); } }); // Get overall API usage statistics router.get('/stats/overview', (0, middleware_1.requireRole)('superadmin', 'admin'), async (req, res) => { try { const { days = 7 } = req.query; const stats = await migrate_1.pool.query(` SELECT COUNT(DISTINCT token_id) as active_tokens, COUNT(*) as total_requests, AVG(response_time_ms) as avg_response_time, SUM(CASE WHEN status_code >= 200 AND status_code < 300 THEN 1 ELSE 0 END) as successful_requests, SUM(CASE WHEN status_code >= 400 THEN 1 ELSE 0 END) as failed_requests FROM api_token_usage WHERE created_at > NOW() - INTERVAL '${parseInt(days)} days' `); // Top tokens by usage const topTokens = await migrate_1.pool.query(` SELECT t.id, t.name, COUNT(u.id) as requests, AVG(u.response_time_ms) as avg_response_time FROM api_tokens t LEFT JOIN api_token_usage u ON t.id = u.token_id WHERE u.created_at > NOW() - INTERVAL '${parseInt(days)} days' GROUP BY t.id, t.name ORDER BY requests DESC LIMIT 10 `); // Most used endpoints const topEndpoints = await migrate_1.pool.query(` SELECT endpoint, method, COUNT(*) as requests, AVG(response_time_ms) as avg_response_time FROM api_token_usage WHERE created_at > NOW() - INTERVAL '${parseInt(days)} days' GROUP BY endpoint, method ORDER BY requests DESC LIMIT 10 `); res.json({ overview: stats.rows[0], top_tokens: topTokens.rows, top_endpoints: topEndpoints.rows }); } catch (error) { console.error('Error fetching API stats:', error); res.status(500).json({ error: 'Failed to fetch API stats' }); } }); exports.default = router;