diff --git a/masqr.js b/masqr.js index 04106e3..773d413 100644 --- a/masqr.js +++ b/masqr.js @@ -1,61 +1,75 @@ -import fp from 'fastify-plugin' -import fs from 'fs'; -const failureFile = fs.readFileSync("Checkfailed.html", "utf8"); -const LICENSE_SERVER_URL = "https://license.mercurywork.shop/validate?license="; -const whiteListedDomain = ["nebulaproxy.io"]; -async function licenseCheck(req, pass) { - try { - const resp = await fetch(`${LICENSE_SERVER_URL}${pass}&host=${req.headers.host}`); - const data = await resp.json(); - if (data.status === "License valid") { - return true; - } - else { - return false; - } - } catch { return false; } -} -const plugin = (fastify, opts, done) => { - fastify.addHook('onRequest', function (req, reply, next) { - if (req.cookies.authcheck === 'true' || whiteListedDomain.includes(req.headers.host)) { - return next(); - } - const authHeader = req.headers.authorization; - if (req.cookies.refreshcheck != "true") { - reply - .setCookie('refreshcheck', 'true', { maxAge: 1000 }) - .type("text/html") - .send(failureFile); - return; - } - if (!authHeader) { - reply - .code(401) - .header('WWW-Authenticate', 'Basic') - .type("text/html") - .send(failureFile); - return; - } - const auth = Buffer.from(authHeader.split(" ")[1], "base64").toString().split(":"); - const user = auth[0]; - const pass = auth[1]; - licenseCheck(req, pass).then((data) => { - if (!data) { - reply.status(401).header('WWW-Authenticate', 'Basic').type("text/html").send(failureFile); - return; - } - else { - reply.setCookie('authcheck', 'true').type("text/html").send('') - return; - } - }); - }); - done(); -}; - -const masqr = fp(plugin, { - fastify: '4.x', - name: 'masqr' -}); - -export default masqr; +import fp from "fastify-plugin"; +import fs from "fs"; +const failureFile = fs.readFileSync("Checkfailed.html", "utf8"); +const LICENSE_SERVER_URL = "https://license.mercurywork.shop/validate?license="; +const whiteListedDomain = ["nebulaproxy.io"]; +async function licenseCheck(req, pass) { + try { + const resp = await fetch( + `${LICENSE_SERVER_URL}${pass}&host=${req.headers.host}` + ); + const data = await resp.json(); + if (data.status === "License valid") { + return true; + } else { + return false; + } + } catch { + return false; + } +} +const plugin = (fastify, opts, done) => { + fastify.addHook("onRequest", function (req, reply, next) { + if ( + req.cookies.authcheck === "true" || + whiteListedDomain.includes(req.headers.host) + ) { + return next(); + } + const authHeader = req.headers.authorization; + if (req.cookies.refreshcheck != "true") { + reply + .setCookie("refreshcheck", "true", { maxAge: 1000 }) + .type("text/html") + .send(failureFile); + return; + } + if (!authHeader) { + reply + .code(401) + .header("WWW-Authenticate", "Basic") + .type("text/html") + .send(failureFile); + return; + } + const auth = Buffer.from(authHeader.split(" ")[1], "base64") + .toString() + .split(":"); + const user = auth[0]; + const pass = auth[1]; + licenseCheck(req, pass).then((data) => { + if (!data) { + reply + .status(401) + .header("WWW-Authenticate", "Basic") + .type("text/html") + .send(failureFile); + return; + } else { + reply + .setCookie("authcheck", "true") + .type("text/html") + .send(""); + return; + } + }); + }); + done(); +}; + +const masqr = fp(plugin, { + fastify: "4.x", + name: "masqr" +}); + +export default masqr; diff --git a/package.json b/package.json index 65d61fc..0f79345 100644 --- a/package.json +++ b/package.json @@ -1,67 +1,67 @@ -{ - "name": "nebula", - "private": true, - "type": "module", - "scripts": { - "dev": "concurrently \"vite\" \"bare-server-node --port 8080\"", - "build": "vite build", - "bstart": "npm run build && tsx server.ts", - "start": "tsx server.ts", - "preview": "vite preview", - "format": "prettier --write ." - }, - "dependencies": { - "@fastify/compress": "^6.5.0", - "@fastify/cookie": "^9.3.1", - "@fastify/static": "^6.12.0", - "@mercuryworkshop/bare-mux": "^1.0.5", - "@mercuryworkshop/epoxy-transport": "^1.1.0", - "@mercuryworkshop/libcurl-transport": "^1.3.1", - "@nebula-services/dynamic": "0.7.2-patch.2", - "@titaniumnetwork-dev/ultraviolet": "^3.0.0", - "@tomphttp/bare-server-node": "2.0.3", - "@tsparticles/engine": "^3.3.0", - "@tsparticles/react": "^3.0.0", - "@tsparticles/slim": "^3.3.0", - "@types/express": "^4.17.21", - "chalk": "^5.3.0", - "classnames": "^2.5.1", - "compression": "^1.7.4", - "cookie-parser": "^1.4.6", - "crypto-js": "^4.2.0", - "express": "^4.19.1", - "fastify": "^4.26.2", - "fastify-plugin": "^4.5.1", - "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.20.0", - "preact-iso": "^2.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", - "react-i18next": "^13.5.0", - "react-icons": "^4.12.0", - "react-toastify": "^9.1.3", - "tsx": "^4.7.1", - "wisp-server-node": "^1.0.4", - "ws": "^8.16.0" - }, - "devDependencies": { - "@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.38", - "prettier": "^3.2.5", - "prettier-plugin-tailwindcss": "^0.5.12", - "tailwindcss": "^3.4.1", - "typescript": "^5.4.3", - "vite": "^5.2.3", - "vite-plugin-static-copy": "^1.0.1" - } -} +{ + "name": "nebula", + "private": true, + "type": "module", + "scripts": { + "dev": "concurrently \"vite\" \"bare-server-node --port 8080\"", + "build": "vite build", + "bstart": "npm run build && tsx server.ts", + "start": "tsx server.ts", + "preview": "vite preview", + "format": "prettier --write ." + }, + "dependencies": { + "@fastify/compress": "^6.5.0", + "@fastify/cookie": "^9.3.1", + "@fastify/static": "^6.12.0", + "@mercuryworkshop/bare-mux": "^1.0.5", + "@mercuryworkshop/epoxy-transport": "^1.1.0", + "@mercuryworkshop/libcurl-transport": "^1.3.1", + "@nebula-services/dynamic": "0.7.2-patch.2", + "@titaniumnetwork-dev/ultraviolet": "^3.0.0", + "@tomphttp/bare-server-node": "2.0.3", + "@tsparticles/engine": "^3.3.0", + "@tsparticles/react": "^3.0.0", + "@tsparticles/slim": "^3.3.0", + "@types/express": "^4.17.21", + "chalk": "^5.3.0", + "classnames": "^2.5.1", + "compression": "^1.7.4", + "cookie-parser": "^1.4.6", + "crypto-js": "^4.2.0", + "express": "^4.19.1", + "fastify": "^4.26.2", + "fastify-plugin": "^4.5.1", + "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.20.0", + "preact-iso": "^2.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", + "react-i18next": "^13.5.0", + "react-icons": "^4.12.0", + "react-toastify": "^9.1.3", + "tsx": "^4.7.1", + "wisp-server-node": "^1.0.4", + "ws": "^8.16.0" + }, + "devDependencies": { + "@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.38", + "prettier": "^3.2.5", + "prettier-plugin-tailwindcss": "^0.5.12", + "tailwindcss": "^3.4.1", + "typescript": "^5.4.3", + "vite": "^5.2.3", + "vite-plugin-static-copy": "^1.0.1" + } +} diff --git a/server.ts b/server.ts index c4d99f0..5641ca7 100644 --- a/server.ts +++ b/server.ts @@ -1,111 +1,115 @@ -import fastify from "fastify"; -import fastifyStatic from "@fastify/static"; -import { fileURLToPath } from "url"; -import path from "path"; -import fs from "fs"; -import cookieParser from "@fastify/cookie"; -import { createServer } from "http"; -import { createBareServer } from "@tomphttp/bare-server-node"; -import createRammerhead from "rammerhead/src/server/index.js"; -import wisp from "wisp-server-node"; -import { Socket } from "net"; -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); -const bare = createBareServer("/bare/"); -const rh = createRammerhead(); -import chalk from "chalk"; -import masqr from './masqr.js'; - -const rammerheadScopes = [ - "/rammerhead.js", - "/hammerhead.js", - "/transport-worker.js", - "/task.js", - "/iframe-task.js", - "/worker-hammerhead.js", - "/messaging", - "/sessionexists", - "/deletesession", - "/newsession", - "/editsession", - "/needpassword", - "/syncLocalStorage", - "/api/shuffleDict", - "/mainport" -]; - -const rammerheadSession = /^\/[a-z0-9]{32}/; - -function shouldRouteRh(req) { - const url = new URL(req.url, "http://0.0.0.0"); - return ( - rammerheadScopes.includes(url.pathname) || - rammerheadSession.test(url.pathname) - ); -} - -function routeRhRequest(req, res) { - rh.emit("request", req, res); -} - -function routeRhUpgrade(req, socket, head) { - rh.emit("upgrade", req, socket, head); -} - -const serverFactory = (handler, opts) => { - return createServer() - .on("request", (req, res) => { - if (bare.shouldRoute(req)) { - bare.routeRequest(req, res); - } else if (shouldRouteRh(req)) { - routeRhRequest(req, res); - } else { - handler(req, res); - } - }) - .on("upgrade", (req, socket, head) => { - if (bare.shouldRoute(req)) { - bare.routeUpgrade(req, socket, head); - } else if (shouldRouteRh(req)) { - routeRhUpgrade(req, socket, head); - } else if (req.url.endsWith("/wisp/")) { - wisp.routeRequest(req, socket as Socket, head); - } - }); -}; - -const app = fastify({ logger: false, serverFactory }); - -app.register(cookieParser); -await app.register(import("@fastify/compress")); -//Uncomment the following line to enable masqr -//app.register(masqr); - -app.register(fastifyStatic, { - root: path.join(__dirname, "dist"), - prefix: "/", - serve: true, - wildcard: false -}); - -app.get("/search=:query", async (req, res) => { - const { query } = req.params as { query: string }; // Define the type for req.params - - const response = await fetch( - `http://api.duckduckgo.com/ac?q=${query}&format=json` - ).then((apiRes) => apiRes.json()); - - res.send(response); -}); - -app.setNotFoundHandler((req, res) => { - res.sendFile("index.html"); // SPA catch-all -}); - -console.log(chalk.green(`Server listening on ${chalk.bold("http://localhost:8080")}`)); -console.log(chalk.magenta(`Server also listening on ${chalk.bold("http://0.0.0.0:8080")}`)); - -app.listen({ - port: 8080, - host: "0.0.0.0" -}); +import fastify from "fastify"; +import fastifyStatic from "@fastify/static"; +import { fileURLToPath } from "url"; +import path from "path"; +import fs from "fs"; +import cookieParser from "@fastify/cookie"; +import { createServer } from "http"; +import { createBareServer } from "@tomphttp/bare-server-node"; +import createRammerhead from "rammerhead/src/server/index.js"; +import wisp from "wisp-server-node"; +import { Socket } from "net"; +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const bare = createBareServer("/bare/"); +const rh = createRammerhead(); +import chalk from "chalk"; +import masqr from "./masqr.js"; + +const rammerheadScopes = [ + "/rammerhead.js", + "/hammerhead.js", + "/transport-worker.js", + "/task.js", + "/iframe-task.js", + "/worker-hammerhead.js", + "/messaging", + "/sessionexists", + "/deletesession", + "/newsession", + "/editsession", + "/needpassword", + "/syncLocalStorage", + "/api/shuffleDict", + "/mainport" +]; + +const rammerheadSession = /^\/[a-z0-9]{32}/; + +function shouldRouteRh(req) { + const url = new URL(req.url, "http://0.0.0.0"); + return ( + rammerheadScopes.includes(url.pathname) || + rammerheadSession.test(url.pathname) + ); +} + +function routeRhRequest(req, res) { + rh.emit("request", req, res); +} + +function routeRhUpgrade(req, socket, head) { + rh.emit("upgrade", req, socket, head); +} + +const serverFactory = (handler, opts) => { + return createServer() + .on("request", (req, res) => { + if (bare.shouldRoute(req)) { + bare.routeRequest(req, res); + } else if (shouldRouteRh(req)) { + routeRhRequest(req, res); + } else { + handler(req, res); + } + }) + .on("upgrade", (req, socket, head) => { + if (bare.shouldRoute(req)) { + bare.routeUpgrade(req, socket, head); + } else if (shouldRouteRh(req)) { + routeRhUpgrade(req, socket, head); + } else if (req.url.endsWith("/wisp/")) { + wisp.routeRequest(req, socket as Socket, head); + } + }); +}; + +const app = fastify({ logger: false, serverFactory }); + +app.register(cookieParser); +await app.register(import("@fastify/compress")); +//Uncomment the following line to enable masqr +//app.register(masqr); + +app.register(fastifyStatic, { + root: path.join(__dirname, "dist"), + prefix: "/", + serve: true, + wildcard: false +}); + +app.get("/search=:query", async (req, res) => { + const { query } = req.params as { query: string }; // Define the type for req.params + + const response = await fetch( + `http://api.duckduckgo.com/ac?q=${query}&format=json` + ).then((apiRes) => apiRes.json()); + + res.send(response); +}); + +app.setNotFoundHandler((req, res) => { + res.sendFile("index.html"); // SPA catch-all +}); + +console.log( + chalk.green(`Server listening on ${chalk.bold("http://localhost:8080")}`) +); +console.log( + chalk.magenta(`Server also listening on ${chalk.bold("http://0.0.0.0:8080")}`) +); + +app.listen({ + port: 8080, + host: "0.0.0.0" +});