@ -1,4 +1,7 @@
const got = require ( "got" ) ;
const pw = require ( "playwright-extra" ) ;
const stl = require ( "puppeteer-extra-plugin-stealth" ) ;
const { PlaywrightBlocker } = require ( "@cliqz/adblocker-playwright" ) ;
const fetch = require ( "cross-fetch" ) ;
const lib = require ( "../lib" ) ;
module . exports = {
@ -17,121 +20,29 @@ module.exports = {
requiresCaptcha : true ,
get : async function ( url , opt ) {
try {
let header = ( lib . config . defaults ? . got ? . headers || lib . config . defaults ? . axios ? . headers || { } ) ;
if ( lib . config . debug == true ) console . log ( "[linkvertise] Launching browser..." ) ;
let blocker = await PlaywrightBlocker . fromPrebuiltFull ( fetch ) ;
let stlh = stl ( ) ;
stlh . enabledEvasions . delete ( "user-agent-override" ) ;
pw . firefox . use ( stlh ) ;
let proxy ;
if ( lib . config . defaults ? . got ? . proxy ) {
if ( lib . config . defaults ? . got ? . proxy ? . type == "socks5" ) {
const agent = require ( "socks-proxy-agent" ) ;
try {
if ( ( new URL ( prox ) . hostname == "localhost" || new URL ( prox ) . hostname == "127.0.0.1" ) && new URL ( proxy ) . port == "9050" ) {
proxy = { } ;
} else {
proxy = { httpsAgent : ( new agent . SocksProxyAgent ( prox ) ) } ;
}
} catch ( err ) {
proxy = { } ;
}
} else {
proxy = { } ;
}
if ( lib . config . captcha . active == false ) {
throw "Captcha service is required for this link, but this instance doesn't support it."
}
let id ;
if ( new URL ( url ) . hostname == "linkvertise.download" ) {
id = new URL ( url ) . pathname . split ( "/" ) . slice ( 2 , 4 ) . join ( "/" ) ;
} else {
id = new URL ( url ) . pathname . split ( "/" ) . slice ( 1 , 3 ) . join ( "/" ) ;
}
if ( lib . config . debug == true ) console . log ( "[linkvertise] Got ID from URL:" , id ) ;
header [ "User-Agent" ] = "Mozilla/5.0 (iPhone; CPU iPhone OS 13_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1 Mobile/15E148 Safari/604.1" ;
header . Accept = "application/json" ;
header [ "Accept-Encoding" ] = "gzip, deflate" ;
header [ "Accept-Language" ] = "en-US,en;q=0.5" ;
header . Connection = "keep-alive" ;
header . Origin = "https://linkvertise.com" ;
header . Referer = "https://linkvertise.com/" ;
header [ "Sec-Fetch-Dest" ] = "empty" ;
header [ "Sec-Fetch-Mode" ] = "cors" ;
header [ "Sec-Fetch-Site" ] = "same-site" ;
header [ "TE" ] = "trailers" ;
if ( lib . config . debug == true ) console . log ( "[linkvertise] Getting user token..." ) ;
let resp = await got ( {
method : "GET" ,
headers : header ,
url : ` https://publisher.linkvertise.com/api/v1/redirect/link/static/ ${ id } ?origin=&resolution=1920x960 `
} ) ;
resp . body = JSON . parse ( resp . body ) ;
let type ;
if ( resp . body ? . data . link . target _type == "URL" ) {
type = "target" ;
} else if ( resp . body ? . data . link . target _type == "PASTE" ) {
type = "paste" ;
} else {
throw "Unknown target type." ;
}
let rp = resp . body ? . data . link . id ;
let ut = resp . body ? . user _token ;
if ( lib . config . debug == true ) console . log ( "[linkvertise] Got user token:" , ut ) ;
let ck ;
if ( lib . config . debug == true ) console . log ( "[linkvertise] Doing CAPTCHA to validate traffic..." ) ;
header [ "Content-Type" ] = "application/json" ;
if ( new URL ( url ) . hostname !== "linkvertise.com" ) url = ` https://linkvertise.com/ ${ url . split ( "/" ) . slice ( 3 ) . join ( "/" ) } ` ;
let tk = await lib . solve ( "6LcEr_UUAAAAAHXt5wx-k9P_m8Z1JY-Ck9Mxrhxo" , "recaptcha" , { referer : url } ) ;
let d = JSON . stringify ( {
token : tk ,
type : "rc"
} ) ;
header [ "Content-Length" ] = lib . byteCount ( d ) ;
if ( lib . config . debug == true ) console . log ( "[linkvertise] Sending CAPTCHA result to get CAPTCHA token..." ) ;
resp = await got ( {
body : d ,
method : "POST" ,
headers : header ,
url : ` https://publisher.linkvertise.com/api/v1/redirect/link/ ${ id } /traffic-validation?X-Linkvertise-UT= ${ ut } `
} ) ;
let args = ( lib . config . defaults ? . puppeteer || { headless : true } ) ;
b = await pw . firefox . launch ( args ) ;
let p = await b . newPage ( ) ;
await blocker . enableBlockingInPage ( p ) ;
await p . goto ( url ) ;
await p . waitForSelector ( "#ngrecaptcha-0" ) ;
if ( lib . config . debug == true ) console . log ( ` [linkvertise] Completing CAPTCHA... ` ) ;
resp . body = JSON . parse ( resp . body ) ;
ck = resp . body ? . data . tokens . TARGET ;
if ( lib . config . debug == true ) console . log ( "[linkvertise] Got CAPTCHA token: " , ck ) ;
let fb = { } ;
fb . serial = Buffer . from ( JSON . stringify ( {
timestamp : new Date ( ) * 1 ,
random : "6548307" ,
link _id : rp
} ) ) . toString ( "base64" ) ;
if ( ck !== undefined ) fb . token = ck ;
fb = JSON . stringify ( fb ) ;
header [ "Content-Type" ] = "application/json" ;
header [ "Content-Length" ] = lib . byteCount ( fb ) ;
if ( lib . config . debug == true ) console . log ( "[linkvertise] Sending final request..." ) ;
resp = await got ( {
body : fb ,
method : "POST" ,
headers : header ,
url : ` https://publisher.linkvertise.com/api/v1/redirect/link/ ${ id } / ${ type } ?X-Linkvertise-UT= ${ ut } `
} ) ;
resp . body = JSON . parse ( resp . body ) ;
return ( resp . body ? . data . paste || resp . body ? . data . target ) ;
await lib . solveThroughPage ( p ) ;
console . log ( "[linkvertise] Solved" )
} catch ( err ) {
throw err ;
}