diff --git a/asgard.png b/asgard.png new file mode 100644 index 0000000..2dc065e Binary files /dev/null and b/asgard.png differ diff --git a/database_assets/image/asgard.png b/database_assets/image/asgard.png new file mode 100644 index 0000000..2dc065e Binary files /dev/null and b/database_assets/image/asgard.png differ diff --git a/package-lock.json b/package-lock.json index 0ef6f38..8cc1de2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,9 @@ "concurrently": "^8.2.2", "express": "^4.19.2", "fastify": "^4.28.1", + "form-data": "^4.0.0", + "formdata-node": "^6.0.3", + "multer": "^1.4.5-lts.1", "nanostores": "^0.10.3", "sequelize": "^6.37.3", "sqlite3": "^5.1.7", @@ -2653,6 +2656,11 @@ "node": ">= 8" } }, + "node_modules/append-field": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", + "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==" + }, "node_modules/aproba": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", @@ -2809,6 +2817,11 @@ "@iconify/utils": "^2.1.5" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, "node_modules/atomic-sleep": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", @@ -3187,6 +3200,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -3707,6 +3731,17 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "optional": true }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/comma-separated-tokens": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", @@ -3740,6 +3775,47 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "optional": true }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/concat-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/concat-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/concurrently": { "version": "8.2.2", "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.2.tgz", @@ -4083,6 +4159,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", @@ -4889,6 +4973,27 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/formdata-node": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-6.0.3.tgz", + "integrity": "sha512-8e1++BCiTzUno9v5IZ2J6bv4RU+3UKDmqWUQD0MIMVCd9AdhWkO1gw57oo1mNEX1dMq2EGI+FbWz4B92pscSQg==", + "engines": { + "node": ">= 18" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -7355,6 +7460,34 @@ "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz", "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==" }, + "node_modules/multer": { + "version": "1.4.5-lts.1", + "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.1.tgz", + "integrity": "sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==", + "dependencies": { + "append-field": "^1.0.0", + "busboy": "^1.0.0", + "concat-stream": "^1.5.2", + "mkdirp": "^0.5.4", + "object-assign": "^4.1.1", + "type-is": "^1.6.4", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/multer/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, "node_modules/mz": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", @@ -9520,6 +9653,14 @@ "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==" }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -10106,6 +10247,11 @@ "node": ">= 0.6" } }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + }, "node_modules/typesafe-path": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/typesafe-path/-/typesafe-path-0.2.2.tgz", diff --git a/package.json b/package.json index 1148ea6..cc75aca 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,9 @@ "concurrently": "^8.2.2", "express": "^4.19.2", "fastify": "^4.28.1", + "form-data": "^4.0.0", + "formdata-node": "^6.0.3", + "multer": "^1.4.5-lts.1", "nanostores": "^0.10.3", "sequelize": "^6.37.3", "sqlite3": "^5.1.7", diff --git a/server.js b/server.js index 9a17de7..63a2344 100644 --- a/server.js +++ b/server.js @@ -5,6 +5,7 @@ import wisp from "wisp-server-node"; import { Sequelize, DataTypes } from "sequelize"; import { fileURLToPath } from "url"; import { handler as ssrHandler } from "./dist/server/entry.mjs"; +import multer from "multer"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -18,6 +19,17 @@ const sequelize = new Sequelize("database", "user", "password", { storage: "database.sqlite", }); +var 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 upload = multer({ storage: storage }); + const catalog_assets = sequelize.define("catalog_assets", { package_name: { type: DataTypes.TEXT, @@ -136,6 +148,22 @@ app.get("/api/packages/:package", async (request, reply) => { } }); +// This API is responsible for image uploads +// PSK authentication required. (NOT YET IMPLEMENTED!!!!!!!!!!) +app.post("/upload", 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, + }); +}); + app.use("/images/", express.static("./database_assets/image")); app.use("/videos/", express.static("./database_assets/video")); app.use("/styles/", express.static("./database_assets/styles")); @@ -179,10 +207,10 @@ server.on("request", (req, res) => { }); server.on("upgrade", (req, socket, head) => { - if (req.url.endsWith("/wisp/")) { - wisp.routeRequest(req, socket, head); - } -}) + if (req.url.endsWith("/wisp/")) { + wisp.routeRequest(req, socket, head); + } +}); server.listen({ port: 8080, diff --git a/test_upload.js b/test_upload.js new file mode 100644 index 0000000..291e6c0 --- /dev/null +++ b/test_upload.js @@ -0,0 +1,10 @@ +// This is a test file to upload files to the Nebula server +import { FormData, File } from "formdata-node"; +import { fileFromPath } from "formdata-node/file-from-path"; + +const form = new FormData(); +// const file = new File(["My hovercraft is full of eels"], "example.txt"); + +form.set("file", await fileFromPath("asgard.png")); + +await fetch("http://localhost:8080/upload", { method: "post", body: form }); diff --git a/upload/1724199750074.txt b/upload/1724199750074.txt new file mode 100644 index 0000000..5235125 --- /dev/null +++ b/upload/1724199750074.txt @@ -0,0 +1 @@ +My hovercraft is full of eels \ No newline at end of file diff --git a/upload/1724200123415.txt b/upload/1724200123415.txt new file mode 100644 index 0000000..5235125 --- /dev/null +++ b/upload/1724200123415.txt @@ -0,0 +1 @@ +My hovercraft is full of eels \ No newline at end of file diff --git a/upload/1724200221644.png b/upload/1724200221644.png new file mode 100644 index 0000000..2dc065e Binary files /dev/null and b/upload/1724200221644.png differ diff --git a/upload/asgard.png b/upload/asgard.png new file mode 100644 index 0000000..2dc065e Binary files /dev/null and b/upload/asgard.png differ diff --git a/upload/shit.png b/upload/shit.png new file mode 100644 index 0000000..2dc065e Binary files /dev/null and b/upload/shit.png differ