#!/usr/bin/env node /** * Admin Routes Test Script * Tests if admin routes are properly registered and accessible */ import axios from 'axios'; const API_URL = 'http://localhost:3000'; const COLORS = { reset: '\x1b[0m', red: '\x1b[31m', green: '\x1b[32m', yellow: '\x1b[33m', blue: '\x1b[34m', cyan: '\x1b[36m', }; function colorize(text, color) { return `${COLORS[color]}${text}${COLORS.reset}`; } function logSuccess(message) { console.log(`${colorize('✅', 'green')} ${message}`); } function logError(message) { console.log(`${colorize('❌', 'red')} ${message}`); } function logInfo(message) { console.log(`${colorize('ℹ️', 'blue')} ${message}`); } function logWarning(message) { console.log(`${colorize('⚠️', 'yellow')} ${message}`); } async function testHealth() { console.log('\n' + colorize('='.repeat(60), 'cyan')); console.log(colorize('TEST 1: Health Check', 'cyan')); console.log(colorize('='.repeat(60), 'cyan')); try { const response = await axios.get(`${API_URL}/health`, { timeout: 5000 }); logSuccess('Backend is running'); logInfo(` Uptime: ${Math.floor(response.data.uptime)}s`); logInfo(` Environment: ${response.data.environment}`); return true; } catch (error) { logError('Backend is not accessible'); logError(` Error: ${error.message}`); return false; } } async function testRoutesList() { console.log('\n' + colorize('='.repeat(60), 'cyan')); console.log(colorize('TEST 2: Routes List (Development Only)', 'cyan')); console.log(colorize('='.repeat(60), 'cyan')); try { const response = await axios.get(`${API_URL}/api/routes`, { timeout: 5000 }); const adminRoutes = response.data.routes.filter(r => r.url.includes('/api/admin')); const configRoutes = response.data.routes.filter(r => r.url.includes('/api/config')); logSuccess(`Found ${adminRoutes.length} admin routes`); logSuccess(`Found ${configRoutes.length} config routes`); console.log('\n' + colorize('Admin Routes:', 'yellow')); adminRoutes.slice(0, 10).forEach(route => { console.log(` ${colorize(route.method.padEnd(6), 'green')} ${route.url}`); }); if (adminRoutes.length > 10) { console.log(` ... and ${adminRoutes.length - 10} more`); } console.log('\n' + colorize('Config Routes:', 'yellow')); configRoutes.forEach(route => { console.log(` ${colorize(route.method.padEnd(6), 'green')} ${route.url}`); }); return adminRoutes.length > 0; } catch (error) { logWarning('Routes list not accessible (may be production mode)'); logInfo(' This is normal in production'); return null; // Not a failure, just unavailable } } async function testAdminConfigNoAuth() { console.log('\n' + colorize('='.repeat(60), 'cyan')); console.log(colorize('TEST 3: Admin Config (No Auth)', 'cyan')); console.log(colorize('='.repeat(60), 'cyan')); try { await axios.get(`${API_URL}/api/admin/config`, { timeout: 5000 }); logWarning('Admin config accessible without auth (security issue!)'); return false; } catch (error) { if (error.response?.status === 401) { logSuccess('Admin config properly protected (401 Unauthorized)'); return true; } else if (error.response?.status === 404) { logError('Admin config route not found (404)'); logError(' Routes may not be registered. Restart the server!'); return false; } else { logError(`Unexpected error: ${error.response?.status || error.message}`); return false; } } } async function testAdminUsersNoAuth() { console.log('\n' + colorize('='.repeat(60), 'cyan')); console.log(colorize('TEST 4: Admin Users Search (No Auth)', 'cyan')); console.log(colorize('='.repeat(60), 'cyan')); try { await axios.get(`${API_URL}/api/admin/users/search?query=test&limit=1`, { timeout: 5000 }); logWarning('Admin users route accessible without auth (security issue!)'); return false; } catch (error) { if (error.response?.status === 401) { logSuccess('Admin users route properly protected (401 Unauthorized)'); return true; } else if (error.response?.status === 404) { logError('Admin users route not found (404)'); logError(' Routes may not be registered. Restart the server!'); return false; } else { logError(`Unexpected error: ${error.response?.status || error.message}`); return false; } } } async function testPublicConfig() { console.log('\n' + colorize('='.repeat(60), 'cyan')); console.log(colorize('TEST 5: Public Config Status', 'cyan')); console.log(colorize('='.repeat(60), 'cyan')); try { const response = await axios.get(`${API_URL}/api/config/status`, { timeout: 5000 }); logSuccess('Public config status accessible'); logInfo(` Maintenance Mode: ${response.data.maintenance?.enabled ? 'ON' : 'OFF'}`); logInfo(` Trading: ${response.data.trading ? 'Enabled' : 'Disabled'}`); logInfo(` Market: ${response.data.market ? 'Enabled' : 'Disabled'}`); return true; } catch (error) { if (error.response?.status === 404) { logError('Public config route not found (404)'); logError(' Routes may not be registered. Restart the server!'); return false; } else { logError(`Error accessing public config: ${error.message}`); return false; } } } async function runTests() { console.log('\n' + colorize('╔' + '═'.repeat(58) + '╗', 'cyan')); console.log(colorize('║' + ' '.repeat(12) + 'ADMIN ROUTES TEST SUITE' + ' '.repeat(23) + '║', 'cyan')); console.log(colorize('╚' + '═'.repeat(58) + '╝', 'cyan')); const results = { health: false, routes: null, configNoAuth: false, usersNoAuth: false, publicConfig: false, }; // Run tests results.health = await testHealth(); if (!results.health) { console.log('\n' + colorize('='.repeat(60), 'red')); logError('Backend is not running. Start it with: npm run dev'); console.log(colorize('='.repeat(60), 'red')); process.exit(1); } results.routes = await testRoutesList(); results.configNoAuth = await testAdminConfigNoAuth(); results.usersNoAuth = await testAdminUsersNoAuth(); results.publicConfig = await testPublicConfig(); // Summary console.log('\n' + colorize('╔' + '═'.repeat(58) + '╗', 'cyan')); console.log(colorize('║' + ' '.repeat(21) + 'TEST SUMMARY' + ' '.repeat(24) + '║', 'cyan')); console.log(colorize('╚' + '═'.repeat(58) + '╝', 'cyan')); const passed = [ results.health, results.routes !== false, results.configNoAuth, results.usersNoAuth, results.publicConfig, ].filter(Boolean).length; const total = 5; console.log(`\n${colorize(`Passed: ${passed}/${total}`, passed === total ? 'green' : 'yellow')}`); if (results.configNoAuth === false || results.usersNoAuth === false || results.publicConfig === false) { console.log('\n' + colorize('⚠️ ACTION REQUIRED:', 'yellow')); console.log(colorize(' Routes are not registered properly.', 'yellow')); console.log(colorize(' Please RESTART the backend server:', 'yellow')); console.log(colorize(' 1. Stop server (Ctrl+C)', 'yellow')); console.log(colorize(' 2. Run: npm run dev', 'yellow')); console.log(colorize(' 3. Run this test again', 'yellow')); } else { console.log('\n' + colorize('✅ All routes are properly registered!', 'green')); console.log(colorize(' Admin panel should work correctly.', 'green')); console.log(colorize(' Access it at: http://localhost:5173/admin', 'green')); } console.log('\n' + colorize('='.repeat(60), 'cyan')); console.log(colorize('Note: These tests check route registration, not authentication.', 'blue')); console.log(colorize('To test full admin access, use the Debug panel in /admin', 'blue')); console.log(colorize('='.repeat(60), 'cyan') + '\n'); process.exit(passed === total ? 0 : 1); } // Run tests runTests().catch(error => { console.error('\n' + colorize('Fatal Error:', 'red'), error.message); process.exit(1); });