239 lines
7.6 KiB
JavaScript
239 lines
7.6 KiB
JavaScript
/**
|
||
* 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();
|