summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/app.ts2
-rw-r--r--src/lib/config.ts23
-rw-r--r--src/routes/static.ts34
-rw-r--r--src/util/config.ts19
-rw-r--r--src/util/markdown.ts16
5 files changed, 71 insertions, 23 deletions
diff --git a/src/app.ts b/src/app.ts
index c43f31d..3370d27 100755
--- a/src/app.ts
+++ b/src/app.ts
@@ -6,6 +6,7 @@ import frontend from "./routes/frontend.js";
import activitypub from "./routes/activitypub.js";
import event from "./routes/event.js";
import group from "./routes/group.js";
+import staticPages from "./routes/static.js";
import { initEmailService } from "./lib/email.js";
@@ -53,6 +54,7 @@ app.use(express.json({ type: "application/json" }));
app.use(express.urlencoded({ extended: true }));
// Router //
+app.use("/", staticPages);
app.use("/", frontend);
app.use("/", activitypub);
app.use("/", event);
diff --git a/src/lib/config.ts b/src/lib/config.ts
index 7b35b98..7366b59 100644
--- a/src/lib/config.ts
+++ b/src/lib/config.ts
@@ -2,6 +2,12 @@ import fs from "fs";
import toml from "toml";
import { exitWithError } from "./process.js";
+interface StaticPage {
+ title: string;
+ path: string;
+ filename: string;
+}
+
interface GathioConfig {
general: {
domain: string;
@@ -25,9 +31,21 @@ interface GathioConfig {
sendgrid?: {
api_key: string;
};
+ static_pages: StaticPage[];
+}
+
+interface FrontendConfig {
+ domain: string;
+ siteName: string;
+ isFederated: boolean;
+ emailLogoUrl: string;
+ showKofi: boolean;
+ showInstanceInformation: boolean;
+ staticPages: StaticPage[];
+ version: string;
}
-export const publicConfig = () => {
+export const frontendConfig = (): FrontendConfig => {
const config = getConfig();
return {
domain: config.general.domain,
@@ -35,6 +53,9 @@ export const publicConfig = () => {
isFederated: config.general.is_federated,
emailLogoUrl: config.general.email_logo_url,
showKofi: config.general.show_kofi,
+ showInstanceInformation: config.static_pages.length > 0,
+ staticPages: config.static_pages,
+ version: process.env.npm_package_version || "unknown",
};
};
diff --git a/src/routes/static.ts b/src/routes/static.ts
new file mode 100644
index 0000000..f57d1db
--- /dev/null
+++ b/src/routes/static.ts
@@ -0,0 +1,34 @@
+import { Router, Request, Response } from "express";
+import fs from "fs";
+import getConfig, { frontendConfig } from "../lib/config.js";
+import { markdownToSanitizedHTML } from "../util/markdown.js";
+
+const config = getConfig();
+const router = Router();
+
+config.static_pages
+ .filter((page) => page.path?.startsWith("/") && page.filename)
+ .forEach((page) => {
+ router.get(page.path, (_: Request, res: Response) => {
+ try {
+ if (fs.existsSync(`./static/${page.filename}`)) {
+ const fileBody = fs.readFileSync(
+ `./static/${page.filename}`,
+ "utf-8",
+ );
+ const parsed = markdownToSanitizedHTML(fileBody);
+ return res.render("static", {
+ title: page.title,
+ content: parsed,
+ ...frontendConfig(),
+ });
+ }
+ return res.status(404).render("404", frontendConfig());
+ } catch (err) {
+ console.error(err);
+ return res.status(404).render("404", frontendConfig());
+ }
+ });
+ });
+
+export default router;
diff --git a/src/util/config.ts b/src/util/config.ts
deleted file mode 100644
index d1fd05b..0000000
--- a/src/util/config.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import getConfig from "../lib/config.js";
-
-const config = getConfig();
-
-interface FrontendConfig {
- domain: string;
- email: string;
- siteName: string;
- showKofi: boolean;
- isFederated: boolean;
-}
-
-export const frontendConfig = (): FrontendConfig => ({
- domain: config.general.domain,
- email: config.general.email,
- siteName: config.general.site_name,
- showKofi: config.general.show_kofi,
- isFederated: config.general.is_federated,
-});
diff --git a/src/util/markdown.ts b/src/util/markdown.ts
index 9f5d384..bab50bd 100644
--- a/src/util/markdown.ts
+++ b/src/util/markdown.ts
@@ -1,7 +1,6 @@
-// Extra marked renderer (used to render plaintext event description for page metadata)
-// Adapted from https://dustinpfister.github.io/2017/11/19/nodejs-marked/
-
import { marked } from "marked";
+import { JSDOM } from "jsdom";
+import DOMPurify from "dompurify";
// ? to ? helper
function htmlEscapeToText(text: string) {
@@ -14,6 +13,9 @@ function htmlEscapeToText(text: string) {
});
}
+// Extra marked renderer (used to render plaintext event description for page metadata)
+// Adapted from https://dustinpfister.github.io/2017/11/19/nodejs-marked/
+
export const renderPlain = () => {
var render = new marked.Renderer();
// render just the text of a link, strong, em
@@ -42,3 +44,11 @@ export const renderPlain = () => {
};
return render;
};
+
+export const markdownToSanitizedHTML = (markdown: string) => {
+ const html = marked.parse(markdown);
+ const window = new JSDOM("").window;
+ const purify = DOMPurify(window);
+ const clean = purify.sanitize(html);
+ return clean;
+};