diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..3f873d1 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,21 @@ +{ + "arrowParens": "always", + "endOfLine": "lf", + "proseWrap": "preserve", + "quoteProps": "consistent", + "trailingComma": "all", + "printWidth": 140, + "tabWidth": 2, + "semi": true, + "singleQuote": false, + "useTabs": false, + "overrides": [ + { + "files": ["*.liquid"], + "options": { + "parser": "angular" + } + } + ] + } + \ No newline at end of file diff --git a/Source/Webserver/index.ts b/Source/Webserver/index.ts index a51a025..be1ffdb 100644 --- a/Source/Webserver/index.ts +++ b/Source/Webserver/index.ts @@ -1,21 +1,52 @@ import express from "express"; import { Liquid } from "liquidjs"; -const engine = new Liquid(); -const app = express(); -const port = 3430; +import path from "path"; -app.engine('liquid', engine.express()); -app.set('views', ['./partials', './views']); -app.set('view engine', 'liquid'); +//import { apiRoutes } from "./routes/api"; +//import { authRoutes } from "./routes/auth"; +import { indexRoutes } from "./routes/index"; -app.get('/', function (req, res) { - const todos = ['fork and clone', 'make it better', 'make a pull request'] - res.render('todolist', { - todos: todos, - title: 'Welcome to liquidjs!' - }) -}) +const isProduction = process.env.NODE_ENV === "production"; +const LAYOUTS_DIRECTORY = path.join(__dirname, "layouts"); +const PARTIALS_DIRECTORY = path.join(__dirname, "partials"); +const PUBLIC_DIRECTORY = path.join(__dirname, "public"); +const VIEWS_DIRECTORY = path.join(__dirname, "views"); -app.listen(port, () => { - console.log('✅ Webserver started on port ', port) -}) \ No newline at end of file +export function startWebserver(config:any) { + const app = express(); + app.disable("x-powered-by"); + + app.use(express.urlencoded({ extended: true, limit: "1mb" })); + app.use(express.json({ limit: "1mb" })); + + // Liquid engine options + const engine = new Liquid({ + root: [VIEWS_DIRECTORY, PARTIALS_DIRECTORY, LAYOUTS_DIRECTORY], + cache: isProduction, + lenientIf: true, + jsTruthy: true, + extname: ".liquid", + }); + + // View engine options + app.engine("liquid", engine.express()); + app.set("views", [VIEWS_DIRECTORY, PARTIALS_DIRECTORY, LAYOUTS_DIRECTORY]); + app.set("view engine", "liquid"); + + // Uses public folder + app.use("/public/", express.static(PUBLIC_DIRECTORY)); + + // Routes + app.use("/", indexRoutes()); + + // 404 handler + app.use((req, res) => { + if (req.accepts("html")) return res.status(404).render("404", { url: req.url, errorCode: 404 }); + else if (req.accepts("json")) return res.status(404).send({ error: "404" }); + else res.status(404).type("txt").send("404"); + }); + + app.listen(3430, "0.0.0.0", () => { + console.log(`Webserver running on port 3430`); + }); +} \ No newline at end of file diff --git a/Source/Webserver/routes/api.ts b/Source/Webserver/routes/api.ts new file mode 100644 index 0000000..e69de29 diff --git a/Source/Webserver/routes/auth.ts b/Source/Webserver/routes/auth.ts new file mode 100644 index 0000000..e69de29 diff --git a/Source/Webserver/routes/index.ts b/Source/Webserver/routes/index.ts new file mode 100644 index 0000000..bff17cb --- /dev/null +++ b/Source/Webserver/routes/index.ts @@ -0,0 +1,40 @@ +/** + * @file Index routes + * @description Routings for the index page and it's redirects + * @module webserver/routes/index + */ + +import express from "express"; +import rateLimit from "express-rate-limit"; +const router = express.Router(); + + +const indexRateLimit = rateLimit({ + windowMs: 1 * 60 * 1000, + max: 50, + message: "Too many requests in a short period of time.", +}); + +export function indexRoutes() { + // Index + router.get("/", indexRateLimit,async (req,res) => { + res.render("index", { + //locales: getWebLocale(bot, locale), + page: req.url, + //user: user, + }); + }) + + // Gitea + router.get("/gitea/", async (_req, res) => { + res.redirect(301, "https://tea.nightly.town/Mangoberry/MangoRecipe"); + }); + + // robots.txt + router.get("/robots.txt", async (_req, res) => { + res.type("text/plain"); + res.send("User-agent: *\nCrawl-delay: 5\nDisallow: /public/\nDisallow: /auth/"); + }); + + return router; +}; \ No newline at end of file diff --git a/Source/Webserver/views/todolist.liquid b/Source/Webserver/views/index.liquid similarity index 100% rename from Source/Webserver/views/todolist.liquid rename to Source/Webserver/views/index.liquid diff --git a/Source/classes/Main.ts b/Source/classes/Main.ts new file mode 100644 index 0000000..57ebbef --- /dev/null +++ b/Source/classes/Main.ts @@ -0,0 +1,12 @@ +import path from "path"; +import { startWebserver } from "../Webserver/index"; +import config from "../../config.json"; + +export class MangoRecipe { + config: typeof config; + // Starts webservers at first boot + constructor() { + this.config = config; + startWebserver(this); + } +} \ No newline at end of file diff --git a/Source/index.ts b/Source/index.ts new file mode 100644 index 0000000..e31927b --- /dev/null +++ b/Source/index.ts @@ -0,0 +1,10 @@ +/** + * @file Index + * @description Creates an instance of Hibiki + * @license AGPL-3.0-or-later + */ + +import { MangoRecipe } from "./classes/Main"; +import config from "../config.json"; + +new MangoRecipe(); \ No newline at end of file diff --git a/config.json b/config.json new file mode 100644 index 0000000..e69de29