pull/4/head
aria 3 months ago
parent 38dc0ec2bd
commit 7c5fe03059
  1. 2
      .gitignore
  2. 2
      README.md
  3. 10
      config.example.json
  4. 19
      extractor.js
  5. 4
      extractors/generic.js
  6. 68
      extractors/ouo.js
  7. 58
      lib.js
  8. 14
      main.js
  9. 2588
      package-lock.json
  10. 28
      package.json

2
.gitignore vendored

@ -130,3 +130,5 @@ dist
.yarn/install-state.gz
.pnp.*
# Config / private
config.json

@ -1,3 +1,3 @@
# bifm-v2
# bifm
Bypasses link protectors server-side.

@ -0,0 +1,10 @@
{
"captcha": {
"active": false,
"service": "2captcha",
"key": ""
},
"db": {
"url": "mongodb://127.0.0.1:27017/bifm"
}
}

@ -0,0 +1,19 @@
const fs = require("fs/promises");
module.exports = {
fromUrl: async function(url) {
let h = new URL(url).hostname;
let d = await fs.readdir(`${__dirname}/extractors`);
for (let i = 0; i < d.length; i++) {
if ((await require(`./extractors/${d[i]}`)).hostnames.includes(h)) return d[i];
}
return "generic";
},
all: async function() {
let dir = await fs.readdir(`./extractors`);
for (let i = 0; i < dir.length; i++) {
dir[i] = await import(`./extractors/${dir[i]}`);
}
return dir;
}
}

@ -0,0 +1,4 @@
module.exports = {
hostnames: [],
get: async function() {}
}

@ -0,0 +1,68 @@
const axios = require("axios");
const cheerio = require("cheerio");
const scp = require("set-cookie-parser");
const lib = require("../lib");
module.exports = {
hostnames: ["ouo.press", "ouo.io"],
get: async function(url) {
let u = new URL(url);
if (u.searchParams.get("s")) return decodeURIComponent(u.searchParams.get("s"));
let r = await axios({
method: "GET",
url: url,
headers: {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate",
"DNT": "1",
"Connection": "keep-alive",
"Upgrade-Insecure-Requests": "1"
}
});
let $ = cheerio.load(r.data);
let c = lib.cookieString(scp(r.headers["set-cookie"]));
console.log(c);
let sk;
for (let d in $("head script")) {
if ($("head script")[d].attribs && $("head script")[d].attribs.src && $("head script")[d].attribs.src.includes("?render")) {
sk = new URL($("head script")[d].attribs.src).searchParams.get("render")
} else {
continue;
}
}
if (sk == null) throw "No sitekey for Captcha found";
let cap = await lib.solve(sk, "recaptcha", {referer: url});
let b = `_token=${encodeURIComponent($("#form-captcha [name=_token]").val())}&x-token=${cap}&v-token=${$("#v-token").val()}`;
console.log(b);
console.log($("#form-captcha").attr("action"))
r = await axios({
method: "POST",
body: b,
url: $("#form-captcha").attr("action"),
headers: {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate",
"Cache-Control": "no-cache",
"Referer": url,
"Content-Type": "application/x-www-form-urlencoded",
"Content-Length": lib.byteCount(b),
"Origin": u.hostname,
"DNT": "1",
"Connection": "keep-alive",
"Cookie": c,
"Upgrade-Insecure-Requests": "1",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "same-origin",
"Sec-GPC": "1",
"TE": "Trailers"
}
});
console.log(r.data);
}
}

@ -0,0 +1,58 @@
const ext = require("./extractor");
const config = require("./config.json");
const two = require("2captcha");
const {MongoClient} = require("mongodb");
const client = new MongoClient(config["db"]["url"]);
(async function() {
await client.connect();
})();
const db = client.db("bifm");
const links = db.collection("links");
module.exports = {
get: async function(url, opt) {
let ex = await ext.fromUrl(url);
let extractor = require(`${__dirname}/extractors/${ex}`);
console.log(url, opt)
if (opt.ignoreCache !== true) {
let f = await links.findOne({url: url});
if (f !== null) {
f._id = undefined;
return f;
}
}
f = await extractor.get(url, opt);
if (opt.allowCache == true) {
await links.insertOne(f);
}
return f;
},
solve: async function(sitekey, type, opt) {
if (config["captcha"]["enabled"] == false) return null;
const tc = new two.Solver(config["captcha"]["key"]);
let ref = opt.referer;
switch(type) {
case "recaptcha":
return (await tc.recaptcha(sitekey, ref)).data;
case "hcaptcha":
return (await tc.hcaptcha(sitekey, ref)).data;
default:
return null;
}
},
cookieString: function(co) {
let s = ``;
for (let c in co) {
if (co[c].value == "deleted") continue;
s = `${s} ${co[c].name}=${encodeURIComponent(co[c].value)};`;
}
s = s.substring(0, s.length - 1);
return s.substring(1);
},
byteCount: function(string) {return encodeURI(string).split(/%..|./).length - 1;}
}

@ -0,0 +1,14 @@
const lib = require("./lib");
(async function() {
try {
let l = await lib.get("https://ouo.io/2dktqo", {
ignoreCache: false,
allowCache: false
});
console.log(l);
} catch(e) {
console.log(e.message);
}
})();

2588
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -0,0 +1,28 @@
{
"name": "bifm-v2",
"version": "1.0.0",
"description": "Bypasses link protectors server-side.",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git@git.gay:a/bifm-v2.git"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"2captcha": "^3.0.3",
"axios": "^0.26.1",
"cheerio": "^1.0.0-rc.10",
"mongodb": "^4.5.0",
"puppeteer": "^13.5.2",
"puppeteer-extra": "^3.2.3",
"puppeteer-extra-plugin-adblocker": "^2.12.0",
"puppeteer-extra-plugin-recaptcha": "^3.5.0",
"puppeteer-extra-plugin-stealth": "^2.9.0",
"set-cookie-parser": "^2.4.8"
}
}
Loading…
Cancel
Save