commit
6c1ce96036
16 changed files with 2033 additions and 1809 deletions
|
|
@ -3,11 +3,12 @@
|
|||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<script src="/epoxy/index.js" defer></script>
|
||||
<script src="/uv/uv.bundle.js" defer></script>
|
||||
<script src="/uv/uv.config.js" defer></script>
|
||||
<script src="/dynamic/dynamic.config.js" defer></script>
|
||||
<script src="/localforage/localforage.min.js" defer></script>
|
||||
<script>
|
||||
<script defer>
|
||||
if ("serviceWorker" in navigator) {
|
||||
window.addEventListener("load", () => {
|
||||
navigator.serviceWorker.register("/sw.js", {
|
||||
|
|
@ -27,11 +28,13 @@
|
|||
)
|
||||
window.location.href = window.location.href;
|
||||
</script>
|
||||
<!-- ONLY ENABLE IF USING MASQR!
|
||||
<script>
|
||||
if (!localStorage["auth"] && new URL(document.all.rcheck.href).password) {
|
||||
window.location.reload();
|
||||
localStorage["auth"] = 1;
|
||||
}
|
||||
</script>
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
44
package.json
44
package.json
|
|
@ -14,45 +14,49 @@
|
|||
"@fastify/compress": "^6.5.0",
|
||||
"@fastify/cookie": "^9.3.1",
|
||||
"@fastify/static": "^6.12.0",
|
||||
"@mercuryworkshop/bare-mux": "^1.0.4",
|
||||
"@mercuryworkshop/epoxy-transport": "^1.0.2",
|
||||
"@nebula-services/bare-server-node": "2.0.1-patch.1",
|
||||
"@nebula-services/dynamic": "0.7.2-patch.2",
|
||||
"@nebula-services/ultraviolet": "1.0.1-1.patch.7",
|
||||
"@titaniumnetwork-dev/ultraviolet": "^3.0.0",
|
||||
"@types/express": "^4.17.21",
|
||||
"chalk": "^5.3.0",
|
||||
"classnames": "^2.3.2",
|
||||
"classnames": "^2.5.1",
|
||||
"compression": "^1.7.4",
|
||||
"cookie-parser": "^1.4.6",
|
||||
"crypto-js": "^4.2.0",
|
||||
"express": "^4.18.2",
|
||||
"fastify": "^4.25.1",
|
||||
"framer-motion": "^10.16.16",
|
||||
"i18next": "^23.7.9",
|
||||
"express": "^4.18.3",
|
||||
"fastify": "^4.26.2",
|
||||
"framer-motion": "^10.18.0",
|
||||
"i18next": "^23.10.0",
|
||||
"i18next-browser-languagedetector": "^7.2.0",
|
||||
"localforage": "^1.10.0",
|
||||
"million": "^2.6.4",
|
||||
"preact": "^10.13.1",
|
||||
"preact-iso": "^2.3.2",
|
||||
"preact-render-to-string": "^6.3.1",
|
||||
"preact": "^10.19.6",
|
||||
"preact-iso": "^2.4.0",
|
||||
"preact-render-to-string": "^6.4.0",
|
||||
"preact-router": "^4.1.2",
|
||||
"rammerhead": "https://github.com/NebulaServices/rammerhead/releases/download/rammerhead-1.2.41-nebula.8/rammerhead-1.2.41-nebula.7.tgz",
|
||||
"react-helmet": "^6.1.0",
|
||||
"react-i18next": "^13.5.0",
|
||||
"react-icons": "^4.12.0",
|
||||
"react-toastify": "^9.1.3",
|
||||
"tsx": "^4.7.0",
|
||||
"wisp-server-node": "^1.0.1"
|
||||
"tsx": "^4.7.1",
|
||||
"wisp-server-node": "^1.0.1",
|
||||
"ws": "^8.16.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@preact/preset-vite": "^2.5.0",
|
||||
"autoprefixer": "^10.4.16",
|
||||
"@preact/preset-vite": "^2.8.1",
|
||||
"autoprefixer": "^10.4.18",
|
||||
"concurrently": "^8.2.2",
|
||||
"eslint": "^8.55.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-preact": "^1.3.0",
|
||||
"postcss": "^8.4.32",
|
||||
"prettier": "^3.1.1",
|
||||
"prettier-plugin-tailwindcss": "^0.5.9",
|
||||
"tailwindcss": "^3.3.6",
|
||||
"postcss": "^8.4.35",
|
||||
"prettier": "^3.2.5",
|
||||
"prettier-plugin-tailwindcss": "^0.5.11",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"typescript": "^5.3.3",
|
||||
"vite": "^5.0.9",
|
||||
"vite-plugin-static-copy": "^1.0.0"
|
||||
"vite": "^5.1.4",
|
||||
"vite-plugin-static-copy": "^1.0.1"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
2816
pnpm-lock.yaml
generated
2816
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,3 +1,4 @@
|
|||
importScripts("/epoxy/index.js");
|
||||
importScripts("/uv/uv.bundle.js");
|
||||
importScripts("/uv/uv.config.js");
|
||||
importScripts(__uv$config.sw || "/uv/uv.sw.js");
|
||||
|
|
|
|||
19
server.ts
19
server.ts
|
|
@ -9,7 +9,8 @@ import path from "path";
|
|||
import fs from "fs";
|
||||
import cookieParser from "cookie-parser";
|
||||
import wisp from "wisp-server-node";
|
||||
import { Socket } from "net";
|
||||
import { Request, Response } from "express";
|
||||
import { Socket, Head } from "ws";
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
|
@ -47,7 +48,7 @@ app.use(
|
|||
app.use(cookieParser());
|
||||
|
||||
// Congratulations! Masqr failed to validate, this is either your first visit or you're a FRAUD
|
||||
async function MasqFail(req, res) {
|
||||
async function MasqFail(req: Request, res: Response) {
|
||||
if (!req.headers.host) {
|
||||
// no bitch still using HTTP/1.0 go away
|
||||
return;
|
||||
|
|
@ -124,7 +125,7 @@ async function MasqFail(req, res) {
|
|||
|
||||
app.use(express.static("dist"));
|
||||
|
||||
app.get("/search=:query", async (req, res) => {
|
||||
app.get("/search=:query", async (req: Request, res: Response) => {
|
||||
const { query } = req.params;
|
||||
|
||||
const response = await fetch(
|
||||
|
|
@ -142,7 +143,7 @@ const server = createServer();
|
|||
|
||||
const bare = createBareServer("/bare/");
|
||||
|
||||
server.on("request", (req, res) => {
|
||||
server.on("request", (req: Request, res: Response) => {
|
||||
if (bare.shouldRoute(req)) {
|
||||
bare.routeRequest(req, res);
|
||||
} else if (shouldRouteRh(req)) {
|
||||
|
|
@ -152,13 +153,13 @@ server.on("request", (req, res) => {
|
|||
}
|
||||
});
|
||||
|
||||
server.on("upgrade", (req, socket, head) => {
|
||||
server.on("upgrade", (req: Request, socket: Socket, head: Head) => {
|
||||
if (bare.shouldRoute(req)) {
|
||||
bare.routeUpgrade(req, socket, head);
|
||||
} else if (shouldRouteRh(req)) {
|
||||
routeRhUpgrade(req, socket, head);
|
||||
} else {
|
||||
wisp.routeRequest(req, socket as Socket, head);
|
||||
} else if (req.url.endsWith("/wisp/")) {
|
||||
wisp.routeRequest(req, socket, head);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -170,11 +171,11 @@ function shouldRouteRh(req) {
|
|||
);
|
||||
}
|
||||
|
||||
function routeRhRequest(req, res) {
|
||||
function routeRhRequest(req: Request, res: Response) {
|
||||
rh.emit("request", req, res);
|
||||
}
|
||||
|
||||
function routeRhUpgrade(req, socket, head) {
|
||||
function routeRhUpgrade(req: Request, socket: Socket, head: Head) {
|
||||
rh.emit("upgrade", req, socket, head);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@ import { motion } from "framer-motion";
|
|||
import { tabContentVariant, settingsPageVariant } from "./Variants";
|
||||
import Dropdown from "./Dropdown";
|
||||
import BareInput from "./BareInput";
|
||||
import WispInput from "./WispInput";
|
||||
import ProxyInput from "./ProxyInput";
|
||||
import { changeTransport } from "../../util/transports";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const Proxy = ({ id, active }) => {
|
||||
|
|
@ -27,6 +29,13 @@ const Proxy = ({ id, active }) => {
|
|||
{ id: "https://bing.com/search?q=%s", label: "Bing" }
|
||||
];
|
||||
|
||||
const wispUrl =
|
||||
(location.protocol === "https:" ? "wss://" : "ws://") +
|
||||
location.host +
|
||||
"/wisp/";
|
||||
//libcurl can be added here when it's stable
|
||||
const transports = [{ id: "epoxy", label: "Epoxy" }];
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
role="tabpanel"
|
||||
|
|
@ -84,6 +93,29 @@ const Proxy = ({ id, active }) => {
|
|||
</div>
|
||||
<BareInput placeholder="/bare/" storageKey="bare" />
|
||||
</div>
|
||||
<div className="flex h-64 w-80 flex-col flex-wrap content-center items-center rounded-lg border border-input-border-color bg-lighter p-2 text-center">
|
||||
<div className="p-2 text-3xl font-bold text-input-text">
|
||||
Wisp Server
|
||||
</div>
|
||||
<div className="text-md p-4 font-bold text-input-text">
|
||||
Enter the url of a Wisp server
|
||||
</div>
|
||||
<WispInput placeholder={wispUrl} />
|
||||
</div>
|
||||
<div className="flex h-64 w-80 flex-col flex-wrap content-center items-center rounded-lg border border-input-border-color bg-lighter p-2 text-center">
|
||||
<div className="p-2 text-3xl font-bold text-input-text">
|
||||
Transport
|
||||
</div>
|
||||
<div className="text-md p-4 font-bold text-input-text">
|
||||
Select the transport to use
|
||||
</div>
|
||||
<Dropdown
|
||||
storageKey="transport"
|
||||
options={transports}
|
||||
refresh={false}
|
||||
onChange={(value) => changeTransport(value, wispUrl)}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex h-96 w-96 flex-col flex-wrap content-center items-center rounded-lg border border-input-border-color bg-lighter p-2 text-center">
|
||||
<div className="p-2 text-3xl font-bold text-input-text">
|
||||
{t("settings.httpProxy.title")}
|
||||
|
|
|
|||
66
src/pages/Settings/WispInput.tsx
Normal file
66
src/pages/Settings/WispInput.tsx
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
import { useState, useEffect } from "preact/hooks";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { changeTransport } from "../../util/transports";
|
||||
import { ToastContainer, toast } from "react-toastify";
|
||||
|
||||
interface WispInputProps {
|
||||
placeholder: string;
|
||||
}
|
||||
|
||||
function WispInput(props: WispInputProps) {
|
||||
const { t } = useTranslation();
|
||||
const value =
|
||||
localStorage.getItem("wispUrl") ||
|
||||
(location.protocol === "https:" ? "wss://" : "ws://") +
|
||||
location.host +
|
||||
"/wisp/";
|
||||
const [inputValue, setInputValue] = useState(value);
|
||||
function validateUrl(url: string) {
|
||||
let finalUrl = url;
|
||||
if (finalUrl.startsWith("http://")) {
|
||||
finalUrl = finalUrl.replace("http://", "ws://");
|
||||
} else if (finalUrl.startsWith("https://")) {
|
||||
finalUrl = finalUrl.replace("https://", "wss://");
|
||||
} else if (finalUrl === "" || finalUrl === null || finalUrl === undefined) {
|
||||
finalUrl =
|
||||
(location.protocol === "https:" ? "wss://" : "ws://") +
|
||||
location.host +
|
||||
"/wisp/";
|
||||
}
|
||||
return finalUrl;
|
||||
}
|
||||
function handleChange() {
|
||||
const url = validateUrl(
|
||||
(document.getElementById("wispinput") as HTMLInputElement).value
|
||||
);
|
||||
localStorage.setItem("wispUrl", url);
|
||||
changeTransport(localStorage.getItem("transport") || "epoxy", url);
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<ToastContainer position="bottom-right" theme="dark" />
|
||||
<div className="flex flex-col items-center">
|
||||
<input
|
||||
type="text"
|
||||
placeholder={props.placeholder}
|
||||
value={inputValue}
|
||||
onKeyPress={(event) => {
|
||||
if (event.key === "Enter") {
|
||||
handleChange();
|
||||
}
|
||||
}}
|
||||
id="wispinput"
|
||||
className="font-roboto flex h-14 w-56 flex-row rounded-2xl border border-input-border-color bg-input p-4 text-center text-xl text-input-text"
|
||||
/>
|
||||
<div
|
||||
className="font-roboto mt-2 flex h-4 w-36 cursor-pointer flex-row items-center justify-center rounded-xl border border-input-border-color bg-input p-5 text-center text-lg text-input-text"
|
||||
onClick={handleChange}
|
||||
>
|
||||
Select
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default WispInput;
|
||||
54
src/util/transports.ts
Normal file
54
src/util/transports.ts
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
import {
|
||||
SetTransport,
|
||||
registerRemoteListener
|
||||
} from "@mercuryworkshop/bare-mux";
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
BareMux: any;
|
||||
p: any;
|
||||
}
|
||||
}
|
||||
|
||||
function changeTransport(transport: string, wispUrl: string) {
|
||||
switch (transport) {
|
||||
case "epoxy":
|
||||
localStorage.setItem("transport", "epoxy");
|
||||
SetTransport("EpxMod.EpoxyClient", { wisp: wispUrl });
|
||||
break;
|
||||
//libcurl when supported can be easily added here
|
||||
//and stuff like bare-as-module3 COULD also be added
|
||||
default:
|
||||
SetTransport("EpxMod.EpoxyClient", { wisp: wispUrl });
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function getTransport() {
|
||||
return localStorage.getItem("transport") || "epoxy";
|
||||
}
|
||||
|
||||
function restartTransport() {
|
||||
changeTransport(
|
||||
getTransport(),
|
||||
localStorage.getItem("wispUrl") ||
|
||||
(location.protocol === "https:" ? "wss://" : "ws://") +
|
||||
location.host +
|
||||
"/wisp/"
|
||||
);
|
||||
}
|
||||
|
||||
//restart transport every minute
|
||||
setInterval(restartTransport, 60000); //60000ms = 60s = 1m
|
||||
|
||||
const wispUrl =
|
||||
(location.protocol === "https:" ? "wss://" : "ws://") +
|
||||
location.host +
|
||||
"/wisp/";
|
||||
registerRemoteListener(navigator.serviceWorker.controller!);
|
||||
changeTransport(
|
||||
localStorage.getItem("transport") || "epoxy",
|
||||
localStorage.getItem("wispUrl") || wispUrl
|
||||
);
|
||||
|
||||
export { changeTransport, getTransport };
|
||||
|
|
@ -2,23 +2,34 @@ import million from "million/compiler";
|
|||
import { defineConfig } from "vite";
|
||||
import preact from "@preact/preset-vite";
|
||||
import { viteStaticCopy } from "vite-plugin-static-copy";
|
||||
import { uvPath } from "@nebula-services/ultraviolet";
|
||||
import { uvPath } from "@titaniumnetwork-dev/ultraviolet";
|
||||
import { dynamicPath } from "@nebula-services/dynamic";
|
||||
import { epoxyPath } from "@mercuryworkshop/epoxy-transport";
|
||||
import { baremuxPath } from "@mercuryworkshop/bare-mux";
|
||||
import path from "path";
|
||||
const __dirname = path.resolve();
|
||||
|
||||
console.log(dynamicPath);
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
viteStaticCopy({
|
||||
targets: [
|
||||
{
|
||||
// .replace fixes weird paths on Windows
|
||||
src: `${uvPath}/uv.*.js`.replace(/\\/g, "/"),
|
||||
src: `${uvPath}/**/*`.replace(/\\/g, "/"),
|
||||
dest: "uv",
|
||||
overwrite: false
|
||||
},
|
||||
//{
|
||||
// src: `${baremuxPath}/**/*`.replace(/\\/g, "/"),
|
||||
// dest: "mux",
|
||||
// overwrite: false
|
||||
//},
|
||||
{
|
||||
//include ALL files types
|
||||
src: `${epoxyPath}/**/*`,
|
||||
dest: "epoxy",
|
||||
overwrite: false
|
||||
},
|
||||
{
|
||||
// .replace fixes weird paths on Windows
|
||||
src: `${dynamicPath}/dynamic.*.js`.replace(/\\/g, "/"),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue