Merge pull request #235 from MotorTruck1221/bugfixes

Bugfixes
This commit is contained in:
rift 2024-03-21 15:28:37 -05:00 committed by GitHub
commit a46908389c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 966 additions and 393 deletions

5
.dockerignore Normal file
View file

@ -0,0 +1,5 @@
node_modules/
.vscode
npm-debug.log
yarn-error.log
.github/

14
Dockerfile Normal file
View file

@ -0,0 +1,14 @@
FROM node:21-alpine
WORKDIR /app
COPY package*.json .
COPY . .
RUN npm i -g pnpm
RUN pnpm install
RUN pnpm run build
EXPOSE 8080
CMD ["pnpm", "start"]

13
docker-compose.yml Normal file
View file

@ -0,0 +1,13 @@
version: "3"
services:
nebula:
image: nebula:latest
build:
context: .
dockerfile: Dockerfile
container_name: nebula
restart: unless-stopped
ports:
# Host:Container (DO NOT MODIFY THE CONTAINER PORT)
- "8081:8080"

View file

@ -4,12 +4,31 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="/epoxy/index.js" defer></script>
<script src="/libcurl/index.cjs" defer></script>
<script src="/libcurl/index.js" defer></script>
<script src="/transports/bareTransport.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>
if ("serviceWorker" in navigator) {
window.addEventListener("load", () => {
navigator.serviceWorker
.register("/sw.js", {
scope: "/~/"
})
.then(() => {
console.log("Service Worker Registered");
try {
window.setTransport();
} catch {}
})
.catch((err) => {
console.error("Service Worker Failed to Register", err);
});
});
}
</script>
</head>
<body style="margin: 0">
<div id="app"></div>
@ -22,10 +41,15 @@
window.location.href = window.location.href;
</script>
<script>
if (!localStorage["auth"] && new URL(document.all.rcheck.href).password) {
try {
if (
!localStorage["auth"] &&
new URL(document.all.rcheck.href).password
) {
window.location.reload();
localStorage["auth"] = 1;
}
} catch {}
</script>
</body>
</html>

View file

@ -16,7 +16,7 @@
"@fastify/static": "^6.12.0",
"@mercuryworkshop/bare-mux": "^1.0.5",
"@mercuryworkshop/epoxy-transport": "^1.1.0",
"@mercuryworkshop/libcurl-transport": "^1.2.1",
"@mercuryworkshop/libcurl-transport": "^1.2.4",
"@nebula-services/dynamic": "0.7.2-patch.2",
"@titaniumnetwork-dev/ultraviolet": "^3.0.0",
"@tomphttp/bare-server-node": "2.0.3",
@ -29,16 +29,16 @@
"compression": "^1.7.4",
"cookie-parser": "^1.4.6",
"crypto-js": "^4.2.0",
"express": "^4.18.3",
"express": "^4.19.1",
"fastify": "^4.26.2",
"framer-motion": "^10.18.0",
"i18next": "^23.10.1",
"i18next-browser-languagedetector": "^7.2.0",
"localforage": "^1.10.0",
"million": "^2.6.4",
"preact": "^10.19.6",
"preact": "^10.20.0",
"preact-iso": "^2.4.0",
"preact-render-to-string": "^6.4.0",
"preact-render-to-string": "^6.4.1",
"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",
@ -46,21 +46,21 @@
"react-icons": "^4.12.0",
"react-toastify": "^9.1.3",
"tsx": "^4.7.1",
"wisp-server-node": "^1.0.2",
"wisp-server-node": "^1.0.4",
"ws": "^8.16.0"
},
"devDependencies": {
"@preact/preset-vite": "^2.8.1",
"autoprefixer": "^10.4.18",
"@preact/preset-vite": "^2.8.2",
"autoprefixer": "^10.4.19",
"concurrently": "^8.2.2",
"eslint": "^8.57.0",
"eslint-config-preact": "^1.3.0",
"postcss": "^8.4.35",
"postcss": "^8.4.38",
"prettier": "^3.2.5",
"prettier-plugin-tailwindcss": "^0.5.12",
"tailwindcss": "^3.4.1",
"typescript": "^5.4.2",
"vite": "^5.1.5",
"typescript": "^5.4.3",
"vite": "^5.2.2",
"vite-plugin-static-copy": "^1.0.1"
}
}

1043
pnpm-lock.yaml generated

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
importScripts("/epoxy/index.js");
importScripts("/libcurl/index.cjs");
importScripts("/libcurl/index.js");
importScripts("/transports/bareTransport.js");
importScripts("/uv/uv.bundle.js");
importScripts("/uv/uv.config.js");

View file

@ -14,8 +14,8 @@ export function HeaderButton(props: HeaderButtonProps) {
return (
<Link href={href} className="flex h-full w-full bg-navbar-color sm:h-auto">
<div className="group flex w-full flex-row items-center justify-center border-t-2 border-solid border-navbar-text-color p-4 md:border-none">
<Icon className="h-10 w-10 text-text-color transition duration-500 group-hover:text-text-hover-color md:h-6 md:w-6" />
<span className="font-roboto pl-1 text-center text-4xl font-bold text-text-color transition duration-500 group-hover:text-text-hover-color md:text-lg">
<Icon className="h-6 w-6 text-text-color transition duration-500 group-hover:text-text-hover-color md:h-6 md:w-6" />
<span className="font-roboto pl-1 text-center text-3xl font-bold text-text-color transition duration-500 group-hover:text-text-hover-color md:text-lg">
{t(translationKey)}
</span>
</div>

View file

@ -8,6 +8,8 @@ import prod from "./config.json"; // Set prod to true if you wish to load balanc
import { enc } from "../aes";
import CloakedHead from "../util/CloakedHead";
import { useEffect } from "preact/hooks";
import { setTransport } from "../util/transports";
import { updateServiceWorkers } from "../util/SWHelper.js";
export function Home() {
const [isFocused, setIsFocused] = useState(false);
@ -18,6 +20,10 @@ export function Home() {
const handleLoad = () => {
const firstLoad = localStorage.getItem("firstLoad") || "true";
console.log(firstLoad);
//make sure service workers are updated
updateServiceWorkers();
//make sure transport is set
//setTransport();
if (firstLoad == "true" && prod) {
function changeBare(url: string) {
set("bare", url);
@ -86,6 +92,8 @@ export function Home() {
const handleSubmit = (event) => {
event.preventDefault();
//ensure transport is set
setTransport();
window.location.href =
"/go/" +
encodeURIComponent(

View file

@ -1,8 +1,11 @@
import { HeaderRoute } from "../components/HeaderRoute";
import { setTransport } from "../util/transports";
interface Window {
__uv$config: any;
}
export function Radon() {
//make sure there is a transport set
setTransport();
return (
<HeaderRoute>
<iframe

View file

@ -17,7 +17,7 @@ const CloakPreset = (props: Props) => {
return (
<div
onClick={cloak}
className="cursor-pointer rounded-full border border-input-border-color bg-lighter"
className="flex h-16 w-16 cursor-pointer rounded-full border border-input-border-color bg-lighter"
>
<img
src={props.faviconUrl === "none" ? "/logo.png" : props.faviconUrl}

View file

@ -4,8 +4,8 @@ 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";
import TransportDropdown from "./transportDropdown";
const Proxy = ({ id, active }) => {
const { t } = useTranslation();
@ -118,10 +118,10 @@ const Proxy = ({ id, active }) => {
<div className="text-md p-4 font-bold text-input-text">
Select the transport to use
</div>
<Dropdown
<TransportDropdown
storageKey="transport"
options={transports}
refresh={true}
refresh={false}
/>
</div>
</motion.div>

View file

@ -26,7 +26,7 @@ const TabSettings = ({ id, active }) => {
<div className="text-md pb-5 font-bold text-input-text">
{t("settings.cloaking.subtitle")}
</div>
<div className="flex flex-row space-x-4">
<div className="flex flex-row flex-wrap items-center justify-center gap-4">
<CloakPreset faviconUrl="none" title="none" />
<CloakPreset
faviconUrl="https://t1.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&url=http://google.com&size=32"

View file

@ -0,0 +1,80 @@
import { FaAngleDown } from "react-icons/fa";
import { useState, useEffect } from "preact/hooks";
import { changeTransport } from "../../util/transports.ts";
const wispUrl =
localStorage.getItem("wispUrl") ||
(location.protocol === "https:" ? "wss://" : "ws://") +
location.host +
"/wisp/";
interface Option {
id: string;
label: string; // Translations CAN be passed
}
const TransportDropdown = ({
storageKey,
options,
refresh
}: {
storageKey: string;
options: Option[];
refresh: boolean;
}) => {
const [isOpen, setIsOpen] = useState(false);
const [choice, setChoice] = useState(() => {
return localStorage.getItem(storageKey) || options[0]?.id || "";
});
// update on localstorage change
useEffect(() => {
setChoice(localStorage.getItem(storageKey) || options[0]?.id || "");
}, [storageKey, options]);
return (
<div className="relative text-center">
<div
className={`font-roboto flex h-14 w-56 cursor-pointer flex-col items-center justify-center border border-input-border-color bg-input text-center text-xl ${
isOpen ? "rounded-t-2xl" : "rounded-2xl"
}`}
onClick={() => setIsOpen(!isOpen)}
>
<div className="flex h-full w-full select-none flex-row items-center">
<div className="h-full w-1/4"></div>
<div className="flex w-2/4 flex-col items-center text-input-text">
{options.find((o) => o.id === choice)?.label}
</div>
<div className="flex w-1/4 flex-col items-center text-input-text">
<FaAngleDown />
</div>
</div>
{isOpen && (
<div className="absolute top-full w-full">
{options.map((option, index) => (
<div
key={option.id}
className={`border border-input-border-color bg-input p-2 text-input-text hover:bg-dropdown-option-hover-color ${
index === options.length - 1 ? "rounded-b-2xl" : ""
}`}
onClick={() => {
setIsOpen(false);
setChoice(option.id);
localStorage.setItem(storageKey, option.id);
changeTransport(option.id, wispUrl);
if (refresh === true) {
window.location.reload();
}
}}
>
{option.label}
</div>
))}
</div>
)}
</div>
</div>
);
};
export default TransportDropdown;

View file

@ -13,14 +13,16 @@ export function NotFound() {
originalFavicon="/logo.png"
/>
<section className="h-full">
<div className="flex h-full flex-col items-center justify-center">
<div className="flex h-full flex-col items-center justify-center text-center">
<img src="/404.png" className="h-72"></img>
<div className="flex flex-col items-center p-6">
<p className="font-roboto text-4xl font-bold">{t("404.text")}</p>
<span className="font-roboto text-3xl">404</span>
<p className="font-roboto text-4xl font-bold text-text-color">
{t("404.text")}
</p>
<span className="font-roboto text-3xl text-text-color">404</span>
</div>
<Link href="/">
<button className="font-roboto h-14 w-44 rounded-2xl border border-input-border-color bg-input p-2 text-center text-xl placeholder:text-input-text focus:outline-none">
<button className="font-roboto h-14 w-44 rounded-2xl border border-input-border-color bg-input p-2 text-center text-xl text-text-color placeholder:text-input-text focus:outline-none">
{t("404.return")}
</button>
</Link>

View file

@ -7,23 +7,25 @@ import { Radon } from "./pages/Radon";
import { Settings } from "./pages/Settings/";
import { AboutBlank } from "./AboutBlank";
import { Faq } from "./pages/Faq";
//import { setTransport } from "./util/transports.js";
import "./style.css";
import "./i18n";
import { setTransport } from "./util/transports";
export default function Routes() {
if ("serviceWorker" in navigator) {
window.addEventListener("load", () => {
navigator.serviceWorker
.register("/sw.js", {
scope: "/~/"
})
.then(() => {
console.log("Service worker registered successfully");
});
});
}
//if ("serviceWorker" in navigator) {
//window.addEventListener("load", () => {
// navigator.serviceWorker
// .register("/sw.js", {
// scope: "/~/"
// })
// .then(() => {
// console.log("Service worker registered successfully");
// setTransport();
// });
//});
//}
return (
<LocationProvider>
<Router>

View file

@ -1,3 +1,5 @@
import { setTransport } from "./transports.ts";
function updateServiceWorkers() {
navigator.serviceWorker.getRegistrations().then(function (registrations) {
for (let registration of registrations) {
@ -16,4 +18,17 @@ function uninstallServiceWorkers() {
});
}
export { updateServiceWorkers, uninstallServiceWorkers };
function registerServiceWorker() {
if ("serviceWorker" in navigator) {
navigator.serviceWorker
.register("/sw.js", {
scope: "/~/"
})
.then(() => {
console.log("Service worker registered successfully");
setTransport();
});
}
}
export { updateServiceWorkers, uninstallServiceWorkers, registerServiceWorker };

View file

@ -2,6 +2,13 @@ import {
SetTransport,
registerRemoteListener
} from "@mercuryworkshop/bare-mux";
//import { isIOS } from "./IosDetector";
declare global {
interface Window {
setTransport: () => void;
}
}
function changeTransport(transport: string, wispUrl: string) {
switch (transport) {
@ -15,7 +22,7 @@ function changeTransport(transport: string, wispUrl: string) {
console.log("Setting transport to Libcurl");
SetTransport("CurlMod.LibcurlClient", {
wisp: wispUrl,
wasm: "https://cdn.jsdelivr.net/npm/libcurl.js@v0.5.2/libcurl.wasm"
wasm: "https://cdn.jsdelivr.net/npm/libcurl.js@v0.5.3/libcurl.wasm"
});
break;
case "bare":
@ -29,7 +36,7 @@ function changeTransport(transport: string, wispUrl: string) {
default:
SetTransport("CurlMod.LibcurlClient", {
wisp: wispUrl,
wasm: "/libcurl.wasm"
wasm: "https://cdn.jsdelivr.net/npm/libcurl.js@v0.5.3/libcurl.wasm"
});
break;
}
@ -45,10 +52,32 @@ const wispUrl =
"/wisp/";
registerRemoteListener(navigator.serviceWorker.controller!);
//if (isIOS) {
// console.log("iOS device detected. Bare will be used.");
// changeTransport(
// localStorage.getItem("transport") || "libcurl",
// localStorage.getItem("wispUrl") || wispUrl
// );
//} else {
// changeTransport(
// localStorage.getItem("transport") || "bare",
// localStorage.getItem("wispUrl") || wispUrl
// );
//}
//changeTransport(
// localStorage.getItem("transport") || "libcurl",
// localStorage.getItem("wispUrl") || wispUrl
//);
// helper function for ../routes.tsx
function setTransport() {
changeTransport(
localStorage.getItem("transport") || "libcurl",
localStorage.getItem("wispUrl") || wispUrl
);
}
export { changeTransport, getTransport };
window.setTransport = setTransport;
export { changeTransport, getTransport, setTransport };

View file

@ -7,6 +7,9 @@ import { dynamicPath } from "@nebula-services/dynamic";
import { epoxyPath } from "@mercuryworkshop/epoxy-transport";
import { libcurlPath } from "@mercuryworkshop/libcurl-transport";
import path from "path";
import { createBareServer } from "@tomphttp/bare-server-node";
import wisp from "wisp-server-node";
import http from "http";
const __dirname = path.resolve();
export default defineConfig({
@ -48,10 +51,16 @@ export default defineConfig({
],
server: {
proxy: {
"/bare": {
"/bare/": {
target: "http://localhost:8080/",
changeOrigin: true,
rewrite: (path) => path.replace(/^\/bare/, "")
rewrite: (path) => path.replace(/^\/bare\//, "")
},
"/wisp/": {
target: "http://ruby.rubynetwork.co/wisp/",
changeOrigin: true,
ws: true,
rewrite: (path) => path.replace(/^\/wisp\//, "")
}
}
}