File size: 5,734 Bytes
99c40f3 89e56d1 f576901 fcd016f 89e56d1 dd7c356 ba3cba1 ad17f38 ba3cba1 f576901 95871cd f10cf51 ba3cba1 f10cf51 ba3cba1 95871cd ba3cba1 95871cd f576901 708fb5f f576901 280c5dd 5607a19 280c5dd f576901 33c0d7a f576901 337ec73 c1fb847 337ec73 c1fb847 2aac949 c1fb847 337ec73 c1fb847 337ec73 c1fb847 337ec73 c1fb847 337ec73 c1fb847 337ec73 59c12a7 e6acbde 95871cd 0963c15 95871cd 0963c15 95871cd 59c12a7 e6acbde 59c12a7 5607a19 59c12a7 84669c7 89e56d1 c3052e3 dc80896 84669c7 dc80896 c3052e3 89e56d1 521427a f1436b2 89e56d1 f1436b2 dc80896 f1436b2 59c12a7 e151afc 21cab6c e6acbde 21cab6c e151afc 21cab6c e151afc 6f9e59b 21cab6c e151afc 21cab6c 06932c2 e151afc 6f9e59b e151afc 21cab6c e151afc c82fac4 ba0cefc e151afc 21cab6c 6222fc9 59c12a7 337ec73 f576901 c1aabc1 59c12a7 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
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 ALLOWED_UA_REGEX = /^Ryzenth\/(Python|TS|Rust)-\d+\.\d+/;
const EXTRA_ALLOWED_UA = [
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36"
];
const authenticateApiKeyPremium = async (req, res, next) => {
const apiKey = req.headers['x-api-key'];
const ua = req.headers['user-agent'];
const isAllowed = ALLOWED_UA_REGEX.test(ua || "") ||
EXTRA_ALLOWED_UA.some(allowed => ua?.startsWith(allowed));
if (!isAllowed) {
return res.status(403).json({
status: "error",
message: "Access blocked: User-Agent not allowed",
});
}
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();
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 dbClient = new Database("AkenoXJs");
const db = dbClient.collection("api_keys_dev");
if (!apiKey) {
return res.status(401).json({ error: 'API Key or bypass token required' });
}
try {
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");
const ua = req.headers['user-agent'];
const isAllowed = ALLOWED_UA_REGEX.test(ua || "") ||
EXTRA_ALLOWED_UA.some(allowed => ua?.startsWith(allowed));
if (!isAllowed) {
return res.status(403).json({
status: "error",
message: "Access blocked: User-Agent not allowed",
});
}
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
}; |