Add eslint support! 🎉

This commit is contained in:
wearrrrr 2024-03-18 00:11:58 -05:00
parent a5d590b7ab
commit f3e347c1cd
17 changed files with 1368 additions and 85 deletions

3
.eslintignore Normal file
View file

@ -0,0 +1,3 @@
node_modules/
dist/
public/

31
.eslintrc.cjs Normal file
View file

@ -0,0 +1,31 @@
module.exports = {
env: {
node: true,
es2022: true,
browser: true,
},
extends: ["eslint:recommended", "plugin:astro/recommended"],
parserOptions: {
ecmaVersion: "latest",
sourceType: "module",
},
rules: {
"no-unused-vars": "error",
},
overrides: [
{
files: ["*.astro"],
parser: "astro-eslint-parser",
parserOptions: {
parser: "@typescript-eslint/parser",
extraFileExtensions: [".astro"],
},
},
{
// Define the configuration for `<script>` tag.
// Script in `<script>` is assigned a virtual file name with the `.js` extension.
files: ["**/*.astro/*.js", "*.astro/*.js"],
parser: "@typescript-eslint/parser",
},
],
};

View file

@ -16,9 +16,8 @@
<body> <body>
<h1>Welcome to nginx!</h1> <h1>Welcome to nginx!</h1>
<p> <p>
If you see this page, the nginx web server is successfully installed and If you see this page, the nginx web server is successfully installed and working. Further
working. Further configuration is required. If you are expecting another configuration is required. If you are expecting another page, please check your network or
page, please check your network or
<a href="/" id="rcheck"><b>Refresh this page</b></a> <a href="/" id="rcheck"><b>Refresh this page</b></a>
</p> </p>

View file

@ -13,6 +13,7 @@ import { existsSync } from "fs";
import dotenv from "dotenv"; import dotenv from "dotenv";
import cookieParser from "cookie-parser"; import cookieParser from "cookie-parser";
import wisp from "wisp-server-node"; import wisp from "wisp-server-node";
import fs from "node:fs";
dotenv.config(); dotenv.config();
const LICENSE_SERVER_URL = "https://license.mercurywork.shop/validate?license="; const LICENSE_SERVER_URL = "https://license.mercurywork.shop/validate?license=";
@ -52,9 +53,7 @@ async function MasqFail(req, res) {
return; return;
} }
const unsafeSuffix = req.headers.host + ".html"; const unsafeSuffix = req.headers.host + ".html";
let safeSuffix = path let safeSuffix = path.normalize(unsafeSuffix).replace(/^(\.\.(\/|\\|$))+/, "");
.normalize(unsafeSuffix)
.replace(/^(\.\.(\/|\\|$))+/, "");
let safeJoin = path.join(process.cwd() + "/Masqrd", safeSuffix); let safeJoin = path.join(process.cwd() + "/Masqrd", safeSuffix);
try { try {
await fs.promises.access(safeJoin); // man do I wish this was an if-then instead of a "exception on fail" await fs.promises.access(safeJoin); // man do I wish this was an if-then instead of a "exception on fail"
@ -82,41 +81,43 @@ app.use(async (req, res, next) => {
return; return;
} }
if (req.cookies["refreshcheck"] != "true") {
if (req.cookies['refreshcheck'] != "true") { res.cookie("refreshcheck", "true", { maxAge: 10000 }); // 10s refresh check
res.cookie("refreshcheck", "true", {maxAge: 10000}) // 10s refresh check MasqFail(req, res);
MasqFail(req, res)
return; return;
} }
if (!authheader) { if (!authheader) {
res.setHeader('WWW-Authenticate', 'Basic'); // Yeah so we need to do this to get the auth params, kinda annoying and just showing a login prompt gives it away so its behind a 10s refresh check res.setHeader("WWW-Authenticate", "Basic"); // Yeah so we need to do this to get the auth params, kinda annoying and just showing a login prompt gives it away so its behind a 10s refresh check
res.status(401); res.status(401);
MasqFail(req, res) MasqFail(req, res);
return; return;
} }
const auth = Buffer.from(authheader.split(' ')[1], 'base64').toString().split(':'); const auth = Buffer.from(authheader.split(" ")[1], "base64").toString().split(":");
const pass = auth[1]; const pass = auth[1];
const licenseCheck = ((await (await fetch(LICENSE_SERVER_URL + pass + "&host=" + req.headers.host)).json()))["status"] const licenseCheck = (
console.log(LICENSE_SERVER_URL + pass + "&host=" + req.headers.host +" returned " +licenseCheck) await (await fetch(LICENSE_SERVER_URL + pass + "&host=" + req.headers.host)).json()
)["status"];
console.log(
LICENSE_SERVER_URL + pass + "&host=" + req.headers.host + " returned " + licenseCheck
);
if (licenseCheck == "License valid") { if (licenseCheck == "License valid") {
res.cookie("authcheck", "true", {expires: new Date((Date.now()) + (365*24*60*60 * 1000))}) // authorize session, for like a year, by then the link will be expired lol res.cookie("authcheck", "true", { expires: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000) }); // authorize session, for like a year, by then the link will be expired lol
res.send(`<script> window.location.href = window.location.href </script>`) // fun hack to make the browser refresh and remove the auth params from the URL res.send(`<script> window.location.href = window.location.href </script>`); // fun hack to make the browser refresh and remove the auth params from the URL
return; return;
} }
MasqFail(req, res) MasqFail(req, res);
return; return;
}) });
app.use(express.static(path.join(process.cwd(), "static"))); app.use(express.static(path.join(process.cwd(), "static")));
app.use(express.static(path.join(process.cwd(), "build"))); app.use(express.static(path.join(process.cwd(), "build")));
app.use("/uv/", express.static(uvPath)); app.use("/uv/", express.static(uvPath));
app.use("/epoxy/", express.static(epoxyPath)); app.use("/epoxy/", express.static(epoxyPath));
app.use("/libcurl/", express.static(libcurlPath)) app.use("/libcurl/", express.static(libcurlPath));
app.use(express.json()); app.use(express.json());
app.use( app.use(
@ -129,7 +130,6 @@ app.use(function (req, res, next) {
console.log("Game request"); console.log("Game request");
res.header("Cross-Origin-Opener-Policy", "same-origin"); res.header("Cross-Origin-Opener-Policy", "same-origin");
res.header("Cross-Origin-Embedder-Policy", "require-corp"); res.header("Cross-Origin-Embedder-Policy", "require-corp");
} }
next(); next();
}); });

1241
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -3,10 +3,12 @@
"type": "module", "type": "module",
"version": "0.0.1", "version": "0.0.1",
"scripts": { "scripts": {
"build:all": "npm run format && npm run lint && npm run build",
"start": "node .", "start": "node .",
"build": "astro build", "build": "astro build",
"lint": "prettier --write .", "format": "prettier --write .",
"lint:check": "prettier --check ." "format:check": "prettier --check .",
"lint": "eslint ."
}, },
"dependencies": { "dependencies": {
"@astrojs/node": "^8.2.0", "@astrojs/node": "^8.2.0",
@ -29,6 +31,11 @@
"wisp-server-node": "^1.0.2" "wisp-server-node": "^1.0.2"
}, },
"devDependencies": { "devDependencies": {
"@babel/eslint-parser": "^7.23.10",
"@typescript-eslint/eslint-plugin": "^7.2.0",
"@typescript-eslint/parser": "^7.2.0",
"eslint": "^8.57.0",
"eslint-plugin-astro": "^0.31.4",
"prettier": "3.2.5", "prettier": "3.2.5",
"prettier-plugin-astro": "^0.13.0" "prettier-plugin-astro": "^0.13.0"
} }

View file

@ -3,9 +3,15 @@ const { buttonNameDefault, dropdownList, id, localStorageKey } = Astro.props;
--- ---
<div class="dropdown"> <div class="dropdown">
<button data-local-storage-key={localStorageKey} id={id} class="dropdown-toggle" type="button" data-toggle="dropdown"> <button
data-local-storage-key={localStorageKey}
id={id}
class="dropdown-toggle"
type="button"
data-toggle="dropdown">
{buttonNameDefault} {buttonNameDefault}
<span class="caret"></span></button> <span class="caret"></span></button
>
<ul class="dropdown-menu" id={id + "-menu"}> <ul class="dropdown-menu" id={id + "-menu"}>
{ {
dropdownList.map((item: any) => { dropdownList.map((item: any) => {

View file

@ -5,7 +5,7 @@ interface LinkProps {
content: string; content: string;
} }
const { href, newTab, content } = Astro.props; const { href, newTab, content } = Astro.props as LinkProps;
const target = newTab ? "_blank" : "_self"; const target = newTab ? "_blank" : "_self";
const rel = newTab ? "noopener noreferrer" : ""; const rel = newTab ? "noopener noreferrer" : "";
--- ---

View file

@ -255,7 +255,10 @@
); );
if (newurl.length > 30) newurl = newurl.slice(0, 50) + "..."; if (newurl.length > 30) newurl = newurl.slice(0, 50) + "...";
urlText.innerText = newurl; urlText.innerText = newurl;
} else urlText.innerText = window.__uv$config.decodeUrl(newURL.split(__uv$config.prefix)[1]); } else
urlText.innerText = window.__uv$config.decodeUrl(
newURL.split(window.__uv$config.prefix)[1]
);
} }
} }
</script> </script>

View file

@ -21,14 +21,13 @@ const languageList = [
<div class="settings-container"> <div class="settings-container">
<div class="setting__theme"> <div class="setting__theme">
<label class="setting-label">{t("settings.customization.theme")}</label> <label class="setting-label">{t("settings.customization.theme")}</label>
<Dropdown buttonNameDefault="Alu" dropdownList={themeList} , id="dropdown__selected-theme" /> <Dropdown buttonNameDefault="Alu" dropdownList={themeList} id="dropdown__selected-theme" />
</div> </div>
<div class="setting__language"> <div class="setting__language">
<label class="setting-label">{t("settings.customization.language")}</label> <label class="setting-label">{t("settings.customization.language")}</label>
<Dropdown <Dropdown
buttonNameDefault="English" buttonNameDefault="English"
dropdownList={languageList} dropdownList={languageList}
,
id="dropdown__selected-language" id="dropdown__selected-language"
/> />
</div> </div>

View file

@ -30,7 +30,7 @@ const transportsList = [
{ name: "Epoxy", value: "EpxMod.EpoxyClient" }, { name: "Epoxy", value: "EpxMod.EpoxyClient" },
{ name: "Libcurl", value: "CurlMod.LibcurlClient" }, { name: "Libcurl", value: "CurlMod.LibcurlClient" },
{ name: "Bare", value: "BareMod.BareClient" }, { name: "Bare", value: "BareMod.BareClient" },
] ];
--- ---
<div class="settings-container"> <div class="settings-container">

View file

@ -312,7 +312,7 @@ const t = useTranslations(lang);
applyInputListeners(wispURLInput, "alu__wispUrl"); applyInputListeners(wispURLInput, "alu__wispUrl");
[selectedProxyDropdown, openWithDropdown, currentTransportDropdown].forEach((dropdown) => { [selectedProxyDropdown, openWithDropdown, currentTransportDropdown].forEach((dropdown) => {
let dropdownButton = document.getElementById(dropdown.id.replace("-menu", "")) let dropdownButton = document.getElementById(dropdown.id.replace("-menu", ""));
applyDropdownEventListeners( applyDropdownEventListeners(
dropdown, dropdown,
dropdownButton.id, dropdownButton.id,

View file

@ -1,10 +1,4 @@
<script> <script>
declare global {
interface Navigator {
deviceMemory: number;
}
}
let primaryColor = "#8c25fa"; let primaryColor = "#8c25fa";
let secondaryColor = "#601aab"; let secondaryColor = "#601aab";
console.log( console.log(
@ -30,9 +24,10 @@
); );
// Cmon firefox, do we really not support this?? Basic stuff here from the "indie browser". // Cmon firefox, do we really not support this?? Basic stuff here from the "indie browser".
console.log( console.log(
"%cMemory: " + navigator.deviceMemory + "GB", "%cMemory: " + (navigator as any).deviceMemory + "GB",
`color: ${primaryColor}; font-size: 0.75rem; font-weight: bold;` `color: ${primaryColor}; font-size: 0.75rem; font-weight: bold;`
); );
console.log( console.log(
"%cPlease include this information in a bug report!", "%cPlease include this information in a bug report!",
`color: ${primaryColor}; font-size: 0.75rem; font-weight: bold;` `color: ${primaryColor}; font-size: 0.75rem; font-weight: bold;`

View file

@ -8,12 +8,12 @@ declare global {
prefix: string; prefix: string;
}; };
} }
}; }
type transportConfig = { type transportConfig = {
wisp: string; wisp: string;
wasm?: string; wasm?: string;
} };
export const wispURLDefault = export const wispURLDefault =
(location.protocol === "https:" ? "wss://" : "ws://") + location.host + "/"; (location.protocol === "https:" ? "wss://" : "ws://") + location.host + "/";
@ -49,12 +49,16 @@ export default class TransportManager {
const TransportMgr = new TransportManager(); const TransportMgr = new TransportManager();
export function initTransport() { export function initTransport() {
registerRemoteListener(navigator.serviceWorker.controller!); registerRemoteListener(navigator.serviceWorker.controller!);
navigator.serviceWorker.register("/sw.js", { navigator.serviceWorker
.register("/sw.js", {
scope: window.__uv$config.prefix, scope: window.__uv$config.prefix,
}).then((registration) => { })
.then((registration) => {
registration.update().then(() => { registration.update().then(() => {
TransportMgr.setTransport(TransportMgr.getTransport(), localStorage.getItem("alu__wispUrl") || wispURLDefault); TransportMgr.setTransport(
TransportMgr.getTransport(),
localStorage.getItem("alu__wispUrl") || wispURLDefault
);
}); });
}); });
} }

View file

@ -65,21 +65,18 @@ export function getStaticPaths() {
</div> </div>
</Layout> </Layout>
<script> <script>
import { initTransport } from "../../components/ts/TransportManager" import { initTransport } from "../../components/ts/TransportManager";
initTransport(); initTransport();
type Suggestion = { type Suggestion = {
phrase: string; phrase: string;
}; };
const debounce = (func: Function, delay: number): ((...args: any[]) => void) => { function debounce(func: Function, timeout: number) {
let debounceTimer: NodeJS.Timeout; return function (this: any, ...args: any) {
return function (this: Function, ...args: any[]) { setTimeout(() => {
const context: any = this; func.apply(this, args);
clearTimeout(debounceTimer); }, timeout);
debounceTimer = setTimeout(() => {
func.apply(context, args);
}, delay);
};
}; };
}
async function sendAPIRequest(urlInput: HTMLInputElement, searchSuggestions: HTMLDivElement) { async function sendAPIRequest(urlInput: HTMLInputElement, searchSuggestions: HTMLDivElement) {
if (!urlInput) throw new Error("urlInput is null"); if (!urlInput) throw new Error("urlInput is null");

View file

@ -1,4 +1,4 @@
{ {
"extends": "astro/tsconfigs/strict", "extends": "astro/tsconfigs/strict",
"exclude": ["dist/**", "node_modules/**", "public/games/**"], "exclude": ["dist/**", "node_modules/**", "public/games/**", ".eslint.cjs"]
} }