Feat: custom wisp server urls

This commit is contained in:
MotorTruck1221 2024-11-09 01:18:50 -07:00
parent 9bc00baa38
commit c9e92d92f8
No known key found for this signature in database
GPG key ID: 08F417E2B8B61EA4
17 changed files with 190 additions and 153 deletions

View file

@ -1,12 +1,12 @@
{
"$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json",
"changelog": ["@changesets/changelog-github", { "repo": "nebulaservices/nebula" }],
"commit": false,
"fixed": [],
"linked": [],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": [],
"privatePackages": { "version": true, "tag": true }
"$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json",
"changelog": ["@changesets/changelog-github", { "repo": "nebulaservices/nebula" }],
"commit": false,
"fixed": [],
"linked": [],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": [],
"privatePackages": { "version": true, "tag": true }
}

View file

@ -1,19 +1,19 @@
:root {
--background-primary: #191724;
--background-lighter: #16121f;
--navbar-color: #26233a;
--navbar-height: 60px;
--navbar-text-color: #7967dd;
--navbar-link-color: #e0def4;
--navbar-link-hover-color: gray;
--navbar-font: "Roboto";
--input-text-color: #e0def4;
--input-placeholder-color: white;
--input-background-color: #1f1d2e;
--input-border-color: #eb6f92;
--input-border-size: 1.3px;
--navbar-logo-filter: none;
--dropdown-option-hover-color: #312a49;
--tab-color: var(--black);
--border-color: #16121f;
--background-primary: #191724;
--background-lighter: #16121f;
--navbar-color: #26233a;
--navbar-height: 60px;
--navbar-text-color: #7967dd;
--navbar-link-color: #e0def4;
--navbar-link-hover-color: gray;
--navbar-font: "Roboto";
--input-text-color: #e0def4;
--input-placeholder-color: white;
--input-background-color: #1f1d2e;
--input-border-color: #eb6f92;
--input-border-size: 1.3px;
--navbar-logo-filter: none;
--dropdown-option-hover-color: #312a49;
--tab-color: var(--black);
--border-color: #16121f;
}

View file

@ -9,7 +9,7 @@ const ww = new WorkerWare({ debug: false });
if (navigator.userAgent.includes("Firefox")) {
Object.defineProperty(globalThis, "crossOriginIsolated", {
value: true,
writable: true
writable: true
});
}

View file

@ -1,33 +1,29 @@
import { createServer } from "node:http";
import {
FastifyServerFactory,
FastifyServerFactoryHandler,
RawServerDefault,
} from "fastify";
import { FastifyServerFactory, FastifyServerFactoryHandler, RawServerDefault } from "fastify";
import wisp from "wisp-server-node";
import { LOG_LEVEL, WispOptions } from "wisp-server-node/dist/Types.js";
import { parsedDoc } from "./config.js";
const wispOptions: WispOptions = {
logLevel: parsedDoc.server.server.logging ? LOG_LEVEL.DEBUG : LOG_LEVEL.NONE,
pingInterval: 30,
logLevel: parsedDoc.server.server.logging ? LOG_LEVEL.DEBUG : LOG_LEVEL.NONE,
pingInterval: 30
};
const serverFactory: FastifyServerFactory = (
handler: FastifyServerFactoryHandler
handler: FastifyServerFactoryHandler
): RawServerDefault => {
const httpServer = createServer();
httpServer.on("request", (req, res) => {
handler(req, res);
});
httpServer.on("upgrade", (req, socket, head) => {
if (parsedDoc.server.server.wisp) {
if (req.url?.endsWith("/wisp/")) {
wisp.routeRequest(req, socket as any, head, wispOptions);
}
}
});
return httpServer;
const httpServer = createServer();
httpServer.on("request", (req, res) => {
handler(req, res);
});
httpServer.on("upgrade", (req, socket, head) => {
if (parsedDoc.server.server.wisp) {
if (req.url?.endsWith("/wisp/")) {
wisp.routeRequest(req, socket as any, head, wispOptions);
}
}
});
return httpServer;
};
export { serverFactory };

View file

@ -3,12 +3,22 @@ interface Inputs {
input: boolean;
required?: boolean;
placeholder?: string;
validate?: boolean;
validateString?: string;
}
interface SelectOptions {
value: string;
name: string;
disabled: boolean;
}
interface Both {
enabled: boolean;
showOnSelect?: {
value: string;
};
showOnInput?: boolean;
}
interface Selects {
select: boolean;
name?: string;
@ -24,27 +34,31 @@ interface Props {
description: string;
input: Inputs;
select: Selects;
both: Both;
button: Buttons;
}
const { title, description, input, select, button } = Astro.props;
const { title, description, input, select, both, button } = Astro.props;
---
<div class="w-64 rounded-3xl bg-navbar-color h-64 flex flex-col items-center p-4">
<div class={`${both.enabled ? "h-72" : "h-64"} w-64 rounded-3xl bg-navbar-color flex flex-col items-center p-4`}>
<h1 class="text-3xl font-bold mb-2"> { title } </h1>
<p class="text-md w-full text-ellipsis text-center"> { description } </p>
<div class="w-full h-full flex-grow flex justify-center items-center flex-col gap-4">
<!-- We only want to render an input if it's enabled -->
{input.input &&
{(input.input && !both.enabled) &&
<input class="text-md w-full h-10 p-2 bg-input border border-input-border-color rounded-md text-input-text" required={input.required} placeholder={input.placeholder}></input>
}
<!-- Same with dropdown selections -->
{select.select &&
<select id={select.name?.replace(/[^a-zA-Z0-9]/g, '').toLowerCase()} class="text-md w-full h-10 p-2 bg-input border border-input-border-color rounded-md text-input-text" multiple={select.multiple} name={select.name}>
<select id={select.name?.replace(/[^a-zA-Z0-9]/g, '').toLowerCase()} class="text-md w-full h-10 p-2 bg-input border border-input-border-color rounded-md text-input-text" multiple={select.multiple} name={select.name}>
{select.options!.map((option) => (
<option disabled={option.disabled} value={option.value}>{option.name}</option>
<option id={option.value} disabled={option.disabled} value={option.value}>{option.name}</option>
))}
</select>
</select>
}
{(both.enabled && both.showOnSelect?.value) &&
<input id={'inputOnSelectValue' + both.showOnSelect?.value} class="hidden text-md w-full h-10 p-2 bg-input border border-input-border-color rounded-md text-input-text" required={input.required} placeholder={input.placeholder}></input>
}
<button id={button.id.replace(/[^a-zA-Z0-9]/g, '').toLowerCase()} class="w-36 h-10 rounded-md border border-input-border-color text-input-text bg-input hover:border-input hover:bg-input-border-color hover:text-input hover:font-bold active:bg-input active:text-input-text transition-all duration-200">
{button.name}

View file

@ -4,8 +4,8 @@ import Header from "@components/Header.astro";
import MobileNavigation from "@components/MobileNavigation.astro";
import SettingsLoader from "@components/settings/Loader.astro";
interface Props {
title: string;
noHeader?: string;
title: string;
noHeader?: string;
}
const { title, noHeader } = Astro.props;

View file

@ -9,7 +9,7 @@ import { Icon } from "astro-icon/components";
<div class="flex flex-row font-roboto">
<div class="text-text-color mt-16 fixed inset-0 h-[calc(100%-4rem)] z-0 bg-primary flex-col flex md:flex-row">
<div class="items-center md:p-3 sm:p-3 flex flex-row border-border-color md:gap-10 xl:gap-10 max-sm:gap-5 sm:gap-5 md:border-r-2 max:md:w-2/12 md:flex-col md:bg-navbar-color md:gap-0 overflow-x-auto md:overflow-x-hidden overflow-y-hidden max-md:ml-1 max-md:mr-1 max-md:max-h-24 max-md:min-h-24 max-md:justify-left max-md:scroll-ml-3 max-md:scroll-mr-3 max-md:snap-x max-md:snap-mandatory">
<div class="items-center md:p-3 sm:p-3 flex flex-row border-border-color md:gap-10 xl:gap-10 max-sm:gap-5 sm:gap-5 md:border-r-2 lg:w-2/12 md:w-3/12 md:flex-col md:bg-navbar-color md:gap-0 overflow-x-auto md:overflow-x-hidden overflow-y-hidden max-md:ml-1 max-md:mr-1 max-md:max-h-24 max-md:min-h-24 max-md:justify-left max-md:scroll-ml-3 max-md:scroll-mr-3 max-md:snap-x max-md:snap-mandatory">
<SidebarButton title={t("settings.appearance")} route={`/${lang}/settings/appearance`}>
<Icon name="ph:palette" class="h-6 w-6 text-text-color transition duration-500 group-hover:text-text-hover-color md:h-6 md:w-6" />
</SidebarButton>
@ -26,7 +26,7 @@ import { Icon } from "astro-icon/components";
<Icon name="ph:user" class="h-6 w-6 text-text-color transistion duration-500 group-hover:text-text-hover-color md:h-6 md:w=6" />
</SidebarButton>
</div>
<div class="p-8 md:pb-2 flex-grow overflow-y-auto">
<div class="p-8 md:pb-2 w-full flex-grow overflow-y-auto">
<p class="text-5xl font-semibold mb-5">{t("settings.settings")}</p>
<p class="text-2xl">{title}</p>
<slot />

View file

@ -4,12 +4,14 @@
id="pagnation_input"
placeholder="..."
/>
<script is:inline data-astro-rerun>
document
.getElementById("pagnation_input")
.addEventListener("keyup", function (event) {
if (event.key === "Enter") {
window.location.href = document.getElementById("pagnation_input").value;
}
<script>
import { pageLoad } from "@utils/events";
pageLoad(() => {
const pagenationInput = document.getElementById('pagnation_input') as HTMLInputElement;
pagenationInput?.addEventListener("keyup", function (event) {
if (event.key === "Enter") {
window.location.href = pagenationInput?.value;
}
});
});
</script>

View file

@ -11,15 +11,13 @@ export const prerender = true;
<iframe id="chango" class="w-full h-full"></iframe>
</Layout>
<script>
import { initSw, loadProxyScripts, setTransport } from "@utils/registerSW.ts"; //../../utils/registerSW.ts
import { setTransport, getSWStuff } from "@utils/registerSW.ts"; //../../utils/registerSW.ts
import { Settings } from "@utils/settings/index";
import { pageLoad } from "@utils/events";
pageLoad(async () => {
const { conn } = getSWStuff();
const iframe = document.getElementById("chango") as HTMLIFrameElement;
const conn = await loadProxyScripts();
await setTransport(conn, localStorage.getItem(Settings.ProxySettings.transport) as string);
await initSw().then(() => {
if (iframe) return iframe.src = __uv$config!.prefix + __uv$config.encodeUrl!("https://radon.games");
});
if (iframe) return iframe.src = __uv$config!.prefix + __uv$config.encodeUrl!("https://radon.games");
});
</script>

View file

@ -3,11 +3,8 @@ import Logo from "@components/Logo.astro";
import Layout from "@layouts/Layout.astro";
import { getLangFromUrl, useTranslations } from "../../i18n/utils";
export function getStaticPaths() {
const STATIC_PATHS = [
{ params: { lang: "en_US" } },
{ params: { lang: "jp" } },
];
return STATIC_PATHS;
const STATIC_PATHS = [{ params: { lang: "en_US" } }, { params: { lang: "jp" } }];
return STATIC_PATHS;
}
export const prerender = true;
const lang = getLangFromUrl(Astro.url);
@ -115,6 +112,7 @@ import { VERSION } from "astro:env/client";
const iframe = document.getElementById("neb-iframe") as HTMLIFrameElement;
const omnibox = document.getElementById("omnibox") as HTMLDivElement;
const copyright = document.getElementById("version") as HTMLDivElement;
const client = new BareClient();
input?.addEventListener("keypress", async function (event: any) {
if (event.key === "Enter") {
copyright.classList.add("hidden");
@ -147,7 +145,6 @@ import { VERSION } from "astro:env/client";
omnibox.classList.add("hidden");
}
if (value.length >= 3) {
const client = new BareClient();
const data = await client.fetch(`https://api.duckduckgo.com/ac?q=${encodeURIComponent(value)}&format=json`);
const dataRes = await data.json();
const filteredData = dataRes.slice(0, 8); //Trim to only about 8 results. Any more and our omnibox dies

View file

@ -34,6 +34,7 @@ export const prerender = true;
{name: 'Japanese', value: 'jp', disabled: false},
]
}}
both={{enabled: false}}
/>
<SettingsCard
title="Proxy Catalog"
@ -47,7 +48,8 @@ export const prerender = true;
{name: 'False', value: 'false', disabled: false},
{name: 'True', value: 'true', disabled: false}
]
}}
}}
both={{enabled: false}}
/>
<SettingsCard
title="Catalog URL"
@ -59,6 +61,7 @@ export const prerender = true;
}}
button={{name: 'Change', id: 'setcataloghostname' }}
select={{select: false}}
both={{enabled: false}}
/>
</SettingsSection>
</SettingsLayout>

View file

@ -12,11 +12,8 @@ import { getLangFromUrl, useTranslations } from "../../../i18n/utils";
const lang = getLangFromUrl(Astro.url);
const t = useTranslations(lang);
export function getStaticPaths() {
const STATIC_PATHS = [
{ params: { lang: "en_US" } },
{ params: { lang: "jp" } },
];
return STATIC_PATHS;
const STATIC_PATHS = [{ params: { lang: "en_US" } }, { params: { lang: "jp" } }];
return STATIC_PATHS;
}
export const prerender = true;
import { MARKETPLACE_ENABLED } from "astro:env/client";
@ -44,7 +41,8 @@ import { MARKETPLACE_ENABLED } from "astro:env/client";
{ name: "Ultraviolet", value: "uv", disabled: false },
{ name: "Scramjet (COMING SOON)", value: "sj", disabled: true },
],
}}
}}
both={{enabled: false}}
/>
<SettingsCard
title="Open in"
@ -60,7 +58,8 @@ import { MARKETPLACE_ENABLED } from "astro:env/client";
{ name: "About:Blank", value: "a:b", disabled: false },
{ name: "Blob", value: "blob", disabled: false },
],
}}
}}
both={{enabled: false}}
/>
<SettingsCard
title="Search Engine"
@ -75,12 +74,13 @@ import { MARKETPLACE_ENABLED } from "astro:env/client";
{ name: "Google", value: "google", disabled: false },
{ name: "Bing", value: "bing", disabled: false },
],
}}
}}
both={{enabled: false}}
/>
<SettingsCard
title="Wisp Server"
description="Choose the wisp server you feel is the fastest"
input={{ input: false }}
input={{ input: true, required: false, placeholder: 'wss://nebulaproxy.io/wisp' }}
button={{ name: "Select", id: "setwispurl" }}
select={{
select: true,
@ -88,8 +88,13 @@ import { MARKETPLACE_ENABLED } from "astro:env/client";
options: [
{ name: "Default", value: "default", disabled: false },
{ name: "Ruby Network (US)", value: "ruby", disabled: false },
{ name: "Custom", value: "custom", disabled: false }
],
}}
}}
both={{
enabled: true,
showOnSelect: {value: 'custom'}
}}
/>
<SettingsCard
title="Transport"
@ -103,7 +108,8 @@ import { MARKETPLACE_ENABLED } from "astro:env/client";
{ name: "Libcurl", value: "libcurl", disabled: false },
{ name: "Epoxy", value: "epoxy", disabled: false },
],
}}
}}
both={{enabled: false}}
/>
</div>
</SettingsSection>
@ -163,7 +169,7 @@ import { MARKETPLACE_ENABLED } from "astro:env/client";
class: "wispUrlMessage",
}}
client:load
/>
/>
<Toast
toastProp={{
toastType: "success",
@ -183,7 +189,8 @@ import { MARKETPLACE_ENABLED } from "astro:env/client";
openInVal: HTMLSelectElement,
searchEngineVal: HTMLSelectElement,
wispServerVal: HTMLSelectElement,
transportVal: HTMLSelectElement
transportVal: HTMLSelectElement,
customUrl: HTMLInputElement
) {
proxySelectVal.value = localStorage.getItem(
SettingsEnum.ProxySettings.proxy
@ -194,48 +201,34 @@ import { MARKETPLACE_ENABLED } from "astro:env/client";
searchEngineVal.value = localStorage.getItem(
SettingsEnum.ProxySettings.searchEngine
) as string;
wispServerVal.value = localStorage.getItem(
SettingsEnum.ProxySettings.wispServerURL
) as string;
wispServerVal.value = localStorage.getItem(SettingsEnum.ProxySettings.wispServerURL) as string;
if (wispServerVal.value === "custom") {
customUrl.classList.remove("hidden");
customUrl.value = localStorage.getItem("customWispUrl") as string;
}
transportVal.value = localStorage.getItem(
SettingsEnum.ProxySettings.transport
) as string;
}
pageLoad(() => {
const proxyButton = document.getElementById(
"setproxy"
) as HTMLButtonElement;
const proxySelectVal = document.getElementById(
"proxy"
) as HTMLSelectElement;
const openInButton = document.getElementById(
"setopenin"
) as HTMLButtonElement;
const proxyButton = document.getElementById("setproxy") as HTMLButtonElement;
const proxySelectVal = document.getElementById("proxy") as HTMLSelectElement;
const openInButton = document.getElementById("setopenin") as HTMLButtonElement;
const openInVal = document.getElementById("openin") as HTMLSelectElement;
const searchEngineButton = document.getElementById(
"setsearchengine"
) as HTMLButtonElement;
const searchEngineVal = document.getElementById(
"searchengine"
) as HTMLSelectElement;
const wispServerButton = document.getElementById(
"setwispurl"
) as HTMLButtonElement;
const wispServerVal = document.getElementById(
"wispurl"
) as HTMLSelectElement;
const transportButton = document.getElementById(
"settransport"
) as HTMLButtonElement;
const transportVal = document.getElementById(
"transport"
) as HTMLSelectElement;
const searchEngineButton = document.getElementById("setsearchengine") as HTMLButtonElement;
const searchEngineVal = document.getElementById("searchengine") as HTMLSelectElement;
const wispServerButton = document.getElementById("setwispurl") as HTMLButtonElement;
const wispServerVal = document.getElementById("wispurl") as HTMLSelectElement;
const transportButton = document.getElementById("settransport") as HTMLButtonElement;
const transportVal = document.getElementById("transport") as HTMLSelectElement;
const customWispUrl = document.getElementById("inputOnSelectValuecustom") as HTMLInputElement;
setup(
proxySelectVal,
openInVal,
searchEngineVal,
wispServerVal,
transportVal
transportVal,
customWispUrl
);
proxyButton.addEventListener("click", () => {
settings.proxySettings.changeProxy(proxySelectVal.value);
@ -250,8 +243,23 @@ import { MARKETPLACE_ENABLED } from "astro:env/client";
toast(".searchEngineMessage");
});
wispServerButton.addEventListener("click", () => {
settings.proxySettings.setWispURL(wispServerVal.value);
toast(".wispUrlMessage");
if (wispServerVal.value === "custom") {
if (customWispUrl.classList.contains('hidden')) {
customWispUrl.classList.remove("hidden");
}
else {
localStorage.setItem("customWispUrl", customWispUrl.value);
settings.proxySettings.setWispURL(wispServerVal.value);
toast(".wispUrlMessage");
}
}
else {
if (!customWispUrl.classList.contains('hidden')) {
customWispUrl.classList.add("hidden");
}
settings.proxySettings.setWispURL(wispServerVal.value);
toast(".wispUrlMessage");
}
});
transportButton.addEventListener("click", () => {
settings.proxySettings.setTransport(transportVal.value);

View file

@ -32,6 +32,7 @@ export const prerender = true;
{name: 'Google Classroom', value: 'classroom', disabled: false},
{name: 'Powerschool', value: 'powerschool', disabled: false}
] }}
both={{enabled: false}}
/>
<SettingsCard
title="A:B & Blob"
@ -42,6 +43,7 @@ export const prerender = true;
{name: 'About:Blank', value: 'a:b', disabled: false},
{name: 'Blob', value: 'blob', disabled: false}
] }}
both={{enabled: false}}
/>
</div>
</SettingsSection>

View file

@ -32,6 +32,7 @@ function setTransport(conn: BareMuxConnection, transport?: string) {
//wrap in a promise so we don't register sw until a transport is set.
const wispServer = localStorage.getItem(Settings.ProxySettings.wispServerURL);
return new Promise<void>((resolve) => {
console.log(`Wisp server set: ${wispServer ? WispServerURLS[wispServer] : WispServerURLS.default}`)
switch (transport) {
case "epoxy":
conn.setTransport("/epoxy/index.mjs", [
@ -78,7 +79,7 @@ function getSWStuff(): SWStuff {
const stuff: SWStuff = {
sw: swReg,
conn: baremuxConn
}
};
return stuff;
}

View file

@ -17,31 +17,31 @@ interface SWPagePlugin extends Omit<Plug, "name" | "src"> {
type SWPluginFunction<T extends unknown> = (args: T) => void | unknown;
type Events =
"abortpayment" |
"activate" |
"backgroundfetchabort" |
"backgroundfetchclick" |
"backgroundfetchfail" |
"backgroundfetchsuccess" |
"canmakepayment" |
"contentdelete" |
"cookiechange" |
"fetch" |
"install" |
"message" |
"messageerror" |
"notificationclick" |
"notificationclose" |
"paymentrequest" |
"periodicsync" |
"push" |
"pushsubscriptionchange" |
"sync"
type Events =
| "abortpayment"
| "activate"
| "backgroundfetchabort"
| "backgroundfetchclick"
| "backgroundfetchfail"
| "backgroundfetchsuccess"
| "canmakepayment"
| "contentdelete"
| "cookiechange"
| "fetch"
| "install"
| "message"
| "messageerror"
| "notificationclick"
| "notificationclose"
| "paymentrequest"
| "periodicsync"
| "push"
| "pushsubscriptionchange"
| "sync";
interface SWPlugin extends Omit<Plug, "src"> {
function: string | SWPluginFunction<any>;
events: Events[]
events: Events[];
}
interface Package {
@ -53,4 +53,13 @@ interface Package {
plugin?: Plug;
}
export { type PluginType, type MarketplacePluginType, type PackageType, type Plug as Plugin, type SWPagePlugin, type SWPlugin, type Package, type SWPluginFunction }
export {
type PluginType,
type MarketplacePluginType,
type PackageType,
type Plug as Plugin,
type SWPagePlugin,
type SWPlugin,
type Package,
type SWPluginFunction
};

View file

@ -1,7 +1,7 @@
import { type SWPagePlugin, type SWPlugin, type SWPluginFunction as PluginFunction } from "./types";
import { type SWPluginFunction as PluginFunction, type SWPagePlugin, type SWPlugin } from "./types";
interface PagePlugin extends Omit<SWPagePlugin, "type"> {};
interface ServiceWorkerPlugin extends Omit<SWPlugin, "type"> {};
interface PagePlugin extends Omit<SWPagePlugin, "type"> {}
interface ServiceWorkerPlugin extends Omit<SWPlugin, "type"> {}
declare global {
function entryFunc(): PagePlugin | ServiceWorkerPlugin;

View file

@ -1,4 +1,11 @@
import { type PackageType, type Package, type PluginType, type Plugin, type SWPagePlugin, type SWPlugin } from "./marketplace/types";
import {
type Package,
type PackageType,
type Plugin,
type PluginType,
type SWPagePlugin,
type SWPlugin
} from "./marketplace/types";
const wispUrl = (location.protocol === "https:" ? "wss://" : "ws://") + location.host + "/wisp/";
type TabCloaks = "default" | "google" | "wikipedia" | "canvas" | "classroom" | "powerschool";
type AbCloaks = "a:b" | "blob";
@ -13,10 +20,10 @@ const SearchEngines: Record<string, string> = {
type SearchEngine = "ddg" | "google" | "bing";
const WispServerURLS: Record<string, string> = {
default: wispUrl,
ruby: "wss://ruby.rubynetwork.co/wisp/"
ruby: "wss://ruby.rubynetwork.co/wisp/",
custom: localStorage.getItem("customWispUrl") as string
};
export {
type TabCloaks,
type AbCloaks,