diff options
author | Raphael Kabo <raphaelkabo@hey.com> | 2023-10-09 10:48:10 +0100 |
---|---|---|
committer | Raphael Kabo <raphaelkabo@hey.com> | 2023-10-09 10:48:10 +0100 |
commit | 8b33335584afbac74388c4ed16ff1ff7a04e3588 (patch) | |
tree | bc35e2e96695a56780139856dfd1f5267546193f /src | |
parent | 8a1f07b11e8e18243c058149ac58ece7766b7ef3 (diff) |
Add static page config and handler
Diffstat (limited to 'src')
-rwxr-xr-x | src/app.ts | 2 | ||||
-rw-r--r-- | src/lib/config.ts | 23 | ||||
-rw-r--r-- | src/routes/static.ts | 34 | ||||
-rw-r--r-- | src/util/config.ts | 19 | ||||
-rw-r--r-- | src/util/markdown.ts | 16 |
5 files changed, 71 insertions, 23 deletions
@@ -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; +}; |