Add support for optionally enabling masqr via .env and optionally enabling wisp, format using prettier.
This commit is contained in:
parent
f1a56b9f91
commit
f8bde78717
15 changed files with 4356 additions and 1803 deletions
3
.env.example
Normal file
3
.env.example
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
USE_WISP=true
|
||||
MASQR_ENABLED=true
|
||||
PORT=3000
|
||||
|
|
@ -20,7 +20,7 @@ Alu is a beautiful, functional, and sleek web proxy, which focuses on customizat
|
|||
|
||||
Deploying Alu is about as simple as it gets, from your terminal, type
|
||||
|
||||
`git clone https://github.com/wearrrrr/Alu --recurse-submodules`
|
||||
`git clone https://github.com/titaniumnetwork-dev/Alu --recurse-submodules`
|
||||
|
||||
This command should clone Alu's frontend, as well as [alu-games](https://github.com/wearrrrr/alu-games). If you wish to skip cloning games, then leave out the last flag.
|
||||
|
||||
|
|
@ -39,6 +39,7 @@ Congrats, you've now deployed your very own web proxy!
|
|||
- Typescript
|
||||
- ExpressJS
|
||||
- Prettier
|
||||
- ESLint
|
||||
|
||||
# License
|
||||
|
||||
|
|
|
|||
85
index.js
85
index.js
|
|
@ -13,13 +13,14 @@ import { existsSync } from "fs";
|
|||
import dotenv from "dotenv";
|
||||
import cookieParser from "cookie-parser";
|
||||
import wisp from "wisp-server-node";
|
||||
import fs from "node:fs";
|
||||
import fetch from "node-fetch";
|
||||
import { masqrCheck } from "./masqr.js";
|
||||
dotenv.config();
|
||||
|
||||
const whiteListedDomains = ["aluu.xyz", "localhost:3000"];
|
||||
const LICENSE_SERVER_URL = "https://license.mercurywork.shop/validate?license=";
|
||||
const whiteListedDomains = ["aluu.xyz", "localhost:3000"]; // Add any public domains you have here
|
||||
const failureFile = fs.readFileSync("Checkfailed.html", "utf8");
|
||||
const WISP_ENABLED = process.env.USE_WISP;
|
||||
const MASQR_ENABLED = process.env.MASQR_ENABLED;
|
||||
|
||||
if (!existsSync("./dist")) build();
|
||||
|
||||
|
|
@ -49,71 +50,12 @@ const app = express();
|
|||
app.use(compression({ threshold: 0, filter: () => true }));
|
||||
app.use(cookieParser());
|
||||
|
||||
async function MasqFail(req, res) {
|
||||
if (!req.headers.host) {
|
||||
return;
|
||||
}
|
||||
const unsafeSuffix = req.headers.host + ".html";
|
||||
let safeSuffix = path.normalize(unsafeSuffix).replace(/^(\.\.(\/|\\|$))+/, "");
|
||||
let safeJoin = path.join(process.cwd() + "/Masqrd", safeSuffix);
|
||||
try {
|
||||
await fs.promises.access(safeJoin); // man do I wish this was an if-then instead of a "exception on fail"
|
||||
const failureFileLocal = await fs.promises.readFile(safeJoin, "utf8");
|
||||
res.setHeader("Content-Type", "text/html");
|
||||
res.send(failureFileLocal);
|
||||
return;
|
||||
} catch (e) {
|
||||
res.setHeader("Content-Type", "text/html");
|
||||
res.send(failureFile);
|
||||
return;
|
||||
}
|
||||
// Set process.env.MASQR_ENABLED to "true" to enable masqr protection.
|
||||
if (process.env.MASQR_ENABLED == "true") {
|
||||
console.log(chalk.gray("Starting Masqr..."));
|
||||
app.use(await masqrCheck({ whitelist: whiteListedDomains, licenseServer: LICENSE_SERVER_URL }));
|
||||
}
|
||||
|
||||
// Woooooo masqr yayyyy (said no one)
|
||||
// uncomment for masqr
|
||||
app.use(async (req, res, next) => {
|
||||
if (req.headers.host && whiteListedDomains.includes(req.headers.host)) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
const authheader = req.headers.authorization;
|
||||
if (req.cookies["authcheck"]) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.cookies["refreshcheck"] != "true") {
|
||||
res.cookie("refreshcheck", "true", { maxAge: 10000 }); // 10s refresh check
|
||||
MasqFail(req, res);
|
||||
return;
|
||||
}
|
||||
|
||||
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.status(401);
|
||||
MasqFail(req, res);
|
||||
return;
|
||||
}
|
||||
|
||||
const auth = Buffer.from(authheader.split(" ")[1], "base64").toString().split(":");
|
||||
const pass = auth[1];
|
||||
|
||||
const 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") {
|
||||
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
|
||||
return;
|
||||
}
|
||||
|
||||
MasqFail(req, res);
|
||||
return;
|
||||
});
|
||||
|
||||
app.use(express.static(path.join(process.cwd(), "static")));
|
||||
app.use(express.static(path.join(process.cwd(), "build")));
|
||||
app.use("/uv/", express.static(uvPath));
|
||||
|
|
@ -127,7 +69,7 @@ app.use(
|
|||
})
|
||||
);
|
||||
app.use((req, res, next) => {
|
||||
if (req.url.includes ("/games/")) {
|
||||
if (req.url.includes("/games/")) {
|
||||
res.header("Cross-Origin-Opener-Policy", "same-origin");
|
||||
res.header("Cross-Origin-Embedder-Policy", "require-corp");
|
||||
}
|
||||
|
|
@ -136,11 +78,11 @@ app.use((req, res, next) => {
|
|||
app.use("/custom-favicon", async (req, res) => {
|
||||
try {
|
||||
const { url, contentType } = req.query;
|
||||
const urlExt = url.split('.').pop();
|
||||
const urlExt = url.split(".").pop();
|
||||
const response = await fetch(url);
|
||||
const arrayBuffer = await response.arrayBuffer();
|
||||
const buffer = Buffer.from(arrayBuffer);
|
||||
console.log(contentType)
|
||||
console.log(contentType);
|
||||
if (contentType || !contentType == "") {
|
||||
res.setHeader("Content-Type", contentType);
|
||||
} else {
|
||||
|
|
@ -197,7 +139,7 @@ app.get("/search", async (req, res) => {
|
|||
res.redirect(302, "/404.html");
|
||||
}
|
||||
});
|
||||
app.get("*", function (req, res) {
|
||||
app.get("*", (req, res) => {
|
||||
res.sendFile(path.join(process.cwd(), "dist/client/404.html"));
|
||||
});
|
||||
|
||||
|
|
@ -217,7 +159,8 @@ server.on("upgrade", (req, socket, head) => {
|
|||
bare.routeUpgrade(req, socket, head);
|
||||
} else if (shouldRouteRh(req)) {
|
||||
routeRhUpgrade(req, socket, head);
|
||||
} else if (req.url.endsWith("/wisp/")) {
|
||||
/* Kinda hacky, I need to do a proper dynamic import. */
|
||||
} else if (req.url.endsWith("/wisp/") && WISP_ENABLED == "true") {
|
||||
wisp.routeRequest(req, socket, head);
|
||||
} else {
|
||||
socket.end();
|
||||
|
|
|
|||
68
masqr.js
Normal file
68
masqr.js
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
import path from "path";
|
||||
|
||||
const failureFile = fs.readFileSync("Checkfailed.html", "utf8");
|
||||
|
||||
export async function masqrCheck(config) {
|
||||
return async (req, res, next) => {
|
||||
if (req.headers.host && config.whitelist.includes(req.headers.host)) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
const authheader = req.headers.authorization;
|
||||
if (req.cookies["authcheck"]) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.cookies["refreshcheck"] != "true") {
|
||||
res.cookie("refreshcheck", "true", { maxAge: 10000 }); // 10s refresh check
|
||||
MasqFail(req, res);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!authheader) {
|
||||
res.setHeader("WWW-Authenticate", "Basic");
|
||||
res.status(401);
|
||||
MasqFail(req, res);
|
||||
return;
|
||||
}
|
||||
|
||||
const auth = Buffer.from(authheader.split(" ")[1], "base64").toString().split(":");
|
||||
const pass = auth[1];
|
||||
|
||||
const licenseCheck = (
|
||||
await (await fetch(config.licenseServer + pass + "&host=" + req.headers.host)).json()
|
||||
)["status"];
|
||||
console.log(
|
||||
config.licenseServer + pass + "&host=" + req.headers.host + " returned " + licenseCheck
|
||||
);
|
||||
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.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;
|
||||
}
|
||||
|
||||
MasqFail(req, res);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
async function MasqFail(req, res) {
|
||||
if (!req.headers.host) {
|
||||
return;
|
||||
}
|
||||
const unsafeSuffix = req.headers.host + ".html";
|
||||
let safeSuffix = path.normalize(unsafeSuffix).replace(/^(\.\.(\/|\\|$))+/, "");
|
||||
let safeJoin = path.join(process.cwd() + "/Masqrd", safeSuffix);
|
||||
try {
|
||||
await fs.promises.access(safeJoin); // man do I wish this was an if-then instead of a "exception on fail"
|
||||
const failureFileLocal = await fs.promises.readFile(safeJoin, "utf8");
|
||||
res.setHeader("Content-Type", "text/html");
|
||||
res.send(failureFileLocal);
|
||||
return;
|
||||
} catch (e) {
|
||||
res.setHeader("Content-Type", "text/html");
|
||||
res.send(failureFile);
|
||||
return;
|
||||
}
|
||||
}
|
||||
5760
pnpm-lock.yaml
generated
5760
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
18
public/sw.js
18
public/sw.js
|
|
@ -7,13 +7,13 @@ importScripts(__uv$config.sw);
|
|||
|
||||
const uv = new UVServiceWorker();
|
||||
|
||||
self.addEventListener('fetch', event => {
|
||||
event.respondWith(
|
||||
(async ()=>{
|
||||
if(event.request.url.startsWith(location.origin + __uv$config.prefix)) {
|
||||
return await uv.fetch(event);
|
||||
}
|
||||
return await fetch(event.request);
|
||||
})()
|
||||
);
|
||||
self.addEventListener("fetch", (event) => {
|
||||
event.respondWith(
|
||||
(async () => {
|
||||
if (event.request.url.startsWith(location.origin + __uv$config.prefix)) {
|
||||
return await uv.fetch(event);
|
||||
}
|
||||
return await fetch(event.request);
|
||||
})()
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,18 +1,21 @@
|
|||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Varela Round';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url(varela-latin-ext.woff2) format('woff2');
|
||||
unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Varela Round';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url(varela-latin.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: "Varela Round";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url(varela-latin-ext.woff2) format("woff2");
|
||||
unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
|
||||
U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: "Varela Round";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url(varela-latin.woff2) format("woff2");
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304,
|
||||
U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF,
|
||||
U+FFFD;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,9 +86,9 @@
|
|||
let iframe = document.getElementById("proxy-frame") as HTMLIFrameElement;
|
||||
let topbar = document.getElementById("top-bar") as HTMLDivElement;
|
||||
let closeButton = document.getElementById("close-button") as HTMLButtonElement;
|
||||
let backwardsButton = document.getElementById('nav-backwards') as HTMLImageElement;
|
||||
let forwardsButton = document.getElementById('nav-forwards') as HTMLImageElement;
|
||||
let shareButton = document.getElementById('nav-share') as HTMLImageElement;
|
||||
let backwardsButton = document.getElementById("nav-backwards") as HTMLImageElement;
|
||||
let forwardsButton = document.getElementById("nav-forwards") as HTMLImageElement;
|
||||
let shareButton = document.getElementById("nav-share") as HTMLImageElement;
|
||||
let preference = getProxyPreference();
|
||||
if (preference === "ultraviolet") {
|
||||
iframe.src = window.__uv$config.prefix + window.__uv$config.encodeUrl(url);
|
||||
|
|
@ -114,7 +114,15 @@
|
|||
iframe.classList.add("proxy-frame");
|
||||
document.body.appendChild(iframe);
|
||||
setTimeout(() => {
|
||||
iframeLoad(iframe, loadingContent, topbar, closeButton, shareButton, forwardsButton, backwardsButton);
|
||||
iframeLoad(
|
||||
iframe,
|
||||
loadingContent,
|
||||
topbar,
|
||||
closeButton,
|
||||
shareButton,
|
||||
forwardsButton,
|
||||
backwardsButton
|
||||
);
|
||||
}, 500);
|
||||
|
||||
function setActive() {
|
||||
|
|
@ -162,9 +170,17 @@
|
|||
shareButton.onclick = () => {
|
||||
let currentProxy = localStorage.getItem("alu__selectedProxy");
|
||||
if (currentProxy && JSON.parse(currentProxy).value === "rammerhead") {
|
||||
navigator.clipboard.writeText(window.location.origin + "/" + getCookie("rammerhead-session") + "/" + input!.value.trim());
|
||||
navigator.clipboard.writeText(
|
||||
window.location.origin +
|
||||
"/" +
|
||||
getCookie("rammerhead-session") +
|
||||
"/" +
|
||||
input!.value.trim()
|
||||
);
|
||||
} else {
|
||||
navigator.clipboard.writeText(window.__uv$config.decodeUrl(iframe.src.split("/service/")[1]));
|
||||
navigator.clipboard.writeText(
|
||||
window.__uv$config.decodeUrl(iframe.src.split("/service/")[1])
|
||||
);
|
||||
}
|
||||
new Notyf({
|
||||
duration: 2000,
|
||||
|
|
@ -265,7 +281,10 @@
|
|||
proxiedFavicon.src = favicon.href;
|
||||
return;
|
||||
}
|
||||
if (proxiedFavicon.src == `${window.location.origin}/custom-favicon?url=${encodedHREF}&contentType=${favicon.type ? encodeURIComponent(favicon.type) : ""}`)
|
||||
if (
|
||||
proxiedFavicon.src ==
|
||||
`${window.location.origin}/custom-favicon?url=${encodedHREF}&contentType=${favicon.type ? encodeURIComponent(favicon.type) : ""}`
|
||||
)
|
||||
return;
|
||||
}
|
||||
if (favicon) {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@ const languageList = [
|
|||
<Dropdown buttonNameDefault="Alu" dropdownList={themeList} id="dropdown__selected-theme" />
|
||||
</div>
|
||||
<div class="setting__language">
|
||||
<label aria-label="Language" class="setting-label">{t("settings.customization.language")}</label>
|
||||
<label aria-label="Language" class="setting-label">{t("settings.customization.language")}</label
|
||||
>
|
||||
<Dropdown
|
||||
buttonNameDefault="English"
|
||||
dropdownList={languageList}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,9 @@ const transportsList = [
|
|||
|
||||
<div class="settings-container">
|
||||
<div class="setting__selected-proxy">
|
||||
<label aria-label="Selected Proxy" class="setting-label">{t("settings.proxy.selectedProxy")}</label>
|
||||
<label aria-label="Selected Proxy" class="setting-label"
|
||||
>{t("settings.proxy.selectedProxy")}</label
|
||||
>
|
||||
<Dropdown
|
||||
buttonNameDefault="Ultraviolet"
|
||||
dropdownList={proxyList}
|
||||
|
|
@ -42,7 +44,9 @@ const transportsList = [
|
|||
/>
|
||||
</div>
|
||||
<div class="setting__search-engine">
|
||||
<label aria-label="Search Engine" class="setting-label">{t("settings.proxy.searchEngine")}</label>
|
||||
<label aria-label="Search Engine" class="setting-label"
|
||||
>{t("settings.proxy.searchEngine")}</label
|
||||
>
|
||||
<Dropdown
|
||||
buttonNameDefault="Google"
|
||||
dropdownList={searchEngineList}
|
||||
|
|
@ -51,7 +55,9 @@ const transportsList = [
|
|||
/>
|
||||
</div>
|
||||
<div class="setting__open_with">
|
||||
<label aria-label="Open Page With" class="setting-label">{t("settings.proxy.openPageWith")}</label>
|
||||
<label aria-label="Open Page With" class="setting-label"
|
||||
>{t("settings.proxy.openPageWith")}</label
|
||||
>
|
||||
<Dropdown
|
||||
buttonNameDefault={t("settings.proxy.openPageWith.embed")}
|
||||
dropdownList={openPageWith}
|
||||
|
|
@ -60,11 +66,15 @@ const transportsList = [
|
|||
/>
|
||||
</div>
|
||||
<div class="setting__wisp_url">
|
||||
<label aria-label="Wisp URL" for="wisp-url-input" class="setting-label">{t("settings.proxy.wispURL")}</label>
|
||||
<label aria-label="Wisp URL" for="wisp-url-input" class="setting-label"
|
||||
>{t("settings.proxy.wispURL")}</label
|
||||
>
|
||||
<Input height="50px" inputName="wisp-url" />
|
||||
</div>
|
||||
<div class="setting__bare_url">
|
||||
<label aria-label="Bare Server URL" for="bare-url-input" class="setting-label">{t("settings.proxy.bareURL")}</label>
|
||||
<label aria-label="Bare Server URL" for="bare-url-input" class="setting-label"
|
||||
>{t("settings.proxy.bareURL")}</label
|
||||
>
|
||||
<Input height="50px" inputName="bare-url" />
|
||||
</div>
|
||||
<div class="setting__transport">
|
||||
|
|
@ -78,6 +88,8 @@ const transportsList = [
|
|||
</div>
|
||||
</div>
|
||||
<div class="setting__searxng-url">
|
||||
<label aria-label="SearXNG URL" for="searxng-url-input" class="setting-label">{t("settings.proxy.searxngURL")}</label>
|
||||
<label aria-label="SearXNG URL" for="searxng-url-input" class="setting-label"
|
||||
>{t("settings.proxy.searxngURL")}</label
|
||||
>
|
||||
<Input height="50px" inputName="searxng-url" defaultTextContent="https://searxng.site/" />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -68,16 +68,14 @@ export const TransportMgr = new TransportManager();
|
|||
export async function registerSW() {
|
||||
navigator.serviceWorker.ready.then(async (sw) => {
|
||||
await registerRemoteListener(sw.active!);
|
||||
})
|
||||
});
|
||||
return new Promise(async (resolve) => {
|
||||
await navigator.serviceWorker
|
||||
.register("/sw.js")
|
||||
.then((registration) => {
|
||||
registration.update().then(() => {
|
||||
console.log("Registered SW!");
|
||||
resolve(null);
|
||||
});
|
||||
await navigator.serviceWorker.register("/sw.js").then((registration) => {
|
||||
registration.update().then(() => {
|
||||
console.log("Registered SW!");
|
||||
resolve(null);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -91,7 +89,6 @@ export async function initTransport() {
|
|||
|
||||
export async function loadSelectedTransportScript(): Promise<void> {
|
||||
return new Promise((resolve) => {
|
||||
|
||||
let selectedTransport = localStorage.getItem("alu__selectedTransport");
|
||||
if (!selectedTransport) {
|
||||
localStorage.setItem("alu__selectedTransport", JSON.stringify({ value: "uv" }));
|
||||
|
|
|
|||
|
|
@ -48,11 +48,7 @@ const { title, optionalPreloads } = Astro.props;
|
|||
/>
|
||||
<meta property="twitter:image" content="/logo.png" />
|
||||
<link rel="sitemap" href="/sitemap-index.xml" />
|
||||
<link
|
||||
href="/varela-round.css"
|
||||
rel="stylesheet"
|
||||
as="style"
|
||||
/>
|
||||
<link href="/varela-round.css" rel="stylesheet" as="style" />
|
||||
{
|
||||
optionalPreloads?.map((item) => {
|
||||
return <link rel="preload" href={item.href} as={item.as} />;
|
||||
|
|
|
|||
|
|
@ -33,9 +33,9 @@ export function getStaticPaths() {
|
|||
<div class="top-bar-left">
|
||||
<button id="close-button">Close</button>
|
||||
<div class="nav-container">
|
||||
<img id="nav-backwards" src="/img/nav/backwards.svg" alt="Backwards Arrow">
|
||||
<img id="nav-forwards" src="/img/nav/forwards.svg" alt="Forwards Arrow">
|
||||
<img id="nav-share" src="/img/nav/share.svg" alt="Share Page">
|
||||
<img id="nav-backwards" src="/img/nav/backwards.svg" alt="Backwards Arrow" />
|
||||
<img id="nav-forwards" src="/img/nav/forwards.svg" alt="Forwards Arrow" />
|
||||
<img id="nav-share" src="/img/nav/share.svg" alt="Share Page" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="top-bar-right">
|
||||
|
|
@ -144,7 +144,6 @@ export function getStaticPaths() {
|
|||
</script>
|
||||
</Layout>
|
||||
|
||||
|
||||
<style is:global>
|
||||
#main-content {
|
||||
width: 100%;
|
||||
|
|
|
|||
|
|
@ -323,7 +323,8 @@ export function getStaticPaths() {
|
|||
if (savedWispUrl == null || savedWispUrl == "")
|
||||
localStorage.setItem("alu__wispUrl", webSocketProtocol + location.host + "/wisp/");
|
||||
let savedBareUrl = localStorage.getItem("alu__bareUrl");
|
||||
if (savedBareUrl == null || savedBareUrl == "") localStorage.setItem("alu__bareUrl", location.origin + "/bare/");
|
||||
if (savedBareUrl == null || savedBareUrl == "")
|
||||
localStorage.setItem("alu__bareUrl", location.origin + "/bare/");
|
||||
wispURLInput.value = localStorage.getItem("alu__wispUrl");
|
||||
bareURLInput.value = localStorage.getItem("alu__bareUrl");
|
||||
// Proxy settings
|
||||
|
|
@ -331,14 +332,16 @@ export function getStaticPaths() {
|
|||
applyInputListeners(wispURLInput, "alu__wispUrl");
|
||||
applyInputListeners(bareURLInput, "alu__bareUrl");
|
||||
|
||||
[selectedProxyDropdown, openWithDropdown, currentTransportDropdown].forEach((dropdown) => {
|
||||
let dropdownButton = document.getElementById(dropdown.id.replace("-menu", ""));
|
||||
applyDropdownEventListeners(
|
||||
dropdown,
|
||||
dropdownButton.id,
|
||||
dropdownButton.dataset.localStorageKey
|
||||
);
|
||||
});
|
||||
[selectedProxyDropdown, openWithDropdown, currentTransportDropdown].forEach(
|
||||
(dropdown) => {
|
||||
let dropdownButton = document.getElementById(dropdown.id.replace("-menu", ""));
|
||||
applyDropdownEventListeners(
|
||||
dropdown,
|
||||
dropdownButton.id,
|
||||
dropdownButton.dataset.localStorageKey
|
||||
);
|
||||
}
|
||||
);
|
||||
applyDropdownEventListeners(
|
||||
searchEngineDropdown,
|
||||
"dropdown__search-engine",
|
||||
|
|
@ -553,5 +556,3 @@ export function getStaticPaths() {
|
|||
}
|
||||
</style>
|
||||
</Layout>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ import { ViewTransitions } from "astro:transitions";
|
|||
<ViewTransitions />
|
||||
<script>
|
||||
let currentLang = localStorage.getItem("alu__selectedLanguage");
|
||||
const redirect = (loc: string) => window.location.href = loc
|
||||
const redirect = (loc: string) => (window.location.href = loc);
|
||||
if (currentLang) {
|
||||
try {
|
||||
let parsed = JSON.parse(currentLang).value;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue