From 8b33335584afbac74388c4ed16ff1ff7a04e3588 Mon Sep 17 00:00:00 2001 From: Raphael Kabo Date: Mon, 9 Oct 2023 10:48:10 +0100 Subject: Add static page config and handler --- src/routes/static.ts | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 src/routes/static.ts (limited to 'src/routes') 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; -- cgit v1.2.3 From fab74cb0100da89f83983f05d3e3d9e9ea30bc7e Mon Sep 17 00:00:00 2001 From: Raphael Kabo Date: Mon, 9 Oct 2023 10:48:25 +0100 Subject: Refactor publicConfig into frontendConfig --- src/routes/activitypub.ts | 19 +++++++++---------- src/routes/frontend.ts | 19 ++++++++----------- 2 files changed, 17 insertions(+), 21 deletions(-) (limited to 'src/routes') diff --git a/src/routes/activitypub.ts b/src/routes/activitypub.ts index 2c4231a..2b8fb4a 100644 --- a/src/routes/activitypub.ts +++ b/src/routes/activitypub.ts @@ -1,7 +1,7 @@ import { Router, Request, Response, NextFunction } from "express"; import { createFeaturedPost, createWebfinger } from "../activitypub.js"; import { acceptsActivityPub } from "../lib/activitypub.js"; -import getConfig from "../lib/config.js"; +import getConfig, { frontendConfig } from "../lib/config.js"; import Event from "../models/Event.js"; import { addToLog } from "../helpers.js"; @@ -15,8 +15,7 @@ const send404IfNotFederated = ( next: NextFunction, ) => { if (!config.general.is_federated) { - res.status(404).render("404", { url: req.url }); - return; + return res.status(404).render("404", frontendConfig()); } next(); }; @@ -49,10 +48,10 @@ router.get("/:eventID/m/:hash", async (req: Request, res: Response) => { id: eventID, }); if (!event) { - return res.status(404).render("404", { url: req.url }); + return res.status(404).render("404", frontendConfig()); } else { if (!event.activityPubMessages) { - return res.status(404).render("404", { url: req.url }); + return res.status(404).render("404", frontendConfig()); } const message = event.activityPubMessages.find( (el) => el.id === id, @@ -69,7 +68,7 @@ router.get("/:eventID/m/:hash", async (req: Request, res: Response) => { ); } } else { - return res.status(404).render("404", { url: req.url }); + return res.status(404).render("404", frontendConfig()); } } } catch (err) { @@ -81,7 +80,7 @@ router.get("/:eventID/m/:hash", async (req: Request, res: Response) => { " failed with error: " + err, ); - return res.status(404).render("404", { url: req.url }); + return res.status(404).render("404", frontendConfig()); } }); @@ -103,7 +102,7 @@ router.get("/.well-known/webfinger", async (req, res) => { const event = await Event.findOne({ id: eventID }); if (!event) { - return res.status(404).render("404", { url: req.url }); + return res.status(404).render("404", frontendConfig()); } else { if (acceptsActivityPub(req)) { res.header( @@ -122,7 +121,7 @@ router.get("/.well-known/webfinger", async (req, res) => { "error", `Attempt to render webfinger for ${resource} failed with error: ${err}`, ); - return res.status(404).render("404", { url: req.url }); + return res.status(404).render("404", frontendConfig()); } } }); @@ -167,7 +166,7 @@ router.get("/:eventID/followers", async (req, res) => { "error", `Attempt to render followers for ${eventID} failed with error: ${err}`, ); - return res.status(404).render("404", { url: req.url }); + return res.status(404).render("404", frontendConfig()); } }); diff --git a/src/routes/frontend.ts b/src/routes/frontend.ts index c9594ef..cdf314c 100644 --- a/src/routes/frontend.ts +++ b/src/routes/frontend.ts @@ -1,9 +1,8 @@ import { Router, Request, Response } from "express"; import moment from "moment-timezone"; import { marked } from "marked"; -import { frontendConfig } from "../util/config.js"; import { renderPlain } from "../util/markdown.js"; -import getConfig from "../lib/config.js"; +import getConfig, { frontendConfig } from "../lib/config.js"; import { addToLog, exportICal } from "../helpers.js"; import Event from "../models/Event.js"; import EventGroup, { IEventGroup } from "../models/EventGroup.js"; @@ -30,9 +29,7 @@ router.get("/:eventID", async (req: Request, res: Response) => { .lean() // Required, see: https://stackoverflow.com/questions/59690923/handlebars-access-has-been-denied-to-resolve-the-property-from-because-it-is .populate("eventGroup"); if (!event) { - res.status(404); - res.render("404", { url: req.url }); - return; + return res.status(404).render("404", frontendConfig()); } const parsedLocation = event.location.replace(/\s+/g, "+"); let displayDate; @@ -252,7 +249,7 @@ router.get("/:eventID", async (req: Request, res: Response) => { err, ); console.log(err); - res.status(404).render("404", { url: req.url }); + return res.status(404).render("404", frontendConfig()); } }); @@ -263,7 +260,7 @@ router.get("/group/:eventGroupID", async (req: Request, res: Response) => { }).lean(); if (!eventGroup) { - return res.status(404).render("404", { url: req.url }); + return res.status(404).render("404", frontendConfig()); } const parsedDescription = marked.parse(eventGroup.description); const eventGroupEditToken = eventGroup.editToken; @@ -364,7 +361,7 @@ router.get("/group/:eventGroupID", async (req: Request, res: Response) => { `Attempt to display event group ${req.params.eventGroupID} failed with error: ${err}`, ); console.log(err); - return res.status(404).render("404", { url: req.url }); + return res.status(404).render("404", frontendConfig()); } }); @@ -391,7 +388,7 @@ router.get( `Attempt to display event group feed for ${req.params.eventGroupID} failed with error: ${err}`, ); console.log(err); - res.status(404).render("404", { url: req.url }); + return res.status(404).render("404", frontendConfig()); } }, ); @@ -413,7 +410,7 @@ router.get("/export/event/:eventID", async (req: Request, res: Response) => { `Attempt to export event ${req.params.eventID} failed with error: ${err}`, ); console.log(err); - res.status(404).render("404", { url: req.url }); + return res.status(404).render("404", frontendConfig()); } }); @@ -439,7 +436,7 @@ router.get( `Attempt to export event group ${req.params.eventGroupID} failed with error: ${err}`, ); console.log(err); - res.status(404).render("404", { url: req.url }); + return res.status(404).render("404", frontendConfig()); } }, ); -- cgit v1.2.3 From 6af99ef4c0c3a28a29bad9f4c66e41d0365234cc Mon Sep 17 00:00:00 2001 From: Raphael Kabo Date: Mon, 9 Oct 2023 10:51:17 +0100 Subject: Fix bug when no static pages defined --- src/routes/static.ts | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) (limited to 'src/routes') diff --git a/src/routes/static.ts b/src/routes/static.ts index f57d1db..33f0225 100644 --- a/src/routes/static.ts +++ b/src/routes/static.ts @@ -6,29 +6,31 @@ 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(), - }); +if (config.static_pages?.length) { + 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()); } - return res.status(404).render("404", frontendConfig()); - } catch (err) { - console.error(err); - return res.status(404).render("404", frontendConfig()); - } + }); }); - }); +} export default router; -- cgit v1.2.3 From 31022a7d323a351041b7b8508fb56c14fd699580 Mon Sep 17 00:00:00 2001 From: Raphael Kabo Date: Mon, 9 Oct 2023 11:05:39 +0100 Subject: Sanitize Markdown HTML output everywhere --- src/routes/event.ts | 4 ++-- src/routes/frontend.ts | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'src/routes') diff --git a/src/routes/event.ts b/src/routes/event.ts index 2245009..cfd877e 100644 --- a/src/routes/event.ts +++ b/src/routes/event.ts @@ -2,7 +2,6 @@ import { Router, Response, Request } from "express"; import multer from "multer"; import Jimp from "jimp"; import moment from "moment-timezone"; -import { marked } from "marked"; import { generateEditToken, generateEventID, @@ -26,6 +25,7 @@ import getConfig from "../lib/config.js"; import { sendEmailFromTemplate } from "../lib/email.js"; import crypto from "crypto"; import ical from "ical"; +import { markdownToSanitizedHTML } from "../util/markdown.js"; const config = getConfig(); @@ -148,7 +148,7 @@ router.post( eventID, config.general.domain, publicKey, - marked.parse(eventData.eventDescription), + markdownToSanitizedHTML(eventData.eventDescription), eventData.eventName, eventData.eventLocation, eventImageFilename, diff --git a/src/routes/frontend.ts b/src/routes/frontend.ts index cdf314c..c405572 100644 --- a/src/routes/frontend.ts +++ b/src/routes/frontend.ts @@ -1,7 +1,7 @@ import { Router, Request, Response } from "express"; import moment from "moment-timezone"; import { marked } from "marked"; -import { renderPlain } from "../util/markdown.js"; +import { markdownToSanitizedHTML, renderPlain } from "../util/markdown.js"; import getConfig, { frontendConfig } from "../lib/config.js"; import { addToLog, exportICal } from "../helpers.js"; import Event from "../models/Event.js"; @@ -91,7 +91,7 @@ router.get("/:eventID", async (req: Request, res: Response) => { eventHasBegun = true; } let fromNow = moment.tz(event.start, event.timezone).fromNow(); - let parsedDescription = marked.parse(event.description); + let parsedDescription = markdownToSanitizedHTML(event.description); let eventEditToken = event.editToken; let escapedName = event.name.replace(/\s+/g, "+"); @@ -262,7 +262,9 @@ router.get("/group/:eventGroupID", async (req: Request, res: Response) => { if (!eventGroup) { return res.status(404).render("404", frontendConfig()); } - const parsedDescription = marked.parse(eventGroup.description); + const parsedDescription = markdownToSanitizedHTML( + eventGroup.description, + ); const eventGroupEditToken = eventGroup.editToken; const escapedName = eventGroup.name.replace(/\s+/g, "+"); const eventGroupHasCoverImage = !!eventGroup.image; -- cgit v1.2.3