const { NetHelperModule } = global.moduleApi; const express = require("express"); const captcha = require("draw-captcha"); const HTTPServer = require("../components/_http"); const captchaPage = `Captcha handling required

Enter captcha

`; 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); } };