commit
aee0c6c202
12 changed files with 183 additions and 18 deletions
2
.github/workflows/releases.yml
vendored
2
.github/workflows/releases.yml
vendored
|
|
@ -36,7 +36,7 @@ jobs:
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install --no-frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
|
|
||||||
- name: Create Release Pull Request or Publish
|
- name: Create Release Pull Request or Publish
|
||||||
id: changesets
|
id: changesets
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ const viteWispServer = (): Plugin => {
|
||||||
name: "vite-wisp-server",
|
name: "vite-wisp-server",
|
||||||
configureServer(server) {
|
configureServer(server) {
|
||||||
server.httpServer?.on("upgrade", (req, socket, head) => {
|
server.httpServer?.on("upgrade", (req, socket, head) => {
|
||||||
req.url.startsWith("/wisp") ? wisp.routeRequest(req, socket, head) : undefined;
|
req.url.startsWith("/wisp") || req.url.startsWith("/adblock") ? wisp.routeRequest(req, socket, head) : undefined;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,8 @@ const serverFactory: FastifyServerFactory = (
|
||||||
handler(req, res);
|
handler(req, res);
|
||||||
})
|
})
|
||||||
.on("upgrade", (req, socket, head) => {
|
.on("upgrade", (req, socket, head) => {
|
||||||
if (req.url?.endsWith("/wisp/")) {
|
if (req.url?.endsWith("/wisp/") || req.url?.endsWith("/adblock/")) {
|
||||||
|
console.log(req.url);
|
||||||
wisp.routeRequest(req, socket as Socket, head);
|
wisp.routeRequest(req, socket as Socket, head);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
const init = async () => {
|
const init = async () => {
|
||||||
settings.searchEngine();
|
settings.searchEngine();
|
||||||
settings.proxy();
|
settings.proxy();
|
||||||
|
settings.adBlock();
|
||||||
await sw.wispServer();
|
await sw.wispServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,4 +17,7 @@ const { active } = Astro.props;
|
||||||
<a href="/settings/links/" class=`gap-2 px-4 py-2 rounded-lg h-10 w-full text-sm font-medium transition-colors items-center justify-start inline-flex ${active === "links" ? 'bg-(--secondary) hover:bg-(--secondary)/[0.8]' : 'bg-(--background) hover:bg-(--accent)'}`>
|
<a href="/settings/links/" class=`gap-2 px-4 py-2 rounded-lg h-10 w-full text-sm font-medium transition-colors items-center justify-start inline-flex ${active === "links" ? 'bg-(--secondary) hover:bg-(--secondary)/[0.8]' : 'bg-(--background) hover:bg-(--accent)'}`>
|
||||||
<Icon name="lucide:link" class="h-5 w-5" /> Social Links
|
<Icon name="lucide:link" class="h-5 w-5" /> Social Links
|
||||||
</a>
|
</a>
|
||||||
|
<a href="/settings/cloaking/" class=`gap-2 px-4 py-2 rounded-lg h-10 w-full text-sm font-medium transition-colors items-center justify-start inline-flex ${active === "cloaking" ? 'bg-(--secondary) hover:bg-(--secondary)/[0.8]' : 'bg-(--background) hover:bg-(--accent)'}`>
|
||||||
|
<Icon name="lucide:eye-off" class="h-5 w-5" /> Cloaking
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,13 @@
|
||||||
import type { DropdownOptions } from "@utils/types";
|
import type { DropdownOptions } from "@utils/types";
|
||||||
interface Props {
|
interface Props {
|
||||||
id: string;
|
id: string;
|
||||||
|
classes?: string;
|
||||||
options: DropdownOptions[];
|
options: DropdownOptions[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const { id, options } = Astro.props;
|
const { id, options, classes } = Astro.props;
|
||||||
---
|
---
|
||||||
<select id=`dropdownBox-${id}` class="cursor-pointer flex h-10 w-[180px] items-center justify-between text-(--foreground) background-(--background) rounded-lg border border-(--border) px-3 py-2">
|
<select id=`dropdownBox-${id}` class=`${classes} cursor-pointer flex h-10 w-[180px] items-center justify-between text-(--foreground) background-(--background) rounded-lg border border-(--border) px-3 py-2`>
|
||||||
{options.map((el) =>
|
{options.map((el) =>
|
||||||
<option class="w-full bg-(--accent) rounded-sm p-1" value={el.value}>{el.name}</option>
|
<option class="w-full bg-(--accent) rounded-sm p-1" value={el.value}>{el.name}</option>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,6 @@ const link = Astro.url.searchParams.get("redir");
|
||||||
if (event.key === "Enter") {
|
if (event.key === "Enter") {
|
||||||
const sw = SW.getInstance().next().value!;
|
const sw = SW.getInstance().next().value!;
|
||||||
const settings = await Settings.getInstance();
|
const settings = await Settings.getInstance();
|
||||||
await sw.setTransport();
|
|
||||||
iframe.classList.remove("hidden");
|
iframe.classList.remove("hidden");
|
||||||
iframe.src = sw.encodeURL(input.value);
|
iframe.src = sw.encodeURL(input.value);
|
||||||
}
|
}
|
||||||
|
|
@ -123,9 +122,14 @@ const link = Astro.url.searchParams.get("redir");
|
||||||
history.pushState({}, "", "/");
|
history.pushState({}, "", "/");
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
(async () => { await init(); })();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('link-element', CustomComponent);
|
customElements.define('link-element', CustomComponent);
|
||||||
|
document.addEventListener("astro:page-load", async () => {
|
||||||
|
try {
|
||||||
|
await init();
|
||||||
|
}
|
||||||
|
catch (_) {}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
63
src/pages/settings/cloaking.astro
Normal file
63
src/pages/settings/cloaking.astro
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
---
|
||||||
|
import SettingsLayout from "@layouts/SettingsLayout.astro";
|
||||||
|
import Input from "@components/ui/Input.astro";
|
||||||
|
import Button from "@components/ui/Button.astro";
|
||||||
|
---
|
||||||
|
<SettingsLayout active="cloaking" title="Cloaking">
|
||||||
|
<div class="w-full flex-grow">
|
||||||
|
<div class="w-full flex flex-row gap-4">
|
||||||
|
<div class="w-1/2">
|
||||||
|
<div>
|
||||||
|
<p> About Blank </p>
|
||||||
|
<Input id="aboutBlankCloaker" placeholder="Redirect url (EX: https://google.com)" />
|
||||||
|
</div>
|
||||||
|
<div class="mt-2">
|
||||||
|
<Button id="aboutBlankLaunch" text="Cloak!" icon="lucide:square-arrow-out-up-right" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="w-1/2">
|
||||||
|
<div>
|
||||||
|
<p> Blob </p>
|
||||||
|
<Input id="blobCloaker" placeholder="Redirect url (EX: https://google.com)" />
|
||||||
|
</div>
|
||||||
|
<div class="mt-2">
|
||||||
|
<Button id="blobLaunch" text="Cloak!" icon="lucide:square-arrow-out-up-right" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</SettingsLayout>
|
||||||
|
<script>
|
||||||
|
import { Settings } from "@utils/settings.ts";
|
||||||
|
import { StoreManager } from "@utils/storage";
|
||||||
|
import { SW } from "@utils/proxy.ts";
|
||||||
|
|
||||||
|
const handleAb = async (settings: Settings, sw: SW, storage: StoreManager<"radius||settings">) => {
|
||||||
|
const input = document.getElementById("aboutBlankCloaker") as HTMLInputElement;
|
||||||
|
const button = document.getElementById("aboutBlankLaunch") as HTMLButtonElement;
|
||||||
|
button.addEventListener("click", () => {
|
||||||
|
const url = sw.search(input.value, storage.getVal('searchEngine'));
|
||||||
|
settings.cloak(url).aboutBlank();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleBlob = async (settings: Settings, sw: SW, storage: StoreManager<"radius||settings">) => {
|
||||||
|
const input = document.getElementById("blobCloaker") as HTMLInputElement;
|
||||||
|
const button = document.getElementById("blobLaunch") as HTMLButtonElement;
|
||||||
|
button.addEventListener("click", () => {
|
||||||
|
const url = sw.search(input.value, storage.getVal('searchEngine'));
|
||||||
|
settings.cloak(url).blob();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener('astro:page-load', async () => {
|
||||||
|
const settings = await Settings.getInstance();
|
||||||
|
const sw = SW.getInstance().next().value!;
|
||||||
|
const storageManager = new StoreManager<"radius||settings">("radius||settings");
|
||||||
|
try {
|
||||||
|
await handleAb(settings, sw, storageManager);
|
||||||
|
await handleBlob(settings, sw, storageManager);
|
||||||
|
}
|
||||||
|
catch (_) {}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
@ -37,6 +37,15 @@ Object.keys(SearchEngines).forEach((k) =>
|
||||||
<div>
|
<div>
|
||||||
<p> Wisp Server </p>
|
<p> Wisp Server </p>
|
||||||
<Input id="wispServerSwitcher" placeholder="Wisp server URL (EX: wss://radiusproxy.app/wisp/" />
|
<Input id="wispServerSwitcher" placeholder="Wisp server URL (EX: wss://radiusproxy.app/wisp/" />
|
||||||
|
<div class="mt-2 hidden" id="adBlocking">
|
||||||
|
<p> Ad Blocking </p>
|
||||||
|
<Dropdown id="adBlocking" options={
|
||||||
|
[
|
||||||
|
{ name: 'Enabled', value: 'enabled', default: true },
|
||||||
|
{ name: 'Disabled', value: 'disabled' }
|
||||||
|
]
|
||||||
|
} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-2 mb-2 hidden" id="wispServerInfo">
|
<div class="mt-2 mb-2 hidden" id="wispServerInfo">
|
||||||
<p class="text-blue-500" id="wispServerInfo-inner"> Checking URL... </p>
|
<p class="text-blue-500" id="wispServerInfo-inner"> Checking URL... </p>
|
||||||
|
|
@ -90,9 +99,10 @@ Object.keys(SearchEngines).forEach((k) =>
|
||||||
const wispServerInfoInner = document.getElementById("wispServerInfo-inner") as HTMLParagraphElement;
|
const wispServerInfoInner = document.getElementById("wispServerInfo-inner") as HTMLParagraphElement;
|
||||||
const wispServerSave = document.getElementById("wispServerSave") as HTMLButtonElement;
|
const wispServerSave = document.getElementById("wispServerSave") as HTMLButtonElement;
|
||||||
const wispServerReset = document.getElementById("wispServerReset") as HTMLButtonElement;
|
const wispServerReset = document.getElementById("wispServerReset") as HTMLButtonElement;
|
||||||
|
const adBlocking = document.getElementById("adBlocking") as HTMLDivElement;
|
||||||
|
|
||||||
wispServerSwitcher.value = opts.storageManager.getVal("wispServer");
|
wispServerSwitcher.value = opts.storageManager.getVal("wispServer");
|
||||||
|
const resetVal = `${(location.protocol === "https:" ? "wss://" : "ws://")}${location.host}/wisp/`
|
||||||
const reset = (hide: boolean = true) => {
|
const reset = (hide: boolean = true) => {
|
||||||
if (hide) wispServerInfo.classList.add("hidden");
|
if (hide) wispServerInfo.classList.add("hidden");
|
||||||
wispServerInfoInner.innerText = "Checking URL..."
|
wispServerInfoInner.innerText = "Checking URL..."
|
||||||
|
|
@ -100,6 +110,26 @@ Object.keys(SearchEngines).forEach((k) =>
|
||||||
wispServerInfoInner.classList.remove("text-green-500");
|
wispServerInfoInner.classList.remove("text-green-500");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const adBlockingFunc = () => {
|
||||||
|
const adBlockingDropdown = document.getElementById("dropdownBox-adBlocking") as HTMLSelectElement;
|
||||||
|
adBlockingDropdown.addEventListener("change", () => {
|
||||||
|
opts.settings.adBlock(adBlockingDropdown.value === "enabled" ? true : false);
|
||||||
|
});
|
||||||
|
|
||||||
|
adBlockingDropdown.value = opts.storageManager.getVal("adBlock") === "true" ? "enabled" : "disabled";
|
||||||
|
|
||||||
|
if (wispServerSwitcher.value === resetVal) {
|
||||||
|
adBlocking.classList.remove("hidden");
|
||||||
|
opts.settings.adBlock(true);
|
||||||
|
adBlockingDropdown.value = "enabled";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
adBlocking.classList.add("hidden");
|
||||||
|
opts.settings.adBlock(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
adBlockingFunc();
|
||||||
|
|
||||||
wispServerSave.addEventListener("click", async () => {
|
wispServerSave.addEventListener("click", async () => {
|
||||||
const server = wispServerSwitcher.value;
|
const server = wispServerSwitcher.value;
|
||||||
wispServerInfo.classList.remove("hidden");
|
wispServerInfo.classList.remove("hidden");
|
||||||
|
|
@ -114,7 +144,9 @@ Object.keys(SearchEngines).forEach((k) =>
|
||||||
reset(false);
|
reset(false);
|
||||||
wispServerInfoInner.innerText = "Wisp Server Set!";
|
wispServerInfoInner.innerText = "Wisp Server Set!";
|
||||||
wispServerInfoInner.classList.add("text-green-500");
|
wispServerInfoInner.classList.add("text-green-500");
|
||||||
|
//adBlocking.classList.contains("hidden") ? "" : adBlocking.classList.add("hidden");
|
||||||
await opts.sw.wispServer(wispServerSwitcher.value, true);
|
await opts.sw.wispServer(wispServerSwitcher.value, true);
|
||||||
|
adBlockingFunc();
|
||||||
}
|
}
|
||||||
|
|
||||||
// We reset this after 4 seconds (any errors OR success)
|
// We reset this after 4 seconds (any errors OR success)
|
||||||
|
|
@ -125,9 +157,10 @@ Object.keys(SearchEngines).forEach((k) =>
|
||||||
wispServerInfo.classList.remove("hidden");
|
wispServerInfo.classList.remove("hidden");
|
||||||
wispServerInfoInner.innerText = "Wisp Server Reset!";
|
wispServerInfoInner.innerText = "Wisp Server Reset!";
|
||||||
wispServerInfoInner.classList.add("text-green-500");
|
wispServerInfoInner.classList.add("text-green-500");
|
||||||
await opts.sw.wispServer(`${(location.protocol === "https:" ? "wss://" : "ws://")}${location.host}/wisp/`, true);
|
await opts.sw.wispServer(resetVal, true);
|
||||||
wispServerSwitcher.value = opts.storageManager.getVal("wispServer");
|
wispServerSwitcher.value = opts.storageManager.getVal("wispServer");
|
||||||
setTimeout(reset, 4000);
|
setTimeout(reset, 4000);
|
||||||
|
adBlockingFunc();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ class SW {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#search(input: string, template: string) {
|
search(input: string, template: string) {
|
||||||
try {
|
try {
|
||||||
return new URL(input).toString();
|
return new URL(input).toString();
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
|
|
@ -52,7 +52,7 @@ class SW {
|
||||||
|
|
||||||
encodeURL(string: string): string {
|
encodeURL(string: string): string {
|
||||||
const proxy = this.#storageManager.getVal("proxy") as "uv" | "sj";
|
const proxy = this.#storageManager.getVal("proxy") as "uv" | "sj";
|
||||||
const input = this.#search(string, this.#storageManager.getVal("searchEngine"));
|
const input = this.search(string, this.#storageManager.getVal("searchEngine"));
|
||||||
return proxy === "uv"
|
return proxy === "uv"
|
||||||
? `${__uv$config.prefix}${__uv$config.encodeUrl!(input)}`
|
? `${__uv$config.prefix}${__uv$config.encodeUrl!(input)}`
|
||||||
: this.#scramjetController!.encodeUrl(input);
|
: this.#scramjetController!.encodeUrl(input);
|
||||||
|
|
@ -60,6 +60,13 @@ class SW {
|
||||||
|
|
||||||
async setTransport(transport?: "epoxy" | "libcurl", get?: boolean) {
|
async setTransport(transport?: "epoxy" | "libcurl", get?: boolean) {
|
||||||
console.log("Setting transport");
|
console.log("Setting transport");
|
||||||
|
const wispServer = (): string => {
|
||||||
|
const wispServerVal = this.#storageManager.getVal("wispServer");
|
||||||
|
if (this.#storageManager.getVal("adBlock") === "true") {
|
||||||
|
return wispServerVal.replace("/wisp/", "/adblock/");
|
||||||
|
}
|
||||||
|
return wispServerVal;
|
||||||
|
}
|
||||||
if (get) return this.#storageManager.getVal("transport");
|
if (get) return this.#storageManager.getVal("transport");
|
||||||
this.#storageManager.setVal(
|
this.#storageManager.setVal(
|
||||||
"transport",
|
"transport",
|
||||||
|
|
@ -68,23 +75,24 @@ class SW {
|
||||||
switch (transport) {
|
switch (transport) {
|
||||||
case "epoxy": {
|
case "epoxy": {
|
||||||
await this.#baremuxConn!.setTransport("/epoxy/index.mjs", [
|
await this.#baremuxConn!.setTransport("/epoxy/index.mjs", [
|
||||||
{ wisp: this.#storageManager.getVal("wispServer") }
|
{ wisp: wispServer() }
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
case "libcurl": {
|
case "libcurl": {
|
||||||
await this.#baremuxConn!.setTransport("/libcurl/index.mjs", [
|
await this.#baremuxConn!.setTransport("/libcurl/index.mjs", [
|
||||||
{ wisp: this.#storageManager.getVal("wispServer") }
|
{ wisp: wispServer() }
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
await this.#baremuxConn!.setTransport("/epoxy/index.mjs", [
|
await this.#baremuxConn!.setTransport("/epoxy/index.mjs", [
|
||||||
{ wisp: this.#storageManager.getVal("wispServer") }
|
{ wisp: wispServer() }
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async wispServer(wispServer?: string, set?: true) {
|
async wispServer(wispServer?: string, set?: true) {
|
||||||
|
console.log(wispServer?.replace("/wisp/", "/adblock/"));
|
||||||
this.#storageManager.setVal(
|
this.#storageManager.setVal(
|
||||||
"wispServer",
|
"wispServer",
|
||||||
wispServer ||
|
wispServer ||
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,57 @@ class Settings {
|
||||||
this.#storageManager.setVal("searchEngine", engine || SearchEngines.DuckDuckGo);
|
this.#storageManager.setVal("searchEngine", engine || SearchEngines.DuckDuckGo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cloak(location: string) {
|
||||||
|
return {
|
||||||
|
aboutBlank: () => {
|
||||||
|
const win = window.open();
|
||||||
|
if (!win) return;
|
||||||
|
window.location.replace(location);
|
||||||
|
const iframe = win.document.createElement("iframe") as HTMLIFrameElement;
|
||||||
|
win.document.body.setAttribute('style', 'margin: 0; height: 100vh; width: 100%;');
|
||||||
|
iframe.setAttribute('style', 'border: none; width: 100%; height: 100%; margin: 0;');
|
||||||
|
iframe.src = window.location.href;
|
||||||
|
win.document.body.appendChild(iframe);
|
||||||
|
},
|
||||||
|
blob: () => {
|
||||||
|
const win = window.open();
|
||||||
|
if (!win) return;
|
||||||
|
window.location.replace(location);
|
||||||
|
const content = `
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style type="text/css">
|
||||||
|
body, html {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<iframe style="border: none; width: 100%; height: 100%;" src="${window.location.href}"></iframe>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`;
|
||||||
|
const blob = new Blob([content], { type: 'text/html' });
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
win.location.href = url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
adBlock(enabled?: boolean) {
|
||||||
|
if (enabled === true || enabled === false) {
|
||||||
|
this.#storageManager.setVal("adBlock", enabled.valueOf().toString());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.#storageManager.setVal("adBlock", "true");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async *#init() {
|
async *#init() {
|
||||||
yield this.theme(this.#storageManager.getVal("theme") || "default");
|
yield this.theme(this.#storageManager.getVal("theme") || "default");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import type { Props } from "astro";
|
import type { Props } from "astro";
|
||||||
|
|
||||||
interface SettingsProps extends Props {
|
interface SettingsProps extends Props {
|
||||||
active: "appearance" | "credits" | "links" | "proxy";
|
active: "appearance" | "credits" | "links" | "proxy" | "cloaking";
|
||||||
title: string;
|
title: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue