add new module of queries limitation control
This commit is contained in:
parent
2e4aa8b5bd
commit
5d32580580
109
modules/antiddos.js
Normal file
109
modules/antiddos.js
Normal file
@ -0,0 +1,109 @@
|
||||
const { NetHelperModule } = global.moduleApi;
|
||||
const express = require("express");
|
||||
const captcha = require("draw-captcha");
|
||||
|
||||
const HTTPServer = require("../components/_http");
|
||||
|
||||
const captchaPage = `<!DOCTYPE html><html><head><title>Captcha handling required</title><meta name="viewport" content="width=device-width, initial-scale=1"><meta charset="utf-8"></head><body>
|
||||
<center>
|
||||
<h1>Enter captcha</h1>
|
||||
<p><img src=:captchaImg:></img></p>
|
||||
<form action="/captcha-solve/:sid:/:from:" method="get">
|
||||
<p><input type="label" name="solve"> <input type="submit" id="solve-captcha"></p>
|
||||
</form>
|
||||
</center>
|
||||
</body></html>`;
|
||||
|
||||
function randint (min, max) {
|
||||
return Math.floor(Math.random() * (max - min + 1) + min);
|
||||
}
|
||||
|
||||
async function getCaptchaPage (fromUrl) {
|
||||
const sidDict = "1234567890abcdef";
|
||||
let sid = "";
|
||||
for (let i = 0; i < 32; i++) {
|
||||
sid += sidDict[randint(0, 15)];
|
||||
}
|
||||
const captchaObject = new captcha.MasterCaptcha();
|
||||
getCaptchaPage.sids[sid] = await captchaObject.setupRandomCaptcha();
|
||||
return captchaPage
|
||||
.replace(new RegExp(":captchaImg:"), `/captcha/${sid}`)
|
||||
.replace(new RegExp(":from:"), Buffer.from(fromUrl).toString("hex"))
|
||||
.replace(new RegExp(":sid:"), sid);
|
||||
}
|
||||
getCaptchaPage.sids = new Object();
|
||||
|
||||
module.exports = class ExampleMdoule extends NetHelperModule {
|
||||
constructor () {
|
||||
super();
|
||||
this.router = express.Router();
|
||||
|
||||
this.lastUptime = new Date(new Date().getTime() + 3600000);
|
||||
this.queryCount = 0;
|
||||
this.ipWhiteListed = new Object();
|
||||
|
||||
this.querylimit = new this.statics.Operator("querylimit", (argv) => {
|
||||
if (argv.length !== 1) return false;
|
||||
return !Number.isNaN(+argv[0]);
|
||||
}, (argv, self, syntaxTree) => {
|
||||
if (!(syntaxTree.Type.prototype instanceof HTTPServer)) {
|
||||
throw new SyntaxError("Unsupported type of server");
|
||||
}
|
||||
let [ queriesLimit ] = argv;
|
||||
queriesLimit = +queriesLimit;
|
||||
|
||||
const router = this.router;
|
||||
|
||||
router.use(async (req, res, next) => {
|
||||
req.adsEx = req.adsEx ?? {};
|
||||
if (this.lastUptime <= new Date()) {
|
||||
this.lastUptime = new Date(this.lastUptime.getTime() + 3600000);
|
||||
this.queryCount = 1;
|
||||
this.ipWhiteListed = new Object();
|
||||
} else
|
||||
this.queryCount++;
|
||||
if (this.queryCount > queriesLimit) {
|
||||
//this.lastUptime = new Date(new Date().getTime() + 3600000);
|
||||
req.adsEx.needsCaptcha = this.ipWhiteListed[req.realip] !== true;
|
||||
}
|
||||
return next();
|
||||
});
|
||||
|
||||
router.get("/captcha/:sid", async (req, res, next) => {
|
||||
if (!req.adsEx.needsCaptcha)
|
||||
return next();
|
||||
const sid = req.params.sid;
|
||||
const content = getCaptchaPage.sids[sid];
|
||||
if (content === undefined) {
|
||||
res.set("Content-Type", "text/plain");
|
||||
return res.status(400).send("Invalid SID. Captcha was solved or not found");
|
||||
}
|
||||
res.set("Content-Type", "image/jpeg");
|
||||
res.send(content.buffer);
|
||||
});
|
||||
|
||||
router.get("/captcha-solve/:sid/:redirectTo", async (req, res) => {
|
||||
const sid = req.params.sid;
|
||||
const content = getCaptchaPage.sids[sid];
|
||||
const redirectTo = Buffer.from(req.params.redirectTo, "hex").toString("utf8");
|
||||
const isSolved = req.query.solve?.toLowerCase() === content?.code;
|
||||
this.ipWhiteListed[req.realip] = isSolved;
|
||||
req.adsEx.needsCaptcha = !isSolved;
|
||||
res.redirect(redirectTo);
|
||||
});
|
||||
|
||||
router.use(async (req, res, next) => {
|
||||
if (!req.adsEx.needsCaptcha)
|
||||
return next();
|
||||
res.send(await getCaptchaPage(req.originalUrl));
|
||||
});
|
||||
});
|
||||
|
||||
this.operators.push(this.querylimit);
|
||||
}
|
||||
|
||||
bind (type) {
|
||||
super.bind(type);
|
||||
this.serverType.routelist.push(this.router);
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue
Block a user