import { Database } from '../database/database.js'; import { MongoStorage } from "@canmertinyo/rate-limiter-mongo"; import { rateLimiter } from "@canmertinyo/rate-limiter-core"; import { ApiKey } from '../models.js'; import { TelegramUseLogNotif } from '../lib/all.js'; import * as config from '../config.js'; const authenticateApiKeyPremium = async (req, res, next) => { const apiKey = req.headers['x-api-key']; if (!apiKey) { return res.status(401).json({ error: 'Premium API Key required' }); } try { const keyData = await ApiKey.findOne({ key: apiKey }); if (!keyData) { return res.status(403).json({ error: 'Invalid or non-premium API Key' }); } if (keyData.is_banned) { return res.status(403).json({ error: 'Banned API Key' }); } if (keyData.is_expired) { return res.status(403).json({ error: 'API Key is expired' }); } if (keyData.expiresAt && new Date() > keyData.expiresAt) { keyData.is_expired = true; await keyData.save(); await TelegramUseLogNotif(keyData.owner, keyData.key); return res.status(403).json({ error: 'Premium API Key has expired' }); } next(); } catch (err) { res.status(500).json({ error: 'Server error' }); } }; const authenticateApiKeyDev = async (req, res, next) => { const apiKey = req.headers['x-api-key']; const xhacker = req.headers['x-hacker-bypass-v1']; const dbClient = new Database("AkenoXJs"); const db = dbClient.collection("api_keys_dev"); if (!apiKey && !xhacker) { return res.status(401).json({ error: 'API Key or bypass token required' }); } try { if (xhacker === "@xpushz") { console.log("Bypass activated via x-hacker-bypass-v1"); return next(); } const keyDoc = await db.findOne({ key: apiKey }); if (!keyDoc) { return res.status(403).json({ error: 'Invalid API Key Dev' }); } if (keyDoc.is_banned === true) { return res.status(403).json({ error: 'Banned API Key' }); } next(); } catch (err) { console.error("Error in authenticateApiKeyDev:", err); res.status(500).json({ error: 'Server error' }); } }; const authenticateApiKey = async (req, res, next) => { const apiKey = req.headers['x-api-key']; const dbClient = new Database("AkenoXJs"); const db = dbClient.collection("api_keys"); if (!apiKey) { return res.status(401).json({ error: 'API Key required' }); } try { const keyDoc = await db.findOne({key: apiKey}); if (!keyDoc) { return res.status(403).json({ error: 'Invalid API Key' }); } if (keyDoc.is_banned === true) { return res.status(403).json({ error: 'Banned API Key' }); } next(); } catch (err) { res.status(500).json({ error: 'Server error' }); } }; const apiLimiter = rateLimiter({ /* store: new MongoStore({ uri: dbUrls, collectionName: "rateLimits", }), */ ms: 2 * 60 * 1000, maxRequest: 100, keyGenerator: (req) => req.headers["x-api-key"], // standardHeaders: true, // legacyHeaders: false, message: (req, res) => { const retryAfterMs = res.getHeaders()["retry-after"] * 1000 || 2 * 60 * 1000; const remainingSeconds = Math.ceil(retryAfterMs / 1000); const remainingMinutes = Math.floor(remainingSeconds / 60); return { error: `Too many requests from this API Key. Try again later: ${remainingMinutes}m ${remainingSeconds % 60}s.` }; } }); class CheckMilWare { constructor() { this.dbClient = new Database("AkenoXJs"); } async handle(req, res, next) { try { const xForwardedFor = req.headers['x-forwarded-for']; const xRealIP = req.headers['x-real-ip']; const cfConnectingIP = req.headers['cf-connecting-ip']; let realIP = req.ip; if (xForwardedFor) { realIP = xForwardedFor.split(',')[0].trim(); } else if (xRealIP) { realIP = xRealIP; } else if (cfConnectingIP) { realIP = cfConnectingIP; } req.realIP = realIP; const isBlocked = await this.dbClient.CheckIsBlocked(realIP); if (isBlocked && isBlocked.blocked) { return res.status(403).send("Access denied: IP is blocked"); } if (req.path === '/.env') { console.log("Check path /env"); await this.dbClient.AddIpisBlocked(realIP); return res.status(403).send("Access denied: IP is blocked.."); } if (req.path.endsWith('.php')) { return res.status(403).send('Access to .php files is forbidden'); } res.on("finish", function() { console.log(`Real IP address is: ${realIP} path method: ${req.path} method: ${req.method} statusCode: ${res.statusCode} header used: ${xForwardedFor ? "x-forwarded-for" : xRealIP ? "x-real-ip" : cfConnectingIP ? "cf-connecting-ip" : "req.ip"} `); }); next(); } catch (error) { console.error("Error in middleware: " + error); res.status(500).send("Something bad happened"); } } } export { CheckMilWare, authenticateApiKey, authenticateApiKeyDev, authenticateApiKeyPremium, apiLimiter };