diff --git a/src/js/auto.js b/src/js/auto.js index 48bbed7..6f41d04 100644 --- a/src/js/auto.js +++ b/src/js/auto.js @@ -67,7 +67,7 @@ if (!window._basedflareAuto) { redirect: "manual", }).then((res) => { if (res.status >= 400 && res.status < 500) { - clearCookiesForDomain(location.hostname); + clearCookiesForDomains(location.hostname); console.error("Server rejected your submission."); } else if (res.status >= 500) { console.error("Server encountered an error."); @@ -76,6 +76,7 @@ if (!window._basedflareAuto) { }).catch((e) => { console.error(e); }).finally(() => { + clearCookiesForDomains(location.hostname); localStorage.removeItem('_basedflare-auto'); }); }; diff --git a/src/js/auto.min.js b/src/js/auto.min.js index a8bde9d..61463bf 100644 --- a/src/js/auto.min.js +++ b/src/js/auto.min.js @@ -1,153 +1 @@ -if (!window._basedflareAuto) { - class BasedFlareAuto { - constructor(cookieMinLife = 600, maxFails = 3) { - this.finished = false; - this.workers = []; - this.fails = 0; - this.cookieMinLife = cookieMinLife; - this.maxFails = maxFails; - this.timeout = null; - this.scriptSrc = "/.basedflare/js/argon2.min.js"; - this.checkCookie(); - } - checkCookie = () => { - console.log("checkCookie"); - const powCookie = document.cookie.split("; ").find((row) => - row.startsWith("_basedflare_pow=") - ); - if (powCookie) { - const powCookieValue = powCookie.split("=")[1]; - const expiry = powCookieValue.split("#")[2]; - const remainingSecs = ((expiry * 1000) - Date.now()) / 1000; - console.log("Basedflare cookie valid for", remainingSecs, "seconds"); - if (remainingSecs <= this.cookieMinLife) return this.doBotCheck(); - this.timeout = setTimeout( - this.checkCookie, - Math.max( - 5000, - Math.floor( - (remainingSecs - this.cookieMinLife + (Math.random() * 300)) * - 1000, - ), - ), - ); - } - }; - includeScript = (scriptSrc) => { - console.log("includeScript"); - return new Promise((res) => { - const script = document.createElement("script"); - script.onload = () => res(); - script.src = scriptSrc; - document.head.appendChild(script); - }); - }; - clearCookiesForDomains = (domain) => { - const parts = domain.split("."); - for (let i = 0; i < parts.length - 1; i += 1) { - const subdomain = parts.slice(i).join("."); - document.cookie = - `_basedflare_pow=; Max-Age=-9999999; Path=/; Domain=.${subdomain}`; - document.cookie = - `_basedflare_captcha=; Max-Age=-9999999; Path=/; Domain=.${subdomain}`; - } - }; - messageHandler = (e, json) => { - console.log("messageHandler"); - if (e.data.length === 1) return; - if (this.finished) return; - this.workers.forEach((w) => w.terminate()); - this.finished = true; - const [_workerId, answer] = e.data; - fetch("/.basedflare/bot-check", { - method: "POST", - headers: { "Content-Type": "application/x-www-form-urlencoded" }, - body: new URLSearchParams({ "pow_response": `${json.ch}#${answer}` }), - redirect: "manual", - }).then((res) => { - if (res.status >= 400 && res.status < 500) { - clearCookiesForDomain(location.hostname); - console.error("Server rejected your submission."); - } else if (res.status >= 500) { - console.error("Server encountered an error."); - } - this.fails += 1; - }).catch((e) => { - console.error(e); - }).finally(() => { - localStorage.removeItem("_basedflare-auto"); - }); - }; - checkRunning = () => { - console.log("checkRunning"); - const lastCheckTime = localStorage.getItem("_basedflare-auto"); - if (lastCheckTime) { - const lastCheckInt = parseInt(lastCheckTime); - if (Date.now() - lastCheckInt < 120) { - console.log("Already running recently"); - return true; - } - } - }; - doProofOfWork = async (json) => { - console.log("doProofOfWork"); - this.workers = []; - this.finished = false; - const [userkey, challenge, _expiry, _signature] = json.ch.split("#"); - const [mode, diff, argon_time, argon_kb] = json.pow.split("#"); - if (mode === "argon2") { - if (!window.argon2) await this.includeScript(this.scriptSrc); - } - const diffString = "0".repeat(diff); - const cpuThreads = window.navigator.hardwareConcurrency; - const isTor = location.hostname.endsWith(".onion"); - const workerThreads = (isTor || cpuThreads === 2) - ? cpuThreads - : Math.max(Math.ceil(cpuThreads / 2), cpuThreads - 1); - for (let i = 0; i < workerThreads; i += 1) { - const powWorker = new Worker("/.basedflare/js/worker.min.js"); - powWorker.onmessage = (e) => this.messageHandler(e, json); - this.workers.push(powWorker); - powWorker.postMessage([ - userkey, - challenge, - diff, - diffString, - { - time: argon_time, - mem: argon_kb, - hashLen: 32, - parallelism: 1, - type: window.argon2 ? window.argon2.ArgonType.Argon2id : null, - mode: mode, - }, - i, - workerThreads, - ]); - } - }; - doBotCheck = async () => { - console.log("doBotCheck"); - if (this.checkRunning()) return; - localStorage.setItem("_basedflare-auto", Date.now()); - try { - const json = await fetch("/.basedflare/bot-check", { - headers: { "accept": "application/json" }, - }).then((res) => res.json()); - if (!json || !json.ch) return; - console.log("Basedflare challenge successfully fetched", json); - if (json.ca) console.warn("Basedflare auto captcha not yet supported"); - else await this.doProofOfWork(json); - } catch (e) { - console.error(e); - this.fails += 1; - } finally { - if (this.fails < this.maxFails) { - this.timeout = setTimeout(this.checkCookie, 30000); - } - } - }; - } - window._basedflareAuto = new BasedFlareAuto(); -} - +if(!window._basedflareAuto){class BasedFlareAuto{constructor(cookieMinLife=600,maxFails=3){this.finished=false;this.workers=[];this.fails=0;this.cookieMinLife=cookieMinLife;this.maxFails=maxFails;this.timeout=null;this.scriptSrc="/.basedflare/js/argon2.min.js";this.checkCookie()}checkCookie=()=>{console.log('checkCookie');const powCookie=document.cookie.split("; ").find((row)=>row.startsWith("_basedflare_pow="));if(powCookie){const powCookieValue=powCookie.split("=")[1];const expiry=powCookieValue.split("#")[2];const remainingSecs=((expiry*1000)-Date.now())/1000;console.log('Basedflare cookie valid for',remainingSecs,'seconds');if(remainingSecs<=this.cookieMinLife){return this.doBotCheck()}this.timeout=setTimeout(this.checkCookie,Math.max(5000,Math.floor(((remainingSecs-this.cookieMinLife+(Math.random()*300))*1000))))}};includeScript=(scriptSrc)=>{console.log('includeScript');return new Promise((res)=>{const script=document.createElement("script");script.onload=()=>res();script.src=scriptSrc;document.head.appendChild(script)})};clearCookiesForDomains=(domain)=>{const parts=domain.split('.');for(let i=0;i{console.log('messageHandler');if(e.data.length===1){return}if(this.finished){return}this.workers.forEach((w)=>w.terminate());this.finished=true;const[_workerId,answer]=e.data;fetch("/.basedflare/bot-check",{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({"pow_response":`${json.ch }#${ answer }`}),redirect:"manual"}).then((res)=>{if(res.status>=400&&res.status<500){clearCookiesForDomains(location.hostname);console.error("Server rejected your submission.")}else if(res.status>=500){console.error("Server encountered an error.")}this.fails+=1}).catch((e)=>{console.error(e)}).finally(()=>{clearCookiesForDomains(location.hostname);localStorage.removeItem('_basedflare-auto')})};checkRunning=()=>{console.log('checkRunning');const lastCheckTime=localStorage.getItem('_basedflare-auto');if(lastCheckTime){const lastCheckInt=parseInt(lastCheckTime);if(Date.now()-lastCheckInt<120){console.log('Already running recently');return true}}};doProofOfWork=async(json)=>{console.log('doProofOfWork');this.workers=[];this.finished=false;const[userkey,challenge,_expiry,_signature]=json.ch.split("#");const[mode,diff,argon_time,argon_kb]=json.pow.split("#");if(mode==="argon2"){if(!window.argon2){await this.includeScript(this.scriptSrc)}}const diffString="0".repeat(diff);const cpuThreads=window.navigator.hardwareConcurrency;const isTor=location.hostname.endsWith(".onion");const workerThreads=(isTor||cpuThreads===2)?cpuThreads:Math.max(Math.ceil(cpuThreads/2),cpuThreads-1);for(let i=0;ithis.messageHandler(e,json);this.workers.push(powWorker);powWorker.postMessage([userkey,challenge,diff,diffString,{time:argon_time,mem:argon_kb,hashLen:32,parallelism:1,type:window.argon2?window.argon2.ArgonType.Argon2id:null,mode:mode},i,workerThreads])}};doBotCheck=async()=>{console.log('doBotCheck');if(this.checkRunning()){return}localStorage.setItem('_basedflare-auto',Date.now());try{const json=await fetch("/.basedflare/bot-check",{headers:{"accept":"application/json"}}).then(res=>res.json());if(!json||!json.ch){return}console.log('Basedflare challenge successfully fetched',json);if(json.ca){console.warn('Basedflare auto captcha not yet supported')}else{await this.doProofOfWork(json)}}catch(e){console.error(e);this.fails+=1}finally{if(this.fails { const s = res.status; if (s >= 400 && s < 500) { - clearCookiesForDomain(location.hostname); + clearCookiesForDomains(location.hostname); return insertError(__("Server rejected your submission.")); } else if (s >= 500) { return insertError(__("Server encountered an error.")); @@ -111,7 +111,7 @@ function postResponse(powResponse, captchaResponse) { window.localStorage.setItem("_basedflare-redirect", Math.random()); finishRedirect(); }).catch(() => { - clearCookiesForDomain(location.hostname); + clearCookiesForDomains(location.hostname); insertError(__("Failed to send request to server.")); }); } diff --git a/src/js/challenge.min.js b/src/js/challenge.min.js index 4b82a01..c088f90 100644 --- a/src/js/challenge.min.js +++ b/src/js/challenge.min.js @@ -1 +1 @@ -let TRANSLATIONS;function __(key,replacement=null){const translation=TRANSLATIONS[key]||key;return replacement!==null?translation.replace('%s',replacement):translation}function updateElem(selector,text,color){const updateElem=document.querySelector(selector);if(updateElem){updateElem.innerText=text;if(color){updateElem.style.color=color}}}function insertError(str){const loader=document.querySelector("#loader");const captcha=document.querySelector("#captcha");(captcha||loader).insertAdjacentHTML("afterend",`

Error: ${ str }

`,);loader&&loader.remove();captcha&&captcha.remove();updateElem(".powstatus","")}function finishRedirect(){window.location=location.search.slice(1)+location.hash||"/"}function makeLoaderGreen(){const dots=document.querySelectorAll(".b");if(dots&&dots.length>0){dots.forEach((dot)=>dot.classList.add("green"))}}const wasmSupported=(()=>{try{if(typeof WebAssembly==="object"&&typeof WebAssembly.instantiate==="function"){const module=new WebAssembly.Module(Uint8Array.of(0x0,0x61,0x73,0x6d,0x01,0x00,0x00,0x00),);if(module instanceof WebAssembly.Module){return new WebAssembly.Instance(module)instanceof WebAssembly.Instance}}}catch(e){console.error(e)}return false})();function clearCookiesForDomains(domain){const parts=domain.split('.');for(let i=0;i{const s=res.status;if(s>=400&&s<500){clearCookiesForDomain(location.hostname);return insertError(__("Server rejected your submission."))}else if(s>=500){return insertError(__("Server encountered an error."))}window.localStorage.setItem("_basedflare-redirect",Math.random());finishRedirect()}).catch(()=>{clearCookiesForDomain(location.hostname);insertError(__("Failed to send request to server."))})}const powFinished=new Promise((resolve)=>{let start=Date.now();const workers=[];let finished=false;const stopPow=()=>{finished=true;const hasCaptcha=document.getElementById("captcha");if(hasCaptcha){updateElem(".powstatus",__("Waiting for captcha."),"#31cc31")}else{updateElem(".powstatus",__("Submitting..."),"#31cc31");makeLoaderGreen()}workers.forEach((w)=>w.terminate())};const submitPow=(answer)=>{window.localStorage.setItem("_basedflare-pow-response",answer);stopPow();const dummyTime=3500-(Date.now()-start);window.setTimeout(()=>{resolve({answer})},dummyTime)};window.addEventListener("DOMContentLoaded",async()=>{TRANSLATIONS=JSON.parse(document.head.dataset.langjson);const{time,kb,pow,diff,mode}=document.querySelector("[data-pow]").dataset;window.addEventListener("storage",(event)=>{if(event.key==="_basedflare-pow-response"&&!finished){console.log("Got answer",event.newValue,"from storage event");stopPow();resolve({answer:event.newValue,localStorage:true})}else if(event.key==="_basedflare-redirect"){console.log("Redirecting, solved in another tab");finishRedirect()}});if(mode==="argon2"&&!wasmSupported){return insertError(__("Browser does not support WebAssembly."))}const powOpts={time:time,mem:kb,hashLen:32,parallelism:1,type:argon2?argon2.ArgonType.Argon2id:null,mode:mode};console.log("Got pow",pow,"with difficulty",diff);const eHashes=Math.pow(16,Math.floor(diff/8))*(((diff%8)*2)||1);const diffString="0".repeat(Math.floor(diff/8));const[userkey,challenge]=pow.split("#");if(window.Worker){const cpuThreads=window.navigator.hardwareConcurrency;const isTor=location.hostname.endsWith(".onion");const workerThreads=(isTor||cpuThreads===2)?cpuThreads:Math.max(Math.ceil(cpuThreads/2),cpuThreads-1);const messageHandler=(e)=>{if(e.data.length===1){const totalHashes=e.data[0];const elapsedSec=Math.floor((Date.now()-start)/1000);const hps=Math.floor(totalHashes/elapsedSec);const requiredSec=Math.floor(eHashes/hps)*1.5;const remainingSec=Math.max(0,Math.floor(requiredSec-elapsedSec),);console.log(`${ hps }H/s, ≈${ remainingSec }s remaining`);return updateElem(".powstatus",__('Working, ≈%ss remaining',remainingSec),)}if(finished){return}const[workerId,answer]=e.data;console.log("Worker",workerId,"returned answer",answer,"in",Date.now()-start+"ms",);submitPow(`${ pow }#${ answer }`)};for(let i=0;isetTimeout(res,10));workers[i].postMessage([userkey,challenge,diff,diffString,powOpts,i,workerThreads])}}else{return insertError(__("Browser does not support Web Workers."))}})}).then((powResponse)=>{const hasCaptchaForm=document.getElementById("captcha");if(!hasCaptchaForm&&!powResponse.localStorage){postResponse(powResponse.answer)}return powResponse.answer}).catch((e)=>{console.error(e)});function onCaptchaSubmit(captchaResponse){const captchaElem=document.querySelector("[data-sitekey]");captchaElem.insertAdjacentHTML("afterend",`
`,);captchaElem.remove();powFinished.then((powResponse)=>{updateElem(".powstatus",__("Submitting..."),"#31cc31");makeLoaderGreen();postResponse(powResponse,captchaResponse)})} +let TRANSLATIONS;function __(key,replacement=null){const translation=TRANSLATIONS[key]||key;return replacement!==null?translation.replace('%s',replacement):translation}function updateElem(selector,text,color){const updateElem=document.querySelector(selector);if(updateElem){updateElem.innerText=text;if(color){updateElem.style.color=color}}}function insertError(str){const loader=document.querySelector("#loader");const captcha=document.querySelector("#captcha");(captcha||loader).insertAdjacentHTML("afterend",`

Error: ${ str }

`,);loader&&loader.remove();captcha&&captcha.remove();updateElem(".powstatus","")}function finishRedirect(){window.location=location.search.slice(1)+location.hash||"/"}function makeLoaderGreen(){const dots=document.querySelectorAll(".b");if(dots&&dots.length>0){dots.forEach((dot)=>dot.classList.add("green"))}}const wasmSupported=(()=>{try{if(typeof WebAssembly==="object"&&typeof WebAssembly.instantiate==="function"){const module=new WebAssembly.Module(Uint8Array.of(0x0,0x61,0x73,0x6d,0x01,0x00,0x00,0x00),);if(module instanceof WebAssembly.Module){return new WebAssembly.Instance(module)instanceof WebAssembly.Instance}}}catch(e){console.error(e)}return false})();function clearCookiesForDomains(domain){const parts=domain.split('.');for(let i=0;i{const s=res.status;if(s>=400&&s<500){clearCookiesForDomains(location.hostname);return insertError(__("Server rejected your submission."))}else if(s>=500){return insertError(__("Server encountered an error."))}window.localStorage.setItem("_basedflare-redirect",Math.random());finishRedirect()}).catch(()=>{clearCookiesForDomains(location.hostname);insertError(__("Failed to send request to server."))})}const powFinished=new Promise((resolve)=>{let start=Date.now();const workers=[];let finished=false;const stopPow=()=>{finished=true;const hasCaptcha=document.getElementById("captcha");if(hasCaptcha){updateElem(".powstatus",__("Waiting for captcha."),"#31cc31")}else{updateElem(".powstatus",__("Submitting..."),"#31cc31");makeLoaderGreen()}workers.forEach((w)=>w.terminate())};const submitPow=(answer)=>{window.localStorage.setItem("_basedflare-pow-response",answer);stopPow();const dummyTime=3500-(Date.now()-start);window.setTimeout(()=>{resolve({answer})},dummyTime)};window.addEventListener("DOMContentLoaded",async()=>{TRANSLATIONS=JSON.parse(document.head.dataset.langjson);const{time,kb,pow,diff,mode}=document.querySelector("[data-pow]").dataset;window.addEventListener("storage",(event)=>{if(event.key==="_basedflare-pow-response"&&!finished){console.log("Got answer",event.newValue,"from storage event");stopPow();resolve({answer:event.newValue,localStorage:true})}else if(event.key==="_basedflare-redirect"){console.log("Redirecting, solved in another tab");finishRedirect()}});if(mode==="argon2"&&!wasmSupported){return insertError(__("Browser does not support WebAssembly."))}const powOpts={time:time,mem:kb,hashLen:32,parallelism:1,type:argon2?argon2.ArgonType.Argon2id:null,mode:mode};console.log("Got pow",pow,"with difficulty",diff);const eHashes=Math.pow(16,Math.floor(diff/8))*(((diff%8)*2)||1);const diffString="0".repeat(Math.floor(diff/8));const[userkey,challenge]=pow.split("#");if(window.Worker){const cpuThreads=window.navigator.hardwareConcurrency;const isTor=location.hostname.endsWith(".onion");const workerThreads=(isTor||cpuThreads===2)?cpuThreads:Math.max(Math.ceil(cpuThreads/2),cpuThreads-1);const messageHandler=(e)=>{if(e.data.length===1){const totalHashes=e.data[0];const elapsedSec=Math.floor((Date.now()-start)/1000);const hps=Math.floor(totalHashes/elapsedSec);const requiredSec=Math.floor(eHashes/hps)*1.5;const remainingSec=Math.max(0,Math.floor(requiredSec-elapsedSec),);console.log(`${ hps }H/s, ≈${ remainingSec }s remaining`);return updateElem(".powstatus",__('Working, ≈%ss remaining',remainingSec),)}if(finished){return}const[workerId,answer]=e.data;console.log("Worker",workerId,"returned answer",answer,"in",Date.now()-start+"ms",);submitPow(`${ pow }#${ answer }`)};for(let i=0;isetTimeout(res,10));workers[i].postMessage([userkey,challenge,diff,diffString,powOpts,i,workerThreads])}}else{return insertError(__("Browser does not support Web Workers."))}})}).then((powResponse)=>{const hasCaptchaForm=document.getElementById("captcha");if(!hasCaptchaForm&&!powResponse.localStorage){postResponse(powResponse.answer)}return powResponse.answer}).catch((e)=>{console.error(e)});function onCaptchaSubmit(captchaResponse){const captchaElem=document.querySelector("[data-sitekey]");captchaElem.insertAdjacentHTML("afterend",`
`,);captchaElem.remove();powFinished.then((powResponse)=>{updateElem(".powstatus",__("Submitting..."),"#31cc31");makeLoaderGreen();postResponse(powResponse,captchaResponse)})}