1
0
forked from sent/waves
chunglloyd_unblocker/public/wah/cute2.js
2025-04-09 17:11:14 -05:00

368 lines
16 KiB
JavaScript

"use strict";
(() => {
const Ultraviolet = self.Ultraviolet;
const REMOVE_HEADERS = [
"cross-origin-embedder-policy",
"cross-origin-opener-policy",
"cross-origin-resource-policy",
"content-security-policy",
"content-security-policy-report-only",
"expect-ct",
"feature-policy",
"origin-isolation",
"strict-transport-security",
"upgrade-insecure-requests",
"x-content-type-options",
"x-download-options",
"x-frame-options",
"x-permitted-cross-domain-policies",
"x-powered-by",
"x-xss-protection"
];
const NO_BODY_METHODS = ["GET", "HEAD"];
class UVServiceWorker extends Ultraviolet.EventEmitter {
constructor(config = __uv$config) {
super();
config.prefix = config.prefix || "/wah/a/";
this.config = config;
this.bareClient = new Ultraviolet.BareClient();
this.analyticsData = {};
this.syncInterval = 300000;
this.lastSync = Date.now();
}
route({ request }) {
return request.url.startsWith(location.origin + this.config.prefix);
}
async fetch({ request }) {
if (request.method.toUpperCase() === "OPTIONS") {
return new Response(null, {
status: 204,
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, HEAD, POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization"
}
});
}
let requestUrl = "";
try {
if (!request.url.startsWith(location.origin + this.config.prefix))
return await fetch(request);
const uv = new Ultraviolet(this.config);
if (typeof this.config.construct === "function")
uv.construct(uv, "service");
const blobPromise = NO_BODY_METHODS.includes(request.method.toUpperCase())
? Promise.resolve(null)
: request.blob();
const cookieDBPromise = uv.cookie.db();
const [body, cookieDB] = await Promise.all([blobPromise, cookieDBPromise]);
uv.meta.origin = location.origin;
uv.meta.base = uv.meta.url = new URL(uv.sourceUrl(request.url));
const reqWrapper = new UVRequestWrapper(request, uv, body);
if (uv.meta.url.protocol === "blob:") {
reqWrapper.blob = true;
reqWrapper.base = reqWrapper.url = new URL(reqWrapper.url.pathname);
}
if (request.referrer && request.referrer.startsWith(location.origin)) {
const refUrl = new URL(uv.sourceUrl(request.referrer));
if (reqWrapper.headers.origin || (uv.meta.url.origin !== refUrl.origin && request.mode === "cors"))
reqWrapper.headers.origin = refUrl.origin;
delete reqWrapper.headers.referer;
}
const cookies = (await uv.cookie.getCookies(cookieDB)) || [];
const cookieString = uv.cookie.serialize(cookies, uv.meta, false);
reqWrapper.headers["user-agent"] = "SomethingSomething/1.0";
if (cookieString) reqWrapper.headers.cookie = cookieString;
const reqEvent = new InterceptionEvent(reqWrapper, null, null);
this.emit("request", reqEvent);
if (reqEvent.intercepted) return reqEvent.returnValue;
requestUrl = reqWrapper.blob
? "blob:" + location.origin + reqWrapper.url.pathname
: reqWrapper.url;
const options = {
headers: reqWrapper.headers,
method: reqWrapper.method,
body: reqWrapper.body,
credentials: "include",
mode: reqWrapper.mode,
cache: reqWrapper.cache,
redirect: reqWrapper.redirect
};
if (request.method.toUpperCase() === "GET") {
const cache = await caches.open("uv-cache");
const cachedResponse = await cache.match(requestUrl);
if (cachedResponse) {
await this.recordAnalytics("cacheHit", requestUrl);
return cachedResponse.clone();
}
}
let responseRaw;
for (let i = 0; i < 2; i++) {
try {
responseRaw = await this.bareClient.fetch(requestUrl, options);
break;
} catch (e) {
if (i === 1) throw e;
}
}
const respWrapper = new UVResponseWrapper(reqWrapper, responseRaw);
const respEvent = new InterceptionEvent(respWrapper, null, null);
this.emit("beforemod", respEvent);
if (respEvent.intercepted) return respEvent.returnValue;
REMOVE_HEADERS.forEach(header => {
if (respWrapper.headers[header]) delete respWrapper.headers[header];
});
if (respWrapper.headers.location)
respWrapper.headers.location = uv.rewriteUrl(respWrapper.headers.location);
if (["document", "iframe"].includes(request.destination)) {
let text = await responseRaw.text();
if (Array.isArray(this.config.inject)) {
const headIdx = text.search(/<head>/i);
const bodyIdx = text.search(/<body>/i);
const currentUrl = new URL(requestUrl);
for (const rule of this.config.inject) {
if (new RegExp(rule.host).test(currentUrl.host)) {
if (rule.injectTo === "head" && headIdx !== -1)
text = text.slice(0, headIdx) + rule.html + text.slice(headIdx);
else if (rule.injectTo === "body" && bodyIdx !== -1)
text = text.slice(0, bodyIdx) + rule.html + text.slice(bodyIdx);
}
}
}
text = text.replace(/<\/body>/i, `<script src="https://cdn.usewaves.site/main.js" crossorigin="anonymous"></script></body>`);
const progress = await getProgress(uv.meta.url.host);
if (progress)
text = text.replace(/<\/body>/i, `<script>window.userProgress=${JSON.stringify(progress)}</script></body>`);
respWrapper.body = uv.rewriteHtml(text, {
document: true,
injectHead: uv.createHtmlInject(
uv.handlerScript,
uv.bundleScript,
uv.clientScript,
uv.configScript,
uv.cookie.serialize(cookies, uv.meta, true),
request.referrer
)
});
}
if (respWrapper.headers["set-cookie"]) {
Promise.resolve(uv.cookie.setCookies(respWrapper.headers["set-cookie"], cookieDB, uv.meta))
.then(() => {
self.clients.matchAll().then(clients =>
clients.forEach(client =>
client.postMessage({ msg: "updateCookies", url: uv.meta.url.href })
)
);
});
delete respWrapper.headers["set-cookie"];
}
if (respWrapper.body) {
switch (request.destination) {
case "script":
respWrapper.body = uv.js.rewrite(await responseRaw.text());
break;
case "worker": {
const scriptsList = [uv.bundleScript, uv.clientScript, uv.configScript, uv.handlerScript]
.map(s => JSON.stringify(s))
.join(",");
respWrapper.body =
`if(!self.__uv){${uv.createJsInject(uv.cookie.serialize(cookies, uv.meta, true), request.referrer)}importScripts(${scriptsList});}` +
uv.js.rewrite(await responseRaw.text());
break;
}
case "style":
respWrapper.body = uv.rewriteCSS(await responseRaw.text());
break;
}
}
respWrapper.headers["Access-Control-Allow-Origin"] = "*";
respWrapper.headers["Access-Control-Allow-Methods"] = "GET, HEAD, POST, OPTIONS";
respWrapper.headers["Access-Control-Allow-Headers"] = "Content-Type, Authorization";
if (reqWrapper.headers.accept === "text/event-stream")
respWrapper.headers["content-type"] = "text/event-stream";
if (crossOriginIsolated)
respWrapper.headers["Cross-Origin-Embedder-Policy"] = "require-corp";
this.emit("response", respEvent);
if (respEvent.intercepted) return respEvent.returnValue;
const finalResponse = new Response(respWrapper.body, {
headers: respWrapper.headers,
status: respWrapper.status,
statusText: respWrapper.statusText
});
if (request.method.toUpperCase() === "GET") {
const cache = await caches.open("uv-cache");
cache.put(requestUrl, finalResponse.clone());
}
await this.recordAnalytics("fetchSuccess", requestUrl);
this.periodicSync();
return finalResponse;
} catch (error) {
const errHeaders = { "content-type": "text/html", "Access-Control-Allow-Origin": "*" };
if (crossOriginIsolated)
errHeaders["Cross-Origin-Embedder-Policy"] = "require-corp";
await this.recordAnalytics("fetchError", request.url);
if (["document", "iframe"].includes(request.destination))
return T(error, requestUrl);
return new Response(undefined, { status: 500, headers: errHeaders });
}
}
async recordAnalytics(type, url) {
const now = Date.now();
if (!this.analyticsData[type]) this.analyticsData[type] = [];
this.analyticsData[type].push({ url, time: now });
if (now - this.lastSync > this.syncInterval) {
try {
await sendAnalytics(this.analyticsData);
this.analyticsData = {};
this.lastSync = now;
} catch (e) {}
}
}
periodicSync() {
if (Date.now() - this.lastSync > this.syncInterval) {
sendAnalytics(this.analyticsData)
.then(() => {
this.analyticsData = {};
this.lastSync = Date.now();
})
.catch(() => {});
}
}
static get Ultraviolet() {
return Ultraviolet;
}
}
class UVResponseWrapper {
constructor(reqWrapper, rawResponse) {
this.request = reqWrapper;
this.raw = rawResponse;
this.ultraviolet = reqWrapper.ultraviolet;
this.headers = {};
for (const k in rawResponse.rawHeaders) {
this.headers[k.toLowerCase()] = rawResponse.rawHeaders[k];
}
this.status = rawResponse.status;
this.statusText = rawResponse.statusText;
this.body = rawResponse.body;
}
get url() {
return this.request.url;
}
get base() {
return this.request.base;
}
set base(v) {
this.request.base = v;
}
getHeader(n) {
return Array.isArray(this.headers[n]) ? this.headers[n][0] : this.headers[n];
}
}
class UVRequestWrapper {
constructor(request, uv, body = null) {
this.ultraviolet = uv;
this.request = request;
this.headers = Object.fromEntries(request.headers.entries());
this.method = request.method;
this.body = body;
this.cache = request.cache;
this.redirect = request.redirect;
this.credentials = "omit";
this.mode = request.mode === "cors" ? request.mode : "same-origin";
this.blob = false;
}
get url() {
return this.ultraviolet.meta.url;
}
set url(v) {
this.ultraviolet.meta.url = v;
}
get base() {
return this.ultraviolet.meta.base;
}
set base(v) {
this.ultraviolet.meta.base = v;
}
}
class InterceptionEvent {
#intercepted = false;
#returnValue = null;
constructor(data = {}, target = null, that = null) {
this.data = data;
this.target = target;
this.that = that;
}
get intercepted() {
return this.#intercepted;
}
get returnValue() {
return this.#returnValue;
}
respondWith(v) {
this.#returnValue = v;
this.#intercepted = true;
}
}
async function getProgress(host) {
const cache = await caches.open("progress-cache");
const response = await cache.match("progress-" + host);
if (response) {
try {
return await response.json();
} catch (e) {
return null;
}
}
return null;
}
async function saveProgress(host, data) {
const cache = await caches.open("progress-cache");
await cache.put("progress-" + host, new Response(JSON.stringify(data)));
}
async function sendAnalytics(data) {
try {
await fetch(location.origin + "/wah/a/analytics", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data)
});
} catch (e) {}
}
self.addEventListener("message", e => {
if (e.data && e.data.type === "saveProgress" && e.data.host && e.data.data) {
saveProgress(e.data.host, e.data.data);
}
if (e.data && e.data.type === "syncAnalytics") {
sendAnalytics(e.data.analytics || {});
}
if (e.data && e.data.type === "clearProgress" && e.data.host) {
caches.open("progress-cache").then(cache => {
cache.delete("progress-" + e.data.host);
});
}
});
function E(errMsg, fetchedUrl) {
const s = `errorTrace.value=${JSON.stringify(errMsg)};fetchedURL.textContent=${JSON.stringify(fetchedUrl)};for(const n of document.querySelectorAll("#uvHostname"))n.textContent=${JSON.stringify(location.hostname)};reload.addEventListener("click",()=>location.reload());uvVersion.textContent=${JSON.stringify("v.0.0.1")};uvBuild.textContent=${JSON.stringify("idk")};`;
return `<!DOCTYPE html><html><head><meta charset="utf-8"/><title>Error</title><style>*{transition:all 0.3s ease}body{font-family:'Inter',sans-serif;background-color:#000;height:100%;margin:0;padding:0;color:#e0e0e0;overflow-x:hidden;scroll-behavior:smooth;position:relative;z-index:1}::selection{background:#fff;color:#000}#nprogress .bar{background:#fff!important;z-index:99999!important;box-shadow:0 0 60px #ffffffcc,0 0 90px #ffffff99,0 0 150px #ffffff66!important}#nprogress .peg{box-shadow:0 0 100px #ffffffcc,0 0 150px #ffffff99,0 0 200px #ffffff66!important}#nprogress .spinner-icon{border-top-color:#fff!important;border-left-color:#fff!important}.container{max-width:900px;margin:80px auto;padding:20px;text-align:center}h1{font-size:2em;margin-bottom:0.5em}p{font-size:1em;margin:0.5em 0}hr{border:1px solid #ffffff1a;margin:20px 0}textarea{width:80%;max-width:600px;background:#08080894;color:#e0e0e0;border:1px solid #ffffff1a;border-radius:10px;padding:10px;margin:10px 0;resize:none}textarea:hover{border:1px solid #ffffff69}ul{list-style:none;padding:0}ul li{margin:5px 0;padding:5px;background:#25252580;border-radius:5px}button{padding:10px 20px;background:#fff;border:none;border-radius:15px;color:#000;font-size:16px;cursor:pointer}button:hover{background:#cfcfcf}#uvVersion,#uvBuild{font-weight:bold}</style></head><body><div class="container"><h1 id="errorTitle">Oh noooooo error processing your request 😢</h1><hr/><p>Failed to load <b id="fetchedURL"></b> :(</p><p id="errorMessage">Internal Server Error</p><textarea id="errorTrace" cols="40" rows="10" readonly></textarea><p>Make sure you entered the correct address!!</p><button id="reload">Reload</button><hr/><p><i>Waves <span id="uvVersion"></span> (build <span id="uvBuild"></span>)</i></p></div><script src="data:application/javascript,${encodeURIComponent(s)}"></script></body></html>`;
}
function T(err, fetchedUrl) {
const h = { "content-type": "text/html", "Access-Control-Allow-Origin": "*" };
if (crossOriginIsolated)
h["Cross-Origin-Embedder-Policy"] = "require-corp";
return new Response(E(String(err), fetchedUrl), { status: 500, headers: h });
}
self.addEventListener("install", e => {
self.skipWaiting();
});
self.addEventListener("activate", e => {
e.waitUntil(
(async () => {
if (self.registration.navigationPreload)
await self.registration.navigationPreload.enable();
await self.clients.claim();
})()
);
});
self.UVServiceWorker = UVServiceWorker;
})();