diff --git a/astro.config.mjs b/astro.config.mjs index ccbb445..49be10f 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -6,9 +6,17 @@ import { epoxyPath } from "@mercuryworkshop/epoxy-transport"; import { libcurlPath } from "@mercuryworkshop/libcurl-transport"; import { uvPath } from "@titaniumnetwork-dev/ultraviolet"; import icon from "astro-icon"; -import { defineConfig } from "astro/config"; +import { defineConfig, envField } from "astro/config"; import { viteStaticCopy } from "vite-plugin-static-copy"; +import { version } from "./package.json"; export default defineConfig({ + experimental: { + env: { + schema: { + VERSION: envField.string({ context: 'client', access: 'public', optional: true, default: version }) + } + } + }, integrations: [tailwind(), icon(), svelte()], vite: { plugins: [ diff --git a/database_assets/image/com.nebula.gruvbox.jpeg b/database_assets/image/com.nebula.gruvbox.jpeg new file mode 100644 index 0000000..3d79448 Binary files /dev/null and b/database_assets/image/com.nebula.gruvbox.jpeg differ diff --git a/database_assets/image/cyber_monay.jpg b/database_assets/image/cyber_monay.jpg deleted file mode 100644 index 1d17b68..0000000 Binary files a/database_assets/image/cyber_monay.jpg and /dev/null differ diff --git a/database_assets/image/neptune.webp b/database_assets/image/neptune.webp deleted file mode 100644 index 58641ca..0000000 Binary files a/database_assets/image/neptune.webp and /dev/null differ diff --git a/database_assets/styles/com.nebula.cybermonay.css b/database_assets/styles/com.nebula.cybermonay.css deleted file mode 100644 index 8cf33f6..0000000 --- a/database_assets/styles/com.nebula.cybermonay.css +++ /dev/null @@ -1,19 +0,0 @@ -:root { - --background-primary: rgba(0, 0, 0, 0); - --background-lighter: #000; - --navbar-color: #000; - --navbar-height: 60px; - --navbar-text-color: greenyellow; - --navbar-link-color: greenyellow; - --navbar-link-hover-color: green; - --navbar-font: "Roboto"; - --input-text-color: greenyellow; - --input-placeholder-color: white; - --input-background-color: #000; - --input-border-color: greenyellow; - --input-border-size: 1.3px; - --navbar-logo-filter: none; - --dropdown-option-hover-color: #312a49; - --tab-color: var(--black); - --border-color: greenyellow; -} diff --git a/database_assets/styles/com.nebula.gruvbox.css b/database_assets/styles/com.nebula.gruvbox.css new file mode 100644 index 0000000..eceedbf --- /dev/null +++ b/database_assets/styles/com.nebula.gruvbox.css @@ -0,0 +1,22 @@ +:root { + --background-primary: #282828; + --background-lighter: #3c3836; + --navbar-color: #504945; + --navbar-height: 60px; + --navbar-text-color: #fbf1c7; + --navbar-link-color: #ebdbb2; + --navbar-link-hover-color: #fabd2f; + --navbar-font: "Roboto", sans-serif; + --input-text-color: #b8bb26; + --input-placeholder-color: #928374; + --input-background-color: #1d2021; + --input-border-color: #b8bb26; + --input-border-size: 1.3px; + --navbar-logo-filter: none; + --dropdown-option-hover-color: #665c54; + --tab-color: #1d2021; + --border-color: #b8bb26; + --highlight-color: #fe8019; + --accent-color: #83a598; + --secondary-text-color: #d3869b; +} diff --git a/database_assets/video/cyber_monay_test.mp4 b/database_assets/video/cyber_monay_test.mp4 deleted file mode 100644 index 55035da..0000000 Binary files a/database_assets/video/cyber_monay_test.mp4 and /dev/null differ diff --git a/server.js b/server.js deleted file mode 100644 index 0f55d76..0000000 --- a/server.js +++ /dev/null @@ -1,345 +0,0 @@ -import fs from "fs"; -import { createServer } from "node:http"; -import path from "path"; -import { fileURLToPath } from "url"; -import { - createRammerhead, - routeRhRequest, - routeRhUpgrade, - shouldRouteRh -} from "@rubynetwork/rammerhead"; -import express from "express"; -import multer from "multer"; -import { DataTypes, Sequelize } from "sequelize"; -import wisp from "wisp-server-node"; -import { handler as ssrHandler } from "./dist/server/entry.mjs"; - -const config = JSON.parse(fs.readFileSync("config.json", "utf8")); -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); -//create the rh server. -const rh = createRammerhead({ - logLevel: "debug", - reverseProxy: true, - disableLocalStorageSync: false, - disableHttp2: false -}); -const app = express(); -const publicPath = "dist/client"; -const sequelize = new Sequelize("database", "user", "password", { - host: "localhost", - dialect: "sqlite", - logging: false, - // SQLite only - storage: "database.sqlite" -}); - -// Auth middleware -function auth_psk(req, res, next) { - if (!config.marketplace_enabled) { - let err = "Marketplace is disabled!"; - return next(err); - } - - if (req.headers.psk !== config.marketplace_psk) { - let err = "Bad PSK!"; - console.log("Bad psk"); - return next(err); - } - - return next(); -} - -var image_storage = multer.diskStorage({ - destination: function (req, file, cb) { - cb(null, "database_assets/image"); - }, - filename: function (req, file, cb) { - cb(null, file.originalname); //Appending extension - } -}); - -var video_storage = multer.diskStorage({ - destination: function (req, file, cb) { - cb(null, "database_assets/video"); - }, - filename: function (req, file, cb) { - cb(null, file.originalname); //Appending extension - } -}); - -var style_storage = multer.diskStorage({ - destination: function (req, file, cb) { - cb(null, "database_assets/styles"); - }, - filename: function (req, file, cb) { - cb(null, file.originalname); //Appending extension - } -}); - -var script_storage = multer.diskStorage({ - destination: function (req, file, cb) { - cb(null, "database_assets/scripts"); - }, - filename: function (req, file, cb) { - cb(null, file.originalname); //Appending extension - } -}); - -var image_upload = multer({ storage: image_storage }); -var video_upload = multer({ storage: video_storage }); -var style_upload = multer({ storage: style_storage }); -var script_upload = multer({ storage: script_storage }); - -const catalog_assets = sequelize.define("catalog_assets", { - package_name: { - type: DataTypes.TEXT, - unique: true - }, - title: { - type: DataTypes.TEXT - }, - description: { - type: DataTypes.TEXT - }, - author: { - type: DataTypes.TEXT - }, - image: { - type: DataTypes.TEXT - }, - tags: { - type: DataTypes.JSON, - allowNull: true - }, - version: { - type: DataTypes.TEXT - }, - background_image: { - type: DataTypes.TEXT, - allowNull: true - }, - background_video: { - type: DataTypes.TEXT, - allowNull: true - }, - payload: { - type: DataTypes.TEXT - }, - type: { - type: DataTypes.TEXT - } -}); - -app.use(express.json()); - -app.get("/api", function (request, reply) { - reply.send({ hello: "world" }); -}); - -// This API returns a list of the assets in the database (SW plugins and themes). -// It also returns the number of pages in the database. -// It can take a `?page=x` argument to display a different page, with a limit of 20 assets per page. -app.get("/api/catalog-assets", async (request, reply) => { - try { - const page = parseInt(request.query.page, 10) || 1; // default to page 1 - - const totalItems = await catalog_assets.count(); - - if (page < 1) { - reply.status(400).send({ error: "Page must be a positive number!" }); - return; - } - - const offset = (page - 1) * 20; - - const db_assets = await catalog_assets.findAll({ - offset: offset, - limit: 20 - }); - - const assets = db_assets.reduce((acc, asset) => { - acc[asset.package_name] = { - title: asset.title, - description: asset.description, - author: asset.author, - image: asset.image, - tags: asset.tags, - version: asset.version, - background_image: asset.background_image, - background_video: asset.background_video, - payload: asset.payload, - type: asset.type - }; - return acc; - }, {}); - - reply.send({ assets, pages: Math.ceil(totalItems / 20) }); - } catch (error) { - reply.status(500).send({ error: "There was an error" }); - } -}); - -// This API returns data about a single package. -app.get("/api/packages/:package", async (request, reply) => { - try { - console.log(request.params.package); - - const package_row = await catalog_assets.findOne({ - where: { package_name: request.params.package } - }); - - if (!package_row) { - return reply.status(404).send({ error: "Package not found!" }); - } - - const details = { - title: package_row.get("title"), - description: package_row.get("description"), - image: package_row.get("image"), - author: package_row.get("author"), - tags: package_row.get("tags"), - version: package_row.get("version"), - background_image: package_row.get("background_image"), - background_video: package_row.get("background_video"), - payload: package_row.get("payload"), - type: package_row.get("type") - }; - reply.send(details); - } catch (error) { - reply.status(500).send({ error: "There was an error" }); - } -}); - -// This API is responsible for image uploads -// PSK authentication required. -app.post("/api/upload-image", auth_psk, image_upload.single("file"), (req, res) => { - console.log("Request file:", req.file); - - if (!req.file) { - return res.status(400).json({ error: "No file uploaded" }); - } - - console.log(req.file.originalname); - res.json({ - message: "File uploaded successfully", - filename: req.file.originalname - }); -}); - -// This API is responsible for video uploads -// PSK authentication required. -app.post("/api/upload-video", auth_psk, video_upload.single("file"), (req, res) => { - if (!req.file) { - return res.status(400).json({ error: "No file uploaded" }); - } - - res.json({ - message: "File uploaded successfully", - filename: req.file.originalname - }); -}); - -// This API is responsible for stylesheet uploads -// PSK authentication required. -app.post("/api/upload-style", auth_psk, style_upload.single("file"), (req, res) => { - if (!req.file) { - return res.status(400).json({ error: "No file uploaded" }); - } - - res.json({ - message: "File uploaded successfully", - filename: req.file.originalname - }); -}); - -// This API is responsible for script/plugin uploads -// PSK authentication required. -app.post("/api/upload-script", auth_psk, script_upload.single("file"), (req, res) => { - if (!req.file) { - return res.status(400).json({ error: "No file uploaded" }); - } - - res.json({ - message: "File uploaded successfully", - filename: req.file.originalname - }); -}); - -// This API is responsible for creating packages in the database. -// PSK authentication required. -app.post("/api/create-package", auth_psk, async function (req, res) { - console.log(req.body); - await catalog_assets.create({ - package_name: req.body.uuid, - title: req.body.title, - image: req.body.image_path, - author: req.body.author, - version: req.body.version, - description: req.body.description, - tags: req.body.tags, - payload: req.body.payload, - background_video: req.body.background_video_path, - background_image: req.body.background_image_path, - type: req.body.type - }); - res.send({ hello: "world" }); -}); - -app.use("/images/", express.static("./database_assets/image")); -app.use("/videos/", express.static("./database_assets/video")); -app.use("/styles/", express.static("./database_assets/styles")); -app.use("/scripts/", express.static("./database_assets/scripts")); -app.use(ssrHandler); -app.use(express.static(publicPath)); - -//await catalog_assets.create({ -// package_name: "com.nebula.cybermonay", -// title: "Cyber Monay", -// image: "cyber_monay.jpg", -// author: "Nebula Services", -// version: "1.0.0", -// description: 'A parody of the famous "Cyber Monay" hack!', -// tags: ["Hacking", "Animated", "Funny"], -// payload: "com.nebula.cybermonay.css", -// background_video: "cyber_monay_test.mp4", -//type: "theme", -//}); - -// await catalog_assets.create({ -// package_name: "com.neptune.neptune", -// title: "Neptune", -// image: "neptune.webp", -// author: "Neptune", -// version: "1.0.0", -// description: "Neptune image", -// tags: ["Image", "Funny"], -// payload: "neptune.css", -// background_image: "neptune.webp", -// type: "theme", -// }); - -catalog_assets.sync(); -const server = createServer(); - -server.on("request", (req, res) => { - res.setHeader("Cross-Origin-Opener-Policy", "same-origin"); - res.setHeader("Cross-Origin-Embedder-Policy", "require-corp"); - if (shouldRouteRh(req)) { - routeRhRequest(rh, req, res); - } else { - app(req, res); - } -}); - -server.on("upgrade", (req, socket, head) => { - if (shouldRouteRh(req)) { - routeRhUpgrade(rh, req, socket, head); - } else if (req.url.endsWith("/wisp/")) { - wisp.routeRequest(req, socket, head); - } -}); - -server.listen({ - port: 8080 -}); diff --git a/server/dbSetup.ts b/server/dbSetup.ts index 5633285..7cdc9e0 100644 --- a/server/dbSetup.ts +++ b/server/dbSetup.ts @@ -31,15 +31,14 @@ async function setupDB(db: ModelStatic) { //We have some packages that need to be installed if they aren't. const items: Items[] = [ { - package_name: 'com.nebula.cybermonay', - title: 'Cyber Monay', - image: 'cyber_monay.jpg', + package_name: 'com.nebula.gruvbox', + title: 'Gruvbox', + image: 'com.nebula.gruvbox.jpeg', author: 'Nebula Services', version: '1.0.0', - description: 'A parody of the famous "Cyber Monay" hack!', - tags: ["Hacking", "Animated", "Funny"], - payload: "com.nebula.cybermonay.css", - background_video: "cyber_monay_test.mp4", + description: 'The gruvbox theme', + tags: ["Theme", "Simple"], + payload: "com.nebula.gruvbox.css", type: 'theme' } ] diff --git a/src/pages/[lang]/index.astro b/src/pages/[lang]/index.astro index fd5eafa..d29bfd6 100644 --- a/src/pages/[lang]/index.astro +++ b/src/pages/[lang]/index.astro @@ -9,22 +9,17 @@ export function getStaticPaths() { export const prerender = true; const lang = getLangFromUrl(Astro.url); const t = useTranslations(lang); +import { VERSION } from "astro:env/client"; --- -
-
+
+
-

+

nebula.

@@ -42,7 +37,11 @@ const t = useTranslations(lang); + > +
+

Version: { VERSION }

+

© Nebula Services 2024

+