/** * Middleware de autenticación para API * * Asegura que TODAS las rutas /api/* estén protegidas: * - Rutas con Authentik: Requieren header x-authentik-username * - Rutas sin Authentik (expuestas): Requieren Bearer token válido */ import { query } from '../utils/database' // Rutas que NO pasan por Authentik (expuestas con API Key) const API_KEY_ROUTES = [ '/api/messages/send', '/api/mcp' ] // Rutas públicas (sin autenticación) const PUBLIC_ROUTES = [ '/api/health' ] export default defineEventHandler(async (event) => { const path = getRequestURL(event).pathname // Solo aplicar a rutas /api/* if (!path.startsWith('/api/')) { return } // Rutas públicas - sin autenticación if (PUBLIC_ROUTES.some(route => path.startsWith(route))) { return } // Verificar si es ruta expuesta (sin Authentik) const isExposedRoute = API_KEY_ROUTES.some(route => path.startsWith(route)) if (isExposedRoute) { // Ruta expuesta: Requiere Bearer token const authHeader = getHeader(event, 'authorization') if (!authHeader?.startsWith('Bearer ')) { throw createError({ statusCode: 401, message: 'Authorization Bearer token required' }) } const token = authHeader.slice(7) const config = useRuntimeConfig() // Validar contra Master API Key if (config.masterApiKey && token === config.masterApiKey) { // Token válido - continuar return } // Validar contra API Keys en DB const crypto = await import('crypto') const keyHash = crypto.createHash('sha256').update(token).digest('hex') const keyResult = await query( `SELECT id FROM api_keys WHERE key_hash = $1 AND is_active = TRUE AND (expires_at IS NULL OR expires_at > NOW())`, [keyHash] ) if (keyResult.rows.length === 0) { throw createError({ statusCode: 401, message: 'Invalid API Key' }) } // Token válido - actualizar last_used await query( 'UPDATE api_keys SET last_used_at = NOW() WHERE id = $1', [keyResult.rows[0].id] ) return } // Ruta protegida por Authentik: Requiere header x-authentik-username const authentikUser = getHeader(event, 'x-authentik-username') if (!authentikUser) { throw createError({ statusCode: 401, message: 'Authentication required' }) } // Usuario autenticado - continuar })