// test-admin-auth — verifica el middleware de /admin (hardcap-backend). // Ejecutar en la VPS: node /srv/hardcap-backend/runtime-tests/test-admin-auth.mjs // (o node runtime/hardcap/test-admin-auth.mjs desde el repo) // Requiere HARDCAP_ADMIN_TOKEN en el .env del servicio y el servicio activo en 127.0.0.1:3001. import { readFileSync } from 'node:fs' const BASE = 'http://127.0.0.1:3001' const env = Object.fromEntries( readFileSync('/srv/hardcap-backend/.env', 'utf8').split('\n').filter(l => l.includes('=')).map(l => [l.slice(0, l.indexOf('=')), l.slice(l.indexOf('=') + 1)]) ) const TOKEN = env.HARDCAP_ADMIN_TOKEN if (!TOKEN) { console.error('HARDCAP_ADMIN_TOKEN no configurado — el test no puede pasar'); process.exit(2) } let failed = 0 async function check(name, path, opts, expected) { const r = await fetch(BASE + path, { ...opts, signal: AbortSignal.timeout(8000) }) const ok = r.status === expected if (!ok) failed++ console.log(`${ok ? '✓' : '✗'} ${name}: esperado ${expected}, obtenido ${r.status}`) } await check('sin token → 401', '/admin/articles?status=QUEUED', {}, 401) await check('token incorrecto → 401', '/admin/articles?status=QUEUED', { headers: { Authorization: 'Bearer ' + 'x'.repeat(64) } }, 401) await check('token vacío en header → 401', '/admin/sources', { headers: { Authorization: 'Bearer ' } }, 401) await check('token correcto → 200', '/admin/articles?status=QUEUED', { headers: { Authorization: `Bearer ${TOKEN}` } }, 200) await check('header alternativo X-Admin-Token → 200', '/admin/sources', { headers: { 'x-admin-token': TOKEN } }, 200) // la comparación debe ser en tiempo constante: un token de la misma longitud pero distinto NO pasa await check('token misma longitud, distinto → 401', '/admin/articles?status=QUEUED', { headers: { Authorization: 'Bearer ' + 'y'.repeat(TOKEN.length) } }, 401) console.log(failed ? `\n${failed} TESTS FALLARON` : '\nTODOS LOS TESTS PASARON') process.exit(failed ? 1 : 0)