import { readFileSync } from 'fs'; import { join, dirname } from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); let blocklist = { blockedIPs: [], blockedUserIds: [], blockedTokens: [], }; /** * Load blocklist from JSON file */ export function loadBlocklist() { try { const blocklistPath = join(process.cwd(), 'config', 'blocklist.json'); const data = readFileSync(blocklistPath, 'utf-8'); blocklist = JSON.parse(data); return blocklist; } catch (error) { console.error('Failed to load blocklist:', error); return blocklist; } } /** * Get current blocklist */ export function getBlocklist() { return blocklist; } /** * Check if an IP is blocked */ export function isIPBlocked(ip) { return blocklist.blockedIPs.includes(ip); } /** * Check if a user ID is blocked */ export function isUserBlocked(userId) { return blocklist.blockedUserIds.includes(userId); } /** * Check if an auth token is blocked */ export function isTokenBlocked(token) { return blocklist.blockedTokens.includes(token); } /** * Extract IP address from request */ function getClientIP(c) { const forwarded = c.req.header('x-forwarded-for'); if (forwarded) { return forwarded.split(',')[0].trim(); } return c.req.header('x-real-ip') || 'unknown'; } /** * Extract user ID from authorization header * This is a simple implementation - adjust based on your auth strategy */ function getUserId(c) { const authHeader = c.req.header('authorization'); if (!authHeader) return null; // Simple extraction - in production, you'd decode JWT or validate token // For now, we'll use the auth header as-is for blocklist checking return authHeader; } /** * Blocklist middleware * Blocks requests from blacklisted IPs, users, or tokens */ export async function blocklistMiddleware(c, next) { const ip = getClientIP(c); const authHeader = c.req.header('authorization'); const userId = getUserId(c); // Check if IP is blocked if (isIPBlocked(ip)) { return c.json({ error: 'Forbidden', message: 'Your IP address has been blocked', }, 403); } // Check if auth token is blocked if (authHeader && isTokenBlocked(authHeader)) { return c.json({ error: 'Forbidden', message: 'Your access token has been blocked', }, 403); } // Check if user ID is blocked if (userId && isUserBlocked(userId)) { return c.json({ error: 'Forbidden', message: 'Your account has been blocked', }, 403); } await next(); } // Load blocklist on module initialization loadBlocklist(); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmxvY2tsaXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21pZGRsZXdhcmUvYmxvY2tsaXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxJQUFJLENBQUE7QUFDakMsT0FBTyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUE7QUFDcEMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLEtBQUssQ0FBQTtBQUVuQyxNQUFNLFVBQVUsR0FBRyxhQUFhLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQTtBQUNqRCxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUE7QUFRckMsSUFBSSxTQUFTLEdBQWM7SUFDdkIsVUFBVSxFQUFFLEVBQUU7SUFDZCxjQUFjLEVBQUUsRUFBRTtJQUNsQixhQUFhLEVBQUUsRUFBRTtDQUNwQixDQUFBO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsYUFBYTtJQUN6QixJQUFJLENBQUM7UUFDRCxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxFQUFFLFFBQVEsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFBO1FBQ3JFLE1BQU0sSUFBSSxHQUFHLFlBQVksQ0FBQyxhQUFhLEVBQUUsT0FBTyxDQUFDLENBQUE7UUFDakQsU0FBUyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDNUIsT0FBTyxTQUFTLENBQUE7SUFDcEIsQ0FBQztJQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7UUFDYixPQUFPLENBQUMsS0FBSyxDQUFDLDJCQUEyQixFQUFFLEtBQUssQ0FBQyxDQUFBO1FBQ2pELE9BQU8sU0FBUyxDQUFBO0lBQ3BCLENBQUM7QUFDTCxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsWUFBWTtJQUN4QixPQUFPLFNBQVMsQ0FBQTtB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