import { Hono } from 'hono' import { serve } from '@hono/node-server' import { stream, streamText, streamSSE } from 'hono/streaming' import { deleteCookie, getCookie, setCookie, } from 'hono/cookie' import * as fs from 'node:fs' import * as fsPromises from 'node:fs/promises' var port = parseInt(process.argv[2]) || 15345; var prefix = process.argv[3] || "/84/_verify"; var cookie_name = process.argv[4] || "_cgwall_token"; var dirname = import.meta.dirname ?? new URL('.', import.meta.url).pathname; var auths = new Map(); var auths_dirty = false; try { for (let [k,v] of Object.entries(JSON.parse(fs.readFileSync(dirname+'/cookies.json')))) { auths.set(k, v); } auths_dirty = true; } catch {} async function saveCache() { if (!auths_dirty) return; glog("Saving cookies"); await fsPromises.writeFile(dirname+'/cookies.json', JSON.stringify(Object.fromEntries( [...auths.entries()].filter(([_,v]) => !v.prepping) ))); auths_dirty = false; } glog('sigmawall', dirname) function randstr() { return [...crypto.getRandomValues(new Uint8Array(32))].map(e=>e.toString(16).padStart(2,0)).join(''); } var app = Object.assign(new Hono(), { port }); function glog(...msg) { console.log(`[${(new Date()).toGMTString()}]`, ...msg); } function log(key, ...msg) { glog(`[${(key??'?'.repeat(64)).substr(0,8)}]`, ...msg) } app.get(`${prefix}/reset`, async (c) => { var key, auth; if ((auth = auths.get(key = getCookie(c, cookie_name)))) { auth.expire = Date.now(); keyValid(key); } return c.text("meow"); }); app.all("*", async (c, next) => { var key; keyValid(getCookie(c, cookie_name)); log(getCookie(c, cookie_name), 'Checking req', auths.get(getCookie(c, cookie_name))); if ((key = auths.get(getCookie(c, cookie_name))) && key.status) { keyValid(getCookie(c, cookie_name), 10000); c.status(421); return c.text("Success"); } log(getCookie(c, cookie_name), 'Verification required'); if (c.req.method != "GET") { log(getCookie(c, cookie_name), 'Non-GET denied'); c.status(403); return c.text("Unauthorized"); } return next(); }); var templ = str => `

anti-scraper protection

${str}`; var funcs = new Map(); app.get(`${prefix}/:key`, async (c) => { let fn = funcs.get(c.req.param('key')); if (fn) { try { await fn(c); } catch(e) { console.error(e); } c.status(200); return c.text('if you see this, Go Back'); } c.status(404); return c.text("wack"); }); function newfunc(fn) { var key = randstr(); var obj; funcs.set(key, (...args) => obj.fn(...args)); return obj = { fn, remove() { funcs.delete(key); }, key }; } function keyValid(key, extend) { var auth; if (!(auth = auths.get(key))) return false; if (Date.now() >= auth.expire) { if (!auth.prepping) { auths_dirty = true; } expsig(key); auths.delete(key); return false; } if (extend != null) { if (auth.real_expire == null && Date.now()+extend >= auth.expire) { auth.real_expire = auth.expire; auth.expire = Date.now()+extend; } } return true; } function on_expire(key) { var auth; if (!(auth = auths.get(key))) return false; auth.expsigs = auth.expsigs ?? new Set(); var fn; return Object.assign(new Promise(succ => auth.expsigs.add(fn = succ)), { remove() { auth.expsigs.delete(fn); } }); } function expsig(key) { var auth; if (!(auth = auths.get(key))) return false; for (let fn of (auth.expsigs ?? new Set())) { fn(); auth.expsigs.delete(fn); } return true; } var conns = 0; app.get("*", async (c) => { return streamText(c, async(stream) => { conns++; try { c.header('X-Accel-Buffering', 'no'); c.header('Content-Type', 'text/html; charset=utf-8'); if ((!(c.req.header('User-Agent')||''+'').match(/^Links /)) &&(!((c.req.header('Accept')||'')+'').match(/^text\/html/))) { return; } var closed = false; var banned = false; var pass; var key; var auth = auths.get(key = getCookie(c, cookie_name)); function boop() { var oauth = auths.get(key); if (oauth && !oauth.prepping) throw new Error("can't boop non-prep"); auths.set(key, auth = Object.assign(oauth ?? {}, { prepping: true, expire: Date.now() + 1000*60*5 })); } var finp, finf; function nfinp() { finp = new Promise((succ) => finf = succ); } if (auth && (!auth.prepping)) { log(key, 'Rejected due to ban'); await stream.write(templ(`

Sorry but you pressed the get banned button return in ${(auth.expire - Date.now())/1000} seconds.`)); return; } else if (!auth) { key = randstr() log(getCookie(c, cookie_name), 'Setting cookie', key); setCookie(c, cookie_name, key); c.req.raw.signal.addEventListener('abort', () => { running = false; closed = true; stream.abort(); }); boop(); (o => (o.users = 0, o.expire = Date.now() + 30*1000))(auths.get(key)); if (!closed) await stream.write(templ( ``+ `

redirecting...
` )); log(key, 'Cookie set complete'); return; } pass = -2; if ((o => o.users)(auths.get(key))) { await stream.write(templ(`

Verification ongoing in another window. Waiting...`)); return; } else { (o => o.users = (o.users ?? 0) + 1)(auths.get(key)); } boop(); nfinp(); c.req.raw.signal.addEventListener('abort', () => { log(key, 'Aborted'); closed = true; finf(); if (keyValid(key) && (o => o.prepping && !--o.users)(auths.get(key))) { log(key, 'Deleted'); auths.delete(key); } stream.abort(); }); var banner = newfunc(function() { banned = true; finf(); log(key, 'Foolish user banned'); auths_dirty = true; expsig(key); auths.set(key, { expire: Date.now()+1000*30, status: false }); if (verb) verb.remove(); this.remove(); banner = null; }); await stream.write(templ(`

click here if you want to get banned for 30 seconds.

otherwise, click the Verify button when it appears.

`)); await stream.write(``); var lastonly_i = 0; async function lastonly_b() { await stream.write(``); } await lastonly_b(); async function dumpflush(i) {} await dumpflush(); async function fakebusy(time = 500) { await lastonly_b(); await stream.write(`
Processing`); for (let i=0; i<10; i++) { await stream.sleep(time / 10); await stream.write('.'); } await stream.write(`
`); } await fakebusy(1000); function fincookie() { auths.set(key, { expire: Date.now()+1000*60*60, status: true }); // 1 hour auths_dirty = true; } var verb = newfunc(function () { pass=3; finf(); fincookie(); log(key, 'Checks passed'); this.remove(); verb = null; }); var msg = 'Challenge failed. Refresh page.'; var imgl = false; var imgls = false; var imge = Date.now() + 50; while ((!closed) && keyValid(key) && auths.get(key).prepping) { var exp; await Promise.race([ new Promise(succ => setTimeout(succ, Math.min(Math.max(auths.get(key).expire - Date.now(), 50), 5000))), ...((!imgl) ? [(new Promise(succ => setTimeout(succ, Math.max(imge - Date.now(), 0)))).then(_ => imgl=true)] : []), finp.then(nfinp), exp = on_expire(key) ]); if ((imgl && !imgls) && !closed) { imgls = true; log(key, 'Serving enter button'); await lastonly_b(); await stream.write(``); } exp.remove(); if (!closed) await stream.write(' '); if (banned) { msg = 'You are now banned for 30 seconds'; break; } if (pass == 3) { log(key, auths.get(key)); msg = 'You are in. Redirecting... '; break; } } if (banner) banner.remove(); if (verb) verb.remove() if (!closed) await stream.write('

'+msg); } finally { conns--; } }); }); setInterval(async function() { for (let [k,v] of auths.entries()) { keyValid(k); } await saveCache(); }, 5000) var lastconns=-1; setInterval(function() { let prepauths = new Map([...auths.entries()].filter(e=>e[1].prepping)).size; let connsc = conns | prepauths | funcs.size; if (!(connsc == 0 && lastconns == 0)) glog(`${conns} connections.. ${prepauths} prepauths.. ${funcs.size} funcs`); lastconns = connsc; }, 5000); serve(app);