Each installed script now saves a reference in IDB.
This commit is contained in:
parent
caf81f9f06
commit
3040dfc66e
5 changed files with 226 additions and 76 deletions
16
masqr.js
16
masqr.js
|
|
@ -13,23 +13,23 @@ export async function masqrCheck(config) {
|
||||||
next();
|
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");
|
res.setHeader("WWW-Authenticate", "Basic");
|
||||||
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 = (
|
const licenseCheck = (
|
||||||
await (await fetch(config.licenseServer + pass + "&host=" + req.headers.host)).json()
|
await (await fetch(config.licenseServer + pass + "&host=" + req.headers.host)).json()
|
||||||
)["status"];
|
)["status"];
|
||||||
|
|
@ -37,14 +37,16 @@ export async function masqrCheck(config) {
|
||||||
config.licenseServer + pass + "&host=" + req.headers.host + " returned " + licenseCheck
|
config.licenseServer + 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;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function MasqFail(req, res) {
|
async function MasqFail(req, res) {
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
|
|
||||||
"footer.brand": "Alu",
|
"footer.brand": "Alu",
|
||||||
"footer.madeWithLove": "Made with ❤️ by wearr",
|
"footer.madeWithLove": "Made with ❤️ by wearr",
|
||||||
"footer.poweredBy": "Powered by Ultraviolet",
|
"footer.poweredBy": "Titanium Network",
|
||||||
"footer.services": "Services",
|
"footer.services": "Services",
|
||||||
"footer.socials": "Socials",
|
"footer.socials": "Socials",
|
||||||
"footer.aluProject": "Alu Project",
|
"footer.aluProject": "Alu Project",
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
|
|
||||||
"footer.brand": "アルー",
|
"footer.brand": "アルー",
|
||||||
"footer.madeWithLove": "wearrによる❤️で作られました",
|
"footer.madeWithLove": "wearrによる❤️で作られました",
|
||||||
"footer.poweredBy": "「ウルトラバイオレット」による駆動",
|
"footer.poweredBy": "チタンネットワークサービス",
|
||||||
"footer.services": "サービス",
|
"footer.services": "サービス",
|
||||||
"footer.socials": "ソーシャル",
|
"footer.socials": "ソーシャル",
|
||||||
"footer.aluProject": "アループロジェクト",
|
"footer.aluProject": "アループロジェクト",
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,14 @@
|
||||||
{
|
{
|
||||||
"adblock": {
|
"dev.wearr.adblock": {
|
||||||
"title": "Adblocker",
|
"title": "Adblocker",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"image": "/marketplace/adblock/adblock.png",
|
"image": "/marketplace/adblock/adblock.png",
|
||||||
"script": "/marketplace/adblock/adblocker.js",
|
"script": "/marketplace/adblock/adblocker.js"
|
||||||
"slug": "adblock"
|
},
|
||||||
}
|
"dev.wearr.adblock2": {
|
||||||
}
|
"title": "Adblocker2",
|
||||||
|
"version": "0.0.2",
|
||||||
|
"image": "/marketplace/adblock/adblock.png",
|
||||||
|
"script": "/marketplace/adblock/adblocker.js"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,76 +1,219 @@
|
||||||
---
|
---
|
||||||
import { STATIC_PATHS } from "@i18n/utils";
|
import { STATIC_PATHS } from "@i18n/utils";
|
||||||
import Layout from "src/layouts/Layout.astro"
|
import Layout from "src/layouts/Layout.astro";
|
||||||
import marketplace from "../../json/marketplace.json"
|
import marketplace from "../../json/marketplace.json";
|
||||||
|
|
||||||
export const getStaticPaths = (() => {
|
export const getStaticPaths = () => {
|
||||||
return STATIC_PATHS;
|
return STATIC_PATHS;
|
||||||
});
|
};
|
||||||
|
|
||||||
type MarketplaceItem = {
|
type MarketplaceItem = {
|
||||||
title: string,
|
title: string;
|
||||||
version: string | number,
|
version: string | number;
|
||||||
image: string,
|
image: string;
|
||||||
script: string,
|
script: string;
|
||||||
slug: string
|
|
||||||
};
|
};
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="Marketplace | Alu">
|
<Layout title="Marketplace | Alu">
|
||||||
<div id="main-content">
|
<div id="main-content">
|
||||||
<h1 class="title-text">Marketplace</h1>
|
<h1 class="title-text">Marketplace</h1>
|
||||||
<div class="marketplace-ext-grid">
|
<div class="marketplace-ext-grid">
|
||||||
{Object.keys(marketplace).map((mp_item) => {
|
{
|
||||||
const item = (marketplace as {[key: string ]: MarketplaceItem})[mp_item]
|
Object.keys(marketplace).map((mp_item) => {
|
||||||
return <div class="marketplace-item" id={item.slug}>
|
const item = (marketplace as { [key: string]: MarketplaceItem })[mp_item];
|
||||||
<img class="marketplace-item-image" src={item.image} alt={`${item.title} Logo`}/>
|
const slug = mp_item;
|
||||||
<div class="marketplace-item-title">{item.title}</div>
|
console.log(slug);
|
||||||
<button class="marketplace-install-btn">Install</button>
|
return (
|
||||||
</div>
|
<div class="marketplace-item" data-slug={slug}>
|
||||||
})}
|
<img class="marketplace-item-image" src={item.image} alt={`${item.title} Logo`} />
|
||||||
</div>
|
<div class="marketplace-item-title">{item.title}</div>
|
||||||
|
<button class="marketplace-install-btn" data-slug={slug} data-title={item.title}>
|
||||||
|
Install
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const installButtons = document.getElementsByClassName("marketplace-install-btn") as HTMLCollectionOf<HTMLButtonElement>;
|
import "notyf/notyf.min.css";
|
||||||
Array.from(installButtons).forEach(btn => {
|
import { Notyf } from "notyf";
|
||||||
btn.addEventListener("click", (event) => {
|
import marketplaceManifest from "../../json/marketplace.json";
|
||||||
console.log(event.target)
|
const installButtons = document.getElementsByClassName(
|
||||||
})
|
"marketplace-install-btn"
|
||||||
|
) as HTMLCollectionOf<HTMLButtonElement>;
|
||||||
|
Array.from(installButtons).forEach((btn) => {
|
||||||
|
btn.addEventListener("click", async (event) => {
|
||||||
|
const ele = event.target as HTMLButtonElement;
|
||||||
|
const title = ele.dataset.title;
|
||||||
|
let notification = new Notyf({
|
||||||
|
duration: 999999,
|
||||||
|
position: { x: "right", y: "bottom" },
|
||||||
|
dismissible: true,
|
||||||
|
ripple: true,
|
||||||
|
});
|
||||||
|
let installNotif = notification.success(`Installing ${title}...`);
|
||||||
|
if (ele.dataset.slug) installExtension(getMarketplaceObj(ele.dataset.slug), ele.dataset.slug).then((code) => {
|
||||||
|
let notifMessage = "";
|
||||||
|
let timeout = 2000;
|
||||||
|
console.log(code)
|
||||||
|
switch (code) {
|
||||||
|
case 0:
|
||||||
|
notifMessage = `Installed ${title} Successfully!`;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
notifMessage = `${title} is already installed!`;
|
||||||
|
timeout = 0;
|
||||||
|
break;
|
||||||
|
case -1:
|
||||||
|
// We should NEVER get here, but just in case.
|
||||||
|
notifMessage = `Failed to install ${title}!`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
notification.dismiss(installNotif);
|
||||||
|
notification.options.duration = 2000;
|
||||||
|
notification.success(notifMessage)
|
||||||
|
notification.options.duration = 999999;
|
||||||
|
}, timeout)
|
||||||
|
|
||||||
|
}).catch(() => {
|
||||||
|
notification.dismiss(installNotif);
|
||||||
|
notification.options.duration = 2000;
|
||||||
|
notification.error(`Failed to install ${title}!`);
|
||||||
|
notification.options.duration = 999999;
|
||||||
|
});
|
||||||
|
else console.error("No slug found!");
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
type MarketplaceItem = {
|
||||||
|
title: string;
|
||||||
|
version: string | number;
|
||||||
|
image: string;
|
||||||
|
script: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
function getMarketplaceObj(slug: string): ExtensionMetadata {
|
||||||
|
return (marketplaceManifest as { [key: string]: MarketplaceItem })[slug];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ExtensionMetadata {
|
||||||
|
title: string;
|
||||||
|
version: string | number;
|
||||||
|
script: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum EXT_RETURN {
|
||||||
|
INSTALL_SUCCESS = 0,
|
||||||
|
INSTALL_FAILED = -1,
|
||||||
|
ALREADY_INSTALLED = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
async function installExtension(ext: ExtensionMetadata, slug: string) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const request = window.indexedDB.open("AluDB", 1);
|
||||||
|
request.onupgradeneeded = (event) => {
|
||||||
|
const db = (event.target as IDBOpenDBRequest).result;
|
||||||
|
if (!db.objectStoreNames.contains("InstalledExtensions")) {
|
||||||
|
db.createObjectStore("InstalledExtensions", { keyPath: "slug" });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
request.onsuccess = async (event) => {
|
||||||
|
const db = (event.target as IDBOpenDBRequest).result;
|
||||||
|
const transaction = db.transaction("InstalledExtensions", "readwrite");
|
||||||
|
const store = transaction.objectStore("InstalledExtensions");
|
||||||
|
const extensionObject = {
|
||||||
|
slug: slug,
|
||||||
|
title: ext.title,
|
||||||
|
version: ext.version,
|
||||||
|
script: ext.script,
|
||||||
|
};
|
||||||
|
// Check if the key already exists in the IDB
|
||||||
|
let slugCheck = store.get(slug);
|
||||||
|
slugCheck.onsuccess = (event) => {
|
||||||
|
if (slugCheck.result) {
|
||||||
|
resolve(EXT_RETURN.ALREADY_INSTALLED);
|
||||||
|
} else {
|
||||||
|
if (store.get(slug)) resolve(EXT_RETURN.ALREADY_INSTALLED);
|
||||||
|
const addRequest = store.add(extensionObject);
|
||||||
|
addRequest.onerror = (event) => {
|
||||||
|
console.error(`Error installing ${slug}!`)
|
||||||
|
reject(EXT_RETURN.INSTALL_FAILED);
|
||||||
|
};
|
||||||
|
addRequest.onsuccess = (event) => {
|
||||||
|
resolve(EXT_RETURN.INSTALL_SUCCESS);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
slugCheck.onerror = (event) => {
|
||||||
|
console.error("Error checking install status!");
|
||||||
|
reject(EXT_RETURN.INSTALL_FAILED);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function InitIDB() {
|
||||||
|
if (!window.indexedDB) {
|
||||||
|
console.error("This browser doesn't support IndexedDB");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const request = window.indexedDB.open("AluDB", 1);
|
||||||
|
request.onerror = (event: Event) => {
|
||||||
|
console.error("Database error: " + (event.target as any).errorCode);
|
||||||
|
};
|
||||||
|
request.onsuccess = (event) => {
|
||||||
|
console.log("Database opened successfully");
|
||||||
|
};
|
||||||
|
request.onupgradeneeded = (event) => {
|
||||||
|
const db = (event.target as IDBOpenDBRequest).result;
|
||||||
|
if (!db.objectStoreNames.contains("InstalledExtensions")) {
|
||||||
|
db.createObjectStore("InstalledExtensions", { keyPath: "slug" });
|
||||||
|
console.log("Database setup complete");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
InitIDB();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.marketplace-ext-grid {
|
.marketplace-ext-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
width: 90%;
|
width: 90%;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
display: grid;
|
display: grid;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
gap: 20px;
|
||||||
.marketplace-item {
|
}
|
||||||
border: 3px solid var(--accent-color);
|
.marketplace-item {
|
||||||
padding: 20px;
|
border: 3px solid var(--accent-color);
|
||||||
border-radius: 15px;
|
padding: 20px;
|
||||||
}
|
border-radius: 15px;
|
||||||
.marketplace-item-image {
|
width: 180px;
|
||||||
width: 64px;
|
}
|
||||||
height: 64px;
|
.marketplace-item-image {
|
||||||
}
|
width: 64px;
|
||||||
.marketplace-install-btn {
|
height: 64px;
|
||||||
width: 100%;
|
}
|
||||||
background-color: var(--accent-color);
|
.marketplace-install-btn {
|
||||||
color: var(--text-color);
|
width: 100%;
|
||||||
border: none;
|
background-color: var(--accent-color);
|
||||||
margin-top: 3px;
|
color: var(--text-color);
|
||||||
padding: 3px;
|
border: none;
|
||||||
cursor: pointer;
|
margin-top: 3px;
|
||||||
font-family: "Varela Round", sans-serif;
|
padding: 3px;
|
||||||
}
|
cursor: pointer;
|
||||||
</style>
|
font-family: "Varela Round", sans-serif;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue