From a8a17443c2d070d2d23920ffff7e4a43c905698c Mon Sep 17 00:00:00 2001 From: Gavin Mogan Date: Wed, 23 Apr 2025 17:27:55 -0700 Subject: Refactor for everywhere to use sendEmailFromTemplate everywhere * Created a singleton to house handlebars so req doesn't need to be passed everywhere (should make unit testing easier later) * Subjectline for sendgrid and nodemailer are both always prefixed in sendEmail() * removed prefix subjectline from all other email places * added a couple if (!event) { return 404 } to help make typescript happy * some minor eslint auto fixes (looks like let => const where it can) --- package.json | 1 + pnpm-lock.yaml | 11 +++++ src/app.ts | 68 ++--------------------------- src/lib/email.ts | 101 ++++++++++++++++++++----------------------- src/lib/handlebars.ts | 97 +++++++++++++++++++++-------------------- src/routes.js | 112 ++++++++++++++++++++++++++---------------------- src/routes/event.ts | 51 ++++++---------------- src/routes/group.ts | 6 +-- src/routes/magicLink.ts | 6 +-- 9 files changed, 188 insertions(+), 265 deletions(-) diff --git a/package.json b/package.json index 26d1d00..0287e77 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "author": "", "license": "GPL-3.0-or-later", "dependencies": { + "@sendgrid/helpers": "^8.0.0", "@sendgrid/mail": "^6.5.5", "@types/cookie-parser": "^1.4.7", "activitypub-types": "^1.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5139a4a..0ac81b2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,9 @@ importers: .: dependencies: + '@sendgrid/helpers': + specifier: ^8.0.0 + version: 8.0.0 '@sendgrid/mail': specifier: ^6.5.5 version: 6.5.5 @@ -370,6 +373,10 @@ packages: resolution: {integrity: sha512-uRFEanalfss5hDsuzVXZ1wm7i7eEXHh1py80piOXjobiQ+MxmtR19EU+gDSXZ+uMcEehBGhxnb7QDNN0q65qig==} engines: {node: '>= 6.0.0'} + '@sendgrid/helpers@8.0.0': + resolution: {integrity: sha512-Ze7WuW2Xzy5GT5WRx+yEv89fsg/pgy3T1E3FS0QEx0/VvRmigMZ5qyVGhJz4SxomegDkzXv/i0aFPpHKN8qdAA==} + engines: {node: '>= 12.0.0'} + '@sendgrid/mail@6.5.5': resolution: {integrity: sha512-DSu8oTPI0BJFH60jMOG9gM+oeNMoRALFmdAYg2PIXpL+Zbxd7L2GzQZtmf1jLy/8UBImkbB3D74TjiOBiLRK1w==} engines: {node: '>=6.0.0'} @@ -2661,6 +2668,10 @@ snapshots: chalk: 2.4.2 deepmerge: 4.3.1 + '@sendgrid/helpers@8.0.0': + dependencies: + deepmerge: 4.3.1 + '@sendgrid/mail@6.5.5': dependencies: '@sendgrid/client': 6.5.5 diff --git a/src/app.ts b/src/app.ts index 85ee64e..5f7c024 100755 --- a/src/app.ts +++ b/src/app.ts @@ -1,5 +1,4 @@ import express from "express"; -import hbs from "express-handlebars"; import cookieParser from "cookie-parser"; import routes from "./routes.js"; @@ -15,77 +14,16 @@ import { activityPubContentType, alternateActivityPubContentType, } from "./lib/activitypub.js"; -import getConfig from "./lib/config.js"; +import { HandlebarsSingleton } from "./lib/handlebars.js"; const app = express(); -const config = getConfig(); initEmailService().then((sendEmails) => (app.locals.sendEmails = sendEmails)); // View engine // -const hbsInstance = hbs.create({ - defaultLayout: "main", - partialsDir: ["views/partials/"], - layoutsDir: "views/layouts/", - runtimeOptions: { - data: { - domain: config.general.domain, - contactEmail: config.general.email, - siteName: config.general.site_name, - mailService: config.general.mail_service, - siteLogo: config.general.email_logo_url, - isFederated: config.general.is_federated || true, - }, - }, - helpers: { - plural: function (number: number, text: string) { - var singular = number === 1; - // If no text parameter was given, just return a conditional s. - if (typeof text !== "string") return singular ? "" : "s"; - // Split with regex into group1/group2 or group1(group3) - var match = text.match(/^([^()\/]+)(?:\/(.+))?(?:\((\w+)\))?/); - // If no match, just append a conditional s. - if (!match) return text + (singular ? "" : "s"); - // We have a good match, so fire away - return ( - (singular && match[1]) || // Singular case - match[2] || // Plural case: 'bagel/bagels' --> bagels - match[1] + (match[3] || "s") - ); // Plural case: 'bagel(s)' or 'bagel' --> bagels - }, - json: function (context: any) { - return JSON.stringify(context); - }, - }, -}); -app.locals.renderEmail = async function renderEmail( - template: string, - data: object -) { - const [html, text] = await Promise.all([ - hbsInstance.renderView( - `./views/emails/${template}Html.handlebars`, - { - cache: true, - layout: "email.handlebars", - ...data, - } - ), - hbsInstance.renderView( - `./views/emails/${template}Text.handlebars`, - { - cache: true, - layout: "email.handlebars", - ...data, - } - ), - ]); - return { html, text } -} - -app.engine("handlebars", hbsInstance.engine); +app.engine("handlebars", HandlebarsSingleton.instance.engine); app.set("view engine", "handlebars"); -app.set("hbsInstance", hbsInstance); +app.set("hbsInstance", HandlebarsSingleton.instance); // Static files // app.use(express.static("public")); diff --git a/src/lib/email.ts b/src/lib/email.ts index e7243aa..57f69f5 100644 --- a/src/lib/email.ts +++ b/src/lib/email.ts @@ -1,13 +1,15 @@ import sgMail from "@sendgrid/mail"; +import sgHelpers from "@sendgrid/helpers"; + import nodemailer, { Transporter } from "nodemailer"; import { getConfig } from "./config.js"; import SMTPTransport from "nodemailer/lib/smtp-transport/index.js"; import { exitWithError } from "./process.js"; -import { renderTemplate } from "./handlebars.js"; -import { ExpressHandlebars } from "express-handlebars"; +import { HandlebarsSingleton } from "./handlebars.js"; + const config = getConfig(); -type EmailTemplate = +type EmailTemplateName = | "addEventAttendee" | "addEventComment" | "createEvent" @@ -16,6 +18,7 @@ type EmailTemplate = | "deleteEvent" | "editEvent" | "eventGroupUpdated" + | "removeEventAttendee" | "subscribed" | "unattendEvent"; @@ -89,30 +92,6 @@ export const initEmailService = async (): Promise => { } }; -export const sendTemplatedEmail = async ( - hbs: ExpressHandlebars, - to: string, - bcc: string, - subject: string, - template: string, - data: object, -): Promise => { - const [html, text] = await Promise.all([ - hbs.renderView(`./views/emails/${template}Html.handlebars`, { - cache: true, - layout: "email.handlebars", - ...data, - }), - hbs.renderView(`./views/emails/${template}Text.handlebars`, { - cache: true, - layout: "email.handlebars", - ...data, - }), - ]); - - return await sendEmail(to, bcc, subject, text, html); -}; - export const sendEmail = async ( to: string | string[], bcc: string | string[] | undefined, @@ -132,11 +111,11 @@ export const sendEmail = async ( html, }); return true; - } catch (e: Error) { - if (e.response) { - console.error(e.response.body); + } catch (e: unknown | sgHelpers.classes.ResponseError) { + if (e instanceof sgHelpers.classes.ResponseError) { + console.error('sendgrid error', e.response.body); } else { - console.error(e); + console.error('sendgrid error', e); } return false; } @@ -164,15 +143,10 @@ export const sendEmail = async ( nodemailer.createTransport(nodemailerConfig); } await nodemailerTransporter.sendMail({ - envelope: { - from: config.general.email, - to, - bcc, - }, from: config.general.email, to, bcc, - subject, + subject: `${config.general.site_name}: ${subject}`, text, html, }); @@ -187,25 +161,42 @@ export const sendEmail = async ( }; export const sendEmailFromTemplate = async ( - to: string, - bcc: string, + to: string | string[], + bcc: string | string[] | undefined, subject: string, - template: EmailTemplate, - templateData: Record, - req: Request, + templateName: EmailTemplateName, + templateData: object, ): Promise => { - const html = await renderTemplate(req, `${template}/${template}Html`, { - siteName: config.general.site_name, - siteLogo: config.general.email_logo_url, - domain: config.general.domain, - cache: true, - layout: "email.handlebars", - ...templateData, - }); - const text = await renderTemplate( - req, - `${template}/${template}Text`, - templateData, - ); + const [html, text] = await Promise.all([ + HandlebarsSingleton.instance.renderView( + `./views/emails/${templateName}/${templateName}Html.handlebars`, + { + domain: config.general.domain, + contactEmail: config.general.email, + siteName: config.general.site_name, + mailService: config.general.mail_service, + siteLogo: config.general.email_logo_url, + isFederated: config.general.is_federated || true, + cache: true, + layout: "email.handlebars", + ...templateData, + } + ), + HandlebarsSingleton.instance.renderView( + `./views/emails/${templateName}/${templateName}Text.handlebars`, + { + domain: config.general.domain, + contactEmail: config.general.email, + siteName: config.general.site_name, + mailService: config.general.mail_service, + siteLogo: config.general.email_logo_url, + isFederated: config.general.is_federated || true, + cache: true, + layout: "email.handlebars", + ...templateData, + } + ), + ]); + return await sendEmail(to, bcc, subject, text, html); }; diff --git a/src/lib/handlebars.ts b/src/lib/handlebars.ts index 42f8010..6d4f796 100644 --- a/src/lib/handlebars.ts +++ b/src/lib/handlebars.ts @@ -1,50 +1,55 @@ -import { Request } from "express"; -import { ExpressHandlebars } from "express-handlebars"; +import hbs, { ExpressHandlebars } from "express-handlebars"; +import { RenderViewOptions } from "express-handlebars/types/index.js"; -export const renderTemplate = async ( - req: Request, - templateName: string, - data: Record, -): Promise => { - return new Promise((resolve, reject) => { - req.app - .get("hbsInstance") - .renderView( - `./views/emails/${templateName}.handlebars`, - data, - (err: any, html: string) => { - if (err) { - console.error(err); - reject(err); - } - resolve(html); +export class HandlebarsSingleton { + static #instance: HandlebarsSingleton; + hbsInstance: hbs.ExpressHandlebars; + + private constructor() { + this.hbsInstance = hbs.create({ + defaultLayout: "main", + partialsDir: ["views/partials/"], + layoutsDir: "views/layouts/", + helpers: { + plural: function (number: number, text: string) { + const singular = number === 1; + // If no text parameter was given, just return a conditional s. + if (typeof text !== "string") return singular ? "" : "s"; + // Split with regex into group1/group2 or group1(group3) + const match = text.match(/^([^()\/]+)(?:\/(.+))?(?:\((\w+)\))?/); + // If no match, just append a conditional s. + if (!match) return text + (singular ? "" : "s"); + // We have a good match, so fire away + return ( + (singular && match[1]) || // Singular case + match[2] || // Plural case: 'bagel/bagels' --> bagels + match[1] + (match[3] || "s") + ); // Plural case: 'bagel(s)' or 'bagel' --> bagels + }, + json: function (context: object) { + return JSON.stringify(context); }, - ); - }); -}; + }, + }); + } + + public static get instance(): HandlebarsSingleton { + if (!HandlebarsSingleton.#instance) { + HandlebarsSingleton.#instance = new HandlebarsSingleton(); + } + + return HandlebarsSingleton.#instance; + } + + public get engine(): ExpressHandlebars["engine"] { + return this.hbsInstance.engine; + } -export const renderEmail = async ( - hbsInstance: ExpressHandlebars, - templateName: string, - data: Record, -): Promise<{ html: string, text: string }> => { - const [html, text] = await Promise.all([ - hbsInstance.renderView( - `./views/emails/${templateName}Html.handlebars`, - { - cache: true, - layout: "email.handlebars", - ...data, - } - ), - hbsInstance.renderView( - `./views/emails/${templateName}Text.handlebars`, - { - cache: true, - layout: "email.handlebars", - ...data, - } - ), - ]); - return { html, text } + /** + * Finally, any singleton can define some business logic, which can be + * executed on its instance. + */ + public renderView(viewPath: string, options: RenderViewOptions): Promise { + return this.hbsInstance.renderView(viewPath, options); + } } diff --git a/src/routes.js b/src/routes.js index f609f94..d5b5877 100755 --- a/src/routes.js +++ b/src/routes.js @@ -9,8 +9,6 @@ import crypto from "crypto"; import request from "request"; import niceware from "niceware"; import ical from "ical"; -import sgMail from "@sendgrid/mail"; -import nodemailer from "nodemailer"; import fileUpload from "express-fileupload"; import Jimp from "jimp"; import schedule from "node-schedule"; @@ -19,20 +17,15 @@ import { broadcastDeleteMessage, processInbox, } from "./activitypub.js"; -import { renderEmail } from "./lib/handlebars.js"; import Event from "./models/Event.js"; import EventGroup from "./models/EventGroup.js"; import path from "path"; import { activityPubContentType } from "./lib/activitypub.js"; import { hashString } from "./util/generator.js"; -import { initEmailService, sendEmail } from "./lib/email.js"; +import { initEmailService, sendEmailFromTemplate } from "./lib/email.js"; const config = getConfig(); const domain = config.general.domain; -const contactEmail = config.general.email; -const siteName = config.general.site_name; -const mailService = config.general.mail_service; -const siteLogo = config.general.email_logo_url; const isFederated = config.general.is_federated || true; // This alphabet (used to generate all event, group, etc. IDs) is missing '-' @@ -329,14 +322,14 @@ router.post("/deleteevent/:eventID/:editToken", (req, res) => { "Sending emails to: " + attendeeEmails, ); - renderEmail( - req.app.get("hbsInstance"), - "deleteEvent/deleteEvent", + sendEmailFromTemplate( + attendeeEmails, + '', + `${event?.name} was deleted`, + "deleteEvent", { eventName: event?.name, }, - ).then( - ({ html, text }) => sendEmail(attendeeEmails, '', `${siteName}: ${event?.name} was deleted`, text, html) ).catch((e) => { console.error('error sending attendy email', e.toString()); res.status(500).end(); @@ -634,6 +627,10 @@ router.post("/attendevent/:eventID", async (req, res) => { }, ) .then((event) => { + if (!event) { + return res.sendStatus(404); + } + addToLog( "addEventAttendee", "success", @@ -641,9 +638,11 @@ router.post("/attendevent/:eventID", async (req, res) => { ); if (sendEmails) { if (req.body.attendeeEmail) { - renderEmail( - req.app.get("hbsInstance"), - "addEventAttendee/addEventAttendee", + sendEmailFromTemplate( + req.body.attendeeEmail, + '', + `You're RSVPed to ${event.name}`, + "addEventAttendee", { eventID: req.params.eventID, removalPassword: req.body.removalPassword, @@ -651,8 +650,6 @@ router.post("/attendevent/:eventID", async (req, res) => { req.body.removalPassword, ), }, - ).then( - ({ html, text }) => sendEmail(req.body.attendeeEmail, '', `${siteName}: You're RSVPed to ${event.name}`, text, html) ).catch((e) => { console.error('error sending addEventAttendee email', e.toString()); res.status(500).end(); @@ -686,11 +683,14 @@ router.get("/oneclickunattendevent/:eventID/:attendeeID", (req, res) => { ) { return res.sendStatus(200); } - Event.updateOne( + Event.findOneAndUpdate( { id: req.params.eventID }, { $pull: { attendees: { _id: req.params.attendeeID } } }, ) - .then((response) => { + .then((event) => { + if (!event) { + return res.sendStatus(404); + } addToLog( "oneClickUnattend", "success", @@ -699,14 +699,14 @@ router.get("/oneclickunattendevent/:eventID/:attendeeID", (req, res) => { if (sendEmails) { // currently this is never called because we don't have the email address if (req.body.attendeeEmail) { - renderEmail( - req.app.get("hbsInstance"), - "removeEventAttendee/removeEventAttendee", + sendEmailFromTemplate( + req.body.attendeeEmail, + '', + `You have been removed from an event`, + "removeEventAttendee", { - eventName: req.params.eventName, + eventName: event.name, }, - ).then( - ({ html, text }) => sendEmail(req.body.attendeeEmail, '', `${siteName}: You have been removed from an event`, text, html) ).catch((e) => { console.error('error sending removeEventAttendeeHtml email', e.toString()); res.status(500).end(); @@ -732,11 +732,14 @@ router.get("/oneclickunattendevent/:eventID/:attendeeID", (req, res) => { }); router.post("/removeattendee/:eventID/:attendeeID", (req, res) => { - Event.updateOne( + Event.findOneAndUpdate( { id: req.params.eventID }, { $pull: { attendees: { _id: req.params.attendeeID } } }, ) - .then((response) => { + .then((event) => { + if (!event) { + return res.sendStatus(404); + } addToLog( "removeEventAttendee", "success", @@ -745,14 +748,14 @@ router.post("/removeattendee/:eventID/:attendeeID", (req, res) => { if (sendEmails) { // currently this is never called because we don't have the email address if (req.body.attendeeEmail) { - renderEmail( - req.app.get("hbsInstance"), - "removeEventAttendee/removeEventAttendee", + sendEmailFromTemplate( + req.body.attendeeEmail, + '', + `You have been removed from an event`, + "removeEventAttendee", { - eventName: req.params.eventName, + eventName: event.name, }, - ).then( - ({ html, text }) => sendEmail(req.body.attendeeEmail, '', `${siteName}: You have been removed from an event`, text, html) ).catch((e) => { console.error('error sending removeEventAttendeeHtml email', e.toString()); res.status(500).end(); @@ -798,16 +801,16 @@ router.post("/subscribe/:eventGroupID", (req, res) => { eventGroup.subscribers.push(subscriber); eventGroup.save(); if (sendEmails) { - renderEmail( - req.app.get("hbsInstance"), - "subscribed/subscribed", + sendEmailFromTemplate( + subscriber.email, + '', + `You have subscribed to an event group`, + "subscribed", { eventGroupName: eventGroup.name, eventGroupID: eventGroup.id, emailAddress: encodeURIComponent(subscriber.email), }, - ).then( - ({ html, text }) => sendEmail(subscriber.email, '', `${siteName}: You have subscribed to an event group`, text, html) ).catch((e) => { console.error('error sending removeEventAttendeeHtml email', e.toString()); res.status(500).end(); @@ -875,7 +878,9 @@ router.post("/post/comment/:eventID", (req, res) => { id: req.params.eventID, }, function (err, event) { - if (!event) return; + if (!event) { + return res.sendStatus(404); + } event.comments.push(newComment); event .save() @@ -914,15 +919,15 @@ router.post("/post/comment/:eventID", (req, res) => { console.log( "Sending emails to: " + attendeeEmails, ); - renderEmail( - req.app.get("hbsInstance"), - "addEventComment/addEventComment", + sendEmailFromTemplate( + event?.creatorEmail || config.general.email, + attendeeEmails, + `New comment in ${event.name}`, + "addEventComment", { eventID: req.params.eventID, commentAuthor: req.body.commentAuthor, }, - ).then( - ({ html, text }) => sendEmail(attendeeEmails, '', `${siteName}: New comment in ${event.name}`, text, html) ).catch((e) => { console.error('error sending removeEventAttendeeHtml email', e.toString()); res.status(500).end(); @@ -967,7 +972,9 @@ router.post("/post/reply/:eventID/:commentID", (req, res) => { id: req.params.eventID, }, function (err, event) { - if (!event) return; + if (!event) { + return res.sendStatus(404); + } var parentComment = event.comments.id(commentID); parentComment.replies.push(newReply); event @@ -999,6 +1006,9 @@ router.post("/post/reply/:eventID/:commentID", (req, res) => { if (sendEmails) { Event.findOne({ id: req.params.eventID }).then( (event) => { + if (!event) { + return res.sendStatus(404); + } const attendeeEmails = event.attendees .filter( (o) => @@ -1009,15 +1019,15 @@ router.post("/post/reply/:eventID/:commentID", (req, res) => { console.log( "Sending emails to: " + attendeeEmails, ); - renderEmail( - req.app.get("hbsInstance"), - "addEventComment/addEventComment", + sendEmailFromTemplate( + event?.creatorEmail || config.general.email, + attendeeEmails, + `New comment in ${event.name}`, + "addEventComment", { eventID: req.params.eventID, commentAuthor: req.body.replyAuthor, }, - ).then( - ({ html, text }) => sendEmail(attendeeEmails, '', `${siteName}: New comment in ${event.name}`, text, html) ).catch((e) => { console.error('error sending removeEventAttendeeHtml email', e.toString()); res.status(500).end(); diff --git a/src/routes/event.ts b/src/routes/event.ts index de5cb4c..f97adc9 100644 --- a/src/routes/event.ts +++ b/src/routes/event.ts @@ -80,8 +80,8 @@ router.post( }); } - let eventID = generateEventID(); - let editToken = generateEditToken(); + const eventID = generateEventID(); + const editToken = generateEditToken(); let eventImageFilename; let isPartOfEventGroup = false; @@ -125,7 +125,7 @@ router.post( } // generate RSA keypair for ActivityPub - let { publicKey, privateKey } = generateRSAKeypair(); + const { publicKey, privateKey } = generateRSAKeypair(); const event = new Event({ id: eventID, @@ -202,11 +202,7 @@ router.post( { eventID, editToken, - siteName: res.locals.config?.general.site_name, - siteLogo: res.locals.config?.general.email_logo_url, - domain: res.locals.config?.general.domain, - }, - req, + } ); } // If the event was added to a group, send an email to any group @@ -237,17 +233,12 @@ router.post( `New event in ${eventGroup.name}`, "eventGroupUpdated", { - siteName: res.locals.config?.general.site_name, - siteLogo: - res.locals.config?.general.email_logo_url, - domain: res.locals.config?.general.domain, eventGroupName: eventGroup.name, eventName: event.name, eventID: event.id, eventGroupID: eventGroup.id, emailAddress: encodeURIComponent(emailAddress), - }, - req, + } ); }); } catch (err) { @@ -332,7 +323,7 @@ router.put( } // Token matches // If there is a new image, upload that first - let eventID = req.params.eventID; + const eventID = req.params.eventID; let eventImageFilename = event.image; if (req.file?.buffer) { Jimp.read(req.file.buffer) @@ -452,7 +443,7 @@ router.put( "Event " + req.params.eventID + " edited", ); // send update to ActivityPub subscribers - let attendees = updatedEventObject.attendees?.filter((el) => el.id); + const attendees = updatedEventObject.attendees?.filter((el) => el.id); // broadcast an identical message to all followers, will show in home timeline const guidObject = crypto.randomBytes(16).toString("hex"); const jsonObject = { @@ -495,21 +486,17 @@ router.put( if (req.app.locals.sendEmails) { const attendeeEmails = event.attendees ?.filter((o) => o.status === "attending" && o.email) - .map((o) => o.email); + .map((o) => o.email!); if (attendeeEmails?.length) { sendEmailFromTemplate( config.general.email, - attendeeEmails.join(","), + attendeeEmails, `${event.name} was just edited`, "editEvent", { diffText, eventID: req.params.eventID, - siteName: res.locals.config?.general.site_name, - siteLogo: res.locals.config?.general.email_logo_url, - domain: res.locals.config?.general.domain, }, - req, ); } } @@ -550,12 +537,12 @@ router.post( }); } - let eventID = generateEventID(); - let editToken = generateEditToken(); + const eventID = generateEventID(); + const editToken = generateEditToken(); - let iCalObject = ical.parseICS(req.file.buffer.toString("utf8")); + const iCalObject = ical.parseICS(req.file.buffer.toString("utf8")); - let importedEventData = iCalObject[Object.keys(iCalObject)[0]]; + const importedEventData = iCalObject[Object.keys(iCalObject)[0]]; let creatorEmail: string | undefined; if (req.body.creatorEmail) { @@ -620,11 +607,7 @@ router.post( { eventID, editToken, - siteName: res.locals.config?.general.site_name, - siteLogo: res.locals.config?.general.email_logo_url, - domain: res.locals.config?.general.domain, }, - req, ); } return res.json({ @@ -700,11 +683,7 @@ router.delete( "unattendEvent", { eventID: req.params.eventID, - siteName: res.locals.config?.general.site_name, - siteLogo: res.locals.config?.general.email_logo_url, - domain: res.locals.config?.general.domain, }, - req, ); } res.sendStatus(200); @@ -752,11 +731,7 @@ router.get( "unattendEvent", { event, - siteName: res.locals.config?.general.site_name, - siteLogo: res.locals.config?.general.email_logo_url, - domain: res.locals.config?.general.domain, }, - req, ); } return res.redirect(`/${req.params.eventID}?m=unattend`); diff --git a/src/routes/group.ts b/src/routes/group.ts index 9f4105c..c63413e 100644 --- a/src/routes/group.ts +++ b/src/routes/group.ts @@ -101,11 +101,7 @@ router.post( { eventGroupID: eventGroup.id, editToken: eventGroup.editToken, - siteName: res.locals.config?.general.site_name, - siteLogo: res.locals.config?.general.email_logo_url, - domain: res.locals.config?.general.domain, }, - req, ); } @@ -182,7 +178,7 @@ router.put( } // Token matches // If there is a new image, upload that first - let eventGroupID = req.params.eventGroupID; + const eventGroupID = req.params.eventGroupID; let eventGroupImageFilename = eventGroup.image; if (req.file?.buffer) { Jimp.read(req.file.buffer) diff --git a/src/routes/magicLink.ts b/src/routes/magicLink.ts index b4afca6..8d0f147 100644 --- a/src/routes/magicLink.ts +++ b/src/routes/magicLink.ts @@ -54,12 +54,8 @@ router.post("/magic-link/event/create", async (req: Request, res: Response) => { `Magic link to create an event`, "createEventMagicLink", { - token, - siteName: res.locals.config?.general.site_name, - siteLogo: res.locals.config?.general.email_logo_url, - domain: res.locals.config?.general.domain, + token }, - req, ); res.render("createEventMagicLink", { ...frontendConfig(res), -- cgit v1.2.3