/** * Script de vérification des endpoints admin * Teste que tous les endpoints sont accessibles et répondent correctement */ import 'dotenv/config'; const API_URL = process.env.API_URL || 'http://localhost:5000'; // Codes couleur pour terminal const colors = { reset: '\x1b[0m', green: '\x1b[32m', red: '\x1b[31m', yellow: '\x1b[33m', blue: '\x1b[34m', cyan: '\x1b[36m', }; const log = { success: (msg) => console.log(`${colors.green}✅ ${msg}${colors.reset}`), error: (msg) => console.log(`${colors.red}❌ ${msg}${colors.reset}`), info: (msg) => console.log(`${colors.blue}ℹ️ ${msg}${colors.reset}`), warn: (msg) => console.log(`${colors.yellow}⚠️ ${msg}${colors.reset}`), section: (msg) => console.log(`\n${colors.cyan}${'='.repeat(60)}${colors.reset}\n${colors.cyan}${msg}${colors.reset}\n${colors.cyan}${'='.repeat(60)}${colors.reset}`), }; /** * Vérifie qu'un endpoint répond (sans authentification) */ async function checkEndpoint(method, path, description) { try { const response = await fetch(`${API_URL}${path}`, { method, headers: { 'Content-Type': 'application/json' }, }); const statusOk = response.status >= 200 && response.status < 500; if (statusOk) { log.success(`${method} ${path} - ${response.status} - ${description}`); return { success: true, status: response.status, path }; } else { log.error(`${method} ${path} - ${response.status} - ${description}`); return { success: false, status: response.status, path }; } } catch (error) { log.error(`${method} ${path} - NETWORK ERROR - ${error.message}`); return { success: false, error: error.message, path }; } } /** * Teste les routes publiques */ async function testPublicRoutes() { log.section('🌍 Routes Publiques'); const routes = [ { method: 'GET', path: '/', desc: 'API status' }, { method: 'GET', path: '/db-check', desc: 'Database connection' }, { method: 'GET', path: '/metrics', desc: 'Prometheus metrics' }, ]; const results = []; for (const route of routes) { const result = await checkEndpoint(route.method, route.path, route.desc); results.push(result); } return results; } /** * Teste les routes d'authentification */ async function testAuthRoutes() { log.section('🔐 Routes Authentification'); const routes = [ { method: 'POST', path: '/api/auth/register', desc: 'Register endpoint' }, { method: 'POST', path: '/api/auth/login', desc: 'Login endpoint' }, { method: 'POST', path: '/api/auth/oauth/google', desc: 'Google OAuth endpoint' }, { method: 'POST', path: '/api/auth/oauth/facebook', desc: 'Facebook OAuth endpoint' }, ]; const results = []; for (const route of routes) { const result = await checkEndpoint(route.method, route.path, route.desc); results.push(result); } return results; } /** * Teste les routes admin (doivent retourner 401/403 sans token) */ async function testAdminRoutes() { log.section('👑 Routes Admin (protected)'); const routes = [ { method: 'GET', path: '/api/admin/statistics', desc: 'Dashboard statistics' }, { method: 'GET', path: '/api/admin/users', desc: 'Get all users' }, { method: 'GET', path: '/api/admin/tickets', desc: 'Get all tickets' }, { method: 'POST', path: '/api/admin/generate-tickets', desc: 'Generate tickets' }, { method: 'GET', path: '/api/game/prizes', desc: 'Get prizes' }, ]; log.info('Ces routes doivent retourner 401 (Unauthorized) sans token - c\'est normal!'); const results = []; for (const route of routes) { const result = await checkEndpoint(route.method, route.path, route.desc); // Pour les routes protégées, 401 est un succès (route existe et est protégée) if (result.status === 401 || result.status === 403) { result.isProtected = true; log.info(` → Route correctement protégée`); } results.push(result); } return results; } /** * Teste les routes de tirage au sort */ async function testDrawRoutes() { log.section('🎲 Routes Tirage au Sort (protected)'); const routes = [ { method: 'GET', path: '/api/draw/eligible-participants', desc: 'Get eligible participants' }, { method: 'GET', path: '/api/draw/check-existing', desc: 'Check existing draw' }, { method: 'POST', path: '/api/draw/conduct', desc: 'Conduct draw' }, { method: 'GET', path: '/api/draw/history', desc: 'Draw history' }, ]; log.info('Ces routes doivent retourner 401 (Unauthorized) sans token - c\'est normal!'); const results = []; for (const route of routes) { const result = await checkEndpoint(route.method, route.path, route.desc); if (result.status === 401 || result.status === 403) { result.isProtected = true; log.info(` → Route correctement protégée`); } results.push(result); } return results; } /** * Résumé final */ function printSummary(allResults) { log.section('📊 Résumé de la Vérification'); const total = allResults.length; const reachable = allResults.filter(r => r.success).length; const protectedRoutes = allResults.filter(r => r.isProtected).length; const errors = allResults.filter(r => !r.success && !r.isProtected).length; console.log(`Total endpoints testés: ${total}`); console.log(`${colors.green}✅ Endpoints accessibles: ${reachable}${colors.reset}`); console.log(`${colors.blue}🔒 Endpoints protégés: ${protectedRoutes}${colors.reset}`); console.log(`${colors.red}❌ Erreurs: ${errors}${colors.reset}`); const successRate = Math.round(((reachable + protectedRoutes) / total) * 100); console.log(`\n${colors.cyan}Taux de succès: ${successRate}%${colors.reset}`); if (successRate === 100) { log.success('Tous les endpoints sont opérationnels! 🎉'); } else if (successRate >= 90) { log.warn('Quelques endpoints ont des problèmes mineurs'); } else { log.error('Plusieurs endpoints ne fonctionnent pas correctement'); } // Afficher les erreurs const failed = allResults.filter(r => !r.success && !r.isProtected); if (failed.length > 0) { console.log(`\n${colors.red}Endpoints en erreur:${colors.reset}`); failed.forEach(f => { console.log(` - ${f.path} (${f.status || 'NETWORK ERROR'})`); }); } } /** * Fonction principale */ async function main() { console.log(`${colors.cyan}`); console.log('╔════════════════════════════════════════════════════════════╗'); console.log('║ VÉRIFICATION DES ENDPOINTS ADMIN - THÉ TIP TOP ║'); console.log('╚════════════════════════════════════════════════════════════╝'); console.log(`${colors.reset}\n`); log.info(`API URL: ${API_URL}`); log.info('Démarrage des tests...\n'); try { const allResults = []; // Test routes publiques const publicResults = await testPublicRoutes(); allResults.push(...publicResults); // Test routes auth const authResults = await testAuthRoutes(); allResults.push(...authResults); // Test routes admin const adminResults = await testAdminRoutes(); allResults.push(...adminResults); // Test routes tirage const drawResults = await testDrawRoutes(); allResults.push(...drawResults); // Résumé printSummary(allResults); // Exit code const hasErrors = allResults.some(r => !r.success && !r.isProtected); process.exit(hasErrors ? 1 : 0); } catch (error) { log.error(`Erreur critique: ${error.message}`); console.error(error); process.exit(1); } } // Lancer le script main();