105 lines
6.1 KiB
JavaScript
105 lines
6.1 KiB
JavaScript
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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
|