diff options
author | lowercasename <raphaelkabo@gmail.com> | 2020-06-12 17:29:59 +0100 |
---|---|---|
committer | lowercasename <raphaelkabo@gmail.com> | 2020-06-12 17:29:59 +0100 |
commit | b9a71a9e009465791e7f0bbb8f1b4bdcf2ad02c6 (patch) | |
tree | b53f97a67d37576e16473393996019b06c9543b0 /routes.js | |
parent | d1e8debc5ca7e3c3f0424ccdd356576802f05cb8 (diff) |
More debugging to event deletion
Diffstat (limited to 'routes.js')
-rwxr-xr-x | routes.js | 1279 |
1 files changed, 643 insertions, 636 deletions
@@ -38,7 +38,7 @@ const ap = require('./activitypub.js'); // Extra marked renderer (used to render plaintext event description for page metadata) // Adapted from https://dustinpfister.github.io/2017/11/19/nodejs-marked/ // ? to ? helper -function htmlEscapeToText (text) { +function htmlEscapeToText(text) { return text.replace(/\&\#[0-9]*;|&/g, function (escapeCode) { if (escapeCode.match(/amp/)) { return '&'; @@ -47,21 +47,21 @@ function htmlEscapeToText (text) { }); } -function render_plain () { +function render_plain() { var render = new marked.Renderer(); // render just the text of a link, strong, em render.link = function (href, title, text) { return text; }; - render.strong = function(text) { + render.strong = function (text) { return text; } - render.em = function(text) { + render.em = function (text) { return text; } // render just the text of a paragraph render.paragraph = function (text) { - return htmlEscapeToText(text)+'\r\n'; + return htmlEscapeToText(text) + '\r\n'; }; // render nothing for headings, images, and br render.heading = function (text, level) { @@ -102,7 +102,8 @@ router.use(fileUpload()); const schedule = require('node-schedule'); -const deleteOldEvents = schedule.scheduleJob('59 23 * * *', function(fireDate){ +// const deleteOldEvents = schedule.scheduleJob('59 23 * * *', function(fireDate){ +function deleteOldEvents() { const too_old = moment.tz('Etc/UTC').subtract(7, 'days').toDate(); console.log("Old event deletion running! Deleting all events concluding before ", too_old); @@ -114,21 +115,21 @@ const deleteOldEvents = schedule.scheduleJob('59 23 * * *', function(fireDate){ console.log("=== ==="); oldEvents.forEach(event => { const deleteEventFromDB = (id) => { - Event.remove({"_id": id}) - .then(response => { - addToLog("deleteOldEvents", "success", "Old event "+id+" deleted"); - }).catch((err) => { - addToLog("deleteOldEvents", "error", "Attempt to delete old event "+id+" failed with error: " + err); - }); + Event.remove({ "_id": id }) + .then(response => { + addToLog("deleteOldEvents", "success", "Old event " + id + " deleted"); + }).catch((err) => { + addToLog("deleteOldEvents", "error", "Attempt to delete old event " + id + " failed with error: " + err); + }); } - if (event.image){ + if (event.image) { fs.unlink(global.appRoot + '/public/events/' + event.image, (err) => { if (err) { - addToLog("deleteOldEvents", "error", "Attempt to delete event image for old event "+event.id+" failed with error: " + err); + addToLog("deleteOldEvents", "error", "Attempt to delete event image for old event " + event.id + " failed with error: " + err); } // Image removed - addToLog("deleteOldEvents", "error", "Image deleted for old event "+event.id); + addToLog("deleteOldEvents", "error", "Image deleted for old event " + event.id); }) } // Check if event has ActivityPub fields @@ -138,8 +139,8 @@ const deleteOldEvents = schedule.scheduleJob('59 23 * * *', function(fireDate){ const jsonUpdateObject = JSON.parse(event.activityPubActor); const jsonEventObject = JSON.parse(event.activityPubEvent); // first broadcast AP messages, THEN delete from DB - ap.broadcastDeleteMessage(jsonUpdateObject, event.followers, event.id, function(statuses) { - ap.broadcastDeleteMessage(jsonEventObject, event.followers, event.id, function(statuses) { + ap.broadcastDeleteMessage(jsonUpdateObject, event.followers, event.id, function (statuses) { + ap.broadcastDeleteMessage(jsonEventObject, event.followers, event.id, function (statuses) { deleteEventFromDB(event._id); }); }); @@ -149,9 +150,11 @@ const deleteOldEvents = schedule.scheduleJob('59 23 * * *', function(fireDate){ } }) }).catch((err) => { - addToLog("deleteOldEvents", "error", "Attempt to delete old event "+event.id+" failed with error: " + err); + addToLog("deleteOldEvents", "error", "Attempt to delete old event " + event.id + " failed with error: " + err); }); -}); +} + +deleteOldEvents(); // FRONTEND ROUTES @@ -191,19 +194,19 @@ router.get('/new/event/public', (req, res) => { let isPublic = true; let isOrganisation = false; let isUnknownType = false; -// let eventType = req.params.eventType; -// if (eventType == "private"){ -// isPrivate = true; -// } -// else if (eventType == "public"){ -// isPublic = true; -// } -// else if (eventType == "organisation"){ -// isOrganisation = true; -// } -// else { -// isUnknownType = true; -// } + // let eventType = req.params.eventType; + // if (eventType == "private"){ + // isPrivate = true; + // } + // else if (eventType == "public"){ + // isPublic = true; + // } + // else if (eventType == "organisation"){ + // isOrganisation = true; + // } + // else { + // isUnknownType = true; + // } res.render('newevent', { title: 'New event', isPrivate: isPrivate, @@ -220,7 +223,7 @@ router.get('/new/event/public', (req, res) => { // return the JSON for the featured/pinned post for this event router.get('/:eventID/featured', (req, res) => { if (!isFederated) return res.sendStatus(404); - const {eventID} = req.params; + const { eventID } = req.params; const guidObject = crypto.randomBytes(16).toString('hex'); const featured = { "@context": "https://www.w3.org/ns/activitystreams", @@ -236,34 +239,34 @@ router.get('/:eventID/featured', (req, res) => { // return the JSON for a given activitypub message router.get('/:eventID/m/:hash', (req, res) => { if (!isFederated) return res.sendStatus(404); - const {hash, eventID} = req.params; + const { hash, eventID } = req.params; const id = `https://${domain}/${eventID}/m/${hash}`; Event.findOne({ id: eventID }) - .then((event) => { - if (!event) { - res.status(404); - res.render('404', { url: req.url }); - } - else { - const message = event.activityPubMessages.find(el => el.id === id); - if (message) { - return res.json(JSON.parse(message.content)); + .then((event) => { + if (!event) { + res.status(404); + res.render('404', { url: req.url }); } else { - res.status(404); - return res.render('404', { url: req.url }); + const message = event.activityPubMessages.find(el => el.id === id); + if (message) { + return res.json(JSON.parse(message.content)); + } + else { + res.status(404); + return res.render('404', { url: req.url }); + } } - } - }) - .catch((err) => { - addToLog("getActivityPubMessage", "error", "Attempt to get Activity Pub Message for " + id + " failed with error: " + err); - res.status(404); - res.render('404', { url: req.url }); - return; - }); + }) + .catch((err) => { + addToLog("getActivityPubMessage", "error", "Attempt to get Activity Pub Message for " + id + " failed with error: " + err); + res.status(404); + res.render('404', { url: req.url }); + return; + }); }); // return the webfinger record required for the initial activitypub handshake @@ -275,40 +278,40 @@ router.get('/.well-known/webfinger', (req, res) => { } else { // "foo@domain" - let activityPubAccount = resource.replace('acct:',''); + let activityPubAccount = resource.replace('acct:', ''); // "foo" - let eventID = activityPubAccount.replace(/@.*/,''); + let eventID = activityPubAccount.replace(/@.*/, ''); Event.findOne({ id: eventID }) - .then((event) => { - if (!event) { + .then((event) => { + if (!event) { + res.status(404); + res.render('404', { url: req.url }); + } + else { + res.json(ap.createWebfinger(eventID, domain)); + } + }) + .catch((err) => { + addToLog("renderWebfinger", "error", "Attempt to render webfinger for " + req.params.eventID + " failed with error: " + err); res.status(404); res.render('404', { url: req.url }); - } - else { - res.json(ap.createWebfinger(eventID, domain)); - } - }) - .catch((err) => { - addToLog("renderWebfinger", "error", "Attempt to render webfinger for " + req.params.eventID + " failed with error: " + err); - res.status(404); - res.render('404', { url: req.url }); - return; - }); + return; + }); } }); router.get('/:eventID', (req, res) => { Event.findOne({ id: req.params.eventID - }) + }) .populate('eventGroup') .then((event) => { if (event) { const parsedLocation = event.location.replace(/\s+/g, '+'); let displayDate; - if (moment.tz(event.end, event.timezone).isSame(event.start, 'day')){ + if (moment.tz(event.end, event.timezone).isSame(event.start, 'day')) { // Happening during one day displayDate = moment.tz(event.start, event.timezone).format('dddd D MMMM YYYY [<span class="text-muted">from</span>] h:mm a') + moment.tz(event.end, event.timezone).format(' [<span class="text-muted">to</span>] h:mm a [<span class="text-muted">](z)[</span>]'); } @@ -320,11 +323,11 @@ router.get('/:eventID', (req, res) => { let parsedStart = moment.tz(event.start, event.timezone).format('YYYYMMDD[T]HHmmss'); let parsedEnd = moment.tz(event.end, event.timezone).format('YYYYMMDD[T]HHmmss'); let eventHasConcluded = false; - if (moment.tz(event.end, event.timezone).isBefore(moment.tz(event.timezone))){ + if (moment.tz(event.end, event.timezone).isBefore(moment.tz(event.timezone))) { eventHasConcluded = true; } let eventHasBegun = false; - if (moment.tz(event.start, event.timezone).isBefore(moment.tz(event.timezone))){ + if (moment.tz(event.start, event.timezone).isBefore(moment.tz(event.timezone))) { eventHasBegun = true; } let fromNow = moment.tz(event.start, event.timezone).fromNow(); @@ -334,14 +337,14 @@ router.get('/:eventID', (req, res) => { let escapedName = event.name.replace(/\s+/g, '+'); let eventHasCoverImage = false; - if( event.image ) { + if (event.image) { eventHasCoverImage = true; } else { eventHasCoverImage = false; } let eventHasHost = false; - if( event.hostName ) { + if (event.hostName) { eventHasHost = true; } else { @@ -350,7 +353,7 @@ router.get('/:eventID', (req, res) => { let firstLoad = false; if (event.firstLoad === true) { firstLoad = true; - Event.findOneAndUpdate({id: req.params.eventID}, {firstLoad: false}, function(err, raw) { + Event.findOneAndUpdate({ id: req.params.eventID }, { firstLoad: false }, function (err, raw) { if (err) { res.send(err); } @@ -363,7 +366,7 @@ router.get('/:eventID', (req, res) => { console.log("No edit token set"); } else { - if (req.query.e === eventEditToken){ + if (req.query.e === eventEditToken) { editingEnabled = true; } else { @@ -371,16 +374,16 @@ router.get('/:eventID', (req, res) => { } } } - let eventAttendees = event.attendees.sort((a,b) => (a.name > b.name) ? 1 : ((b.name > a.name) ? -1 : 0)) - .map(el => { - if (!el.id) { - el.id = el._id; - } - return el; - }) - .filter((obj, pos, arr) => { + let eventAttendees = event.attendees.sort((a, b) => (a.name > b.name) ? 1 : ((b.name > a.name) ? -1 : 0)) + .map(el => { + if (!el.id) { + el.id = el._id; + } + return el; + }) + .filter((obj, pos, arr) => { return arr.map(mapObj => mapObj.id).indexOf(obj.id) === pos; - }); + }); let spotsRemaining, noMoreSpots; if (event.maxAttendees) { @@ -391,7 +394,7 @@ router.get('/:eventID', (req, res) => { } let metadata = { title: event.name, - description: marked(event.description, { renderer: render_plain()}).split(" ").splice(0,40).join(" ").trim(), + description: marked(event.description, { renderer: render_plain() }).split(" ").splice(0, 40).join(" ").trim(), image: (eventHasCoverImage ? `https://${domain}/events/` + event.image : null), url: `https://${domain}/` + req.params.eventID }; @@ -450,7 +453,7 @@ router.get('/:eventID/followers', (req, res) => { const eventID = req.params.eventID; Event.findOne({ id: eventID - }) + }) .then((event) => { if (event) { const followers = event.followers.map(el => el.actorId); @@ -465,7 +468,7 @@ router.get('/:eventID/followers', (req, res) => { "orderedItems": followers, "id": `https://${domain}/${eventID}/followers?page=1` }, - "@context":["https://www.w3.org/ns/activitystreams"] + "@context": ["https://www.w3.org/ns/activitystreams"] }; return res.json(followersCollection); } @@ -478,7 +481,7 @@ router.get('/:eventID/followers', (req, res) => { router.get('/group/:eventGroupID', (req, res) => { EventGroup.findOne({ id: req.params.eventGroupID - }) + }) .then(async (eventGroup) => { if (eventGroup) { let parsedDescription = marked(eventGroup.description); @@ -487,31 +490,31 @@ router.get('/group/:eventGroupID', (req, res) => { let escapedName = eventGroup.name.replace(/\s+/g, '+'); let eventGroupHasCoverImage = false; - if( eventGroup.image ) { + if (eventGroup.image) { eventGroupHasCoverImage = true; } else { eventGroupHasCoverImage = false; } let eventGroupHasHost = false; - if( eventGroup.hostName ) { + if (eventGroup.hostName) { eventGroupHasHost = true; } else { eventGroupHasHost = false; } - let events = await Event.find({eventGroup: eventGroup._id}).sort('start') + let events = await Event.find({ eventGroup: eventGroup._id }).sort('start') events.forEach(event => { - if (moment.tz(event.end, event.timezone).isSame(event.start, 'day')){ + if (moment.tz(event.end, event.timezone).isSame(event.start, 'day')) { // Happening during one day event.displayDate = moment.tz(event.start, event.timezone).format('D MMM YYYY'); } else { event.displayDate = moment.tz(event.start, event.timezone).format('D MMM YYYY') + moment.tz(event.end, event.timezone).format(' - D MMM YYYY'); } - if (moment.tz(event.end, event.timezone).isBefore(moment.tz(event.timezone))){ + if (moment.tz(event.end, event.timezone).isBefore(moment.tz(event.timezone))) { event.eventHasConcluded = true; } else { event.eventHasConcluded = false; @@ -526,7 +529,7 @@ router.get('/group/:eventGroupID', (req, res) => { let firstLoad = false; if (eventGroup.firstLoad === true) { firstLoad = true; - EventGroup.findOneAndUpdate({id: req.params.eventGroupID}, {firstLoad: false}, function(err, raw) { + EventGroup.findOneAndUpdate({ id: req.params.eventGroupID }, { firstLoad: false }, function (err, raw) { if (err) { res.send(err); } @@ -539,7 +542,7 @@ router.get('/group/:eventGroupID', (req, res) => { console.log("No edit token set"); } else { - if (req.query.e === eventGroupEditToken){ + if (req.query.e === eventGroupEditToken) { editingEnabled = true; } else { @@ -549,7 +552,7 @@ router.get('/group/:eventGroupID', (req, res) => { } let metadata = { title: eventGroup.name, - description: marked(eventGroup.description, { renderer: render_plain()}).split(" ").splice(0,40).join(" ").trim(), + description: marked(eventGroup.description, { renderer: render_plain() }).split(" ").splice(0, 40).join(" ").trim(), image: (eventGroupHasCoverImage ? `https://${domain}/events/` + eventGroup.image : null), url: `https://${domain}/` + req.params.eventID }; @@ -587,7 +590,7 @@ router.get('/group/:eventGroupID', (req, res) => { router.get('/exportevent/:eventID', (req, res) => { Event.findOne({ id: req.params.eventID - }) + }) .populate('eventGroup') .then((event) => { if (event) { @@ -633,7 +636,7 @@ router.post('/newevent', async (req, res) => { let eventID = shortid.generate(); // this is a hack, activitypub does not like "-" in ids so we are essentially going // to have a 63-character alphabet instead of a 64-character one - eventID = eventID.replace(/-/g,'_'); + eventID = eventID.replace(/-/g, '_'); let editToken = randomstring.generate(); let eventImageFilename = ""; let isPartOfEventGroup = false; @@ -688,7 +691,7 @@ router.post('/newevent', async (req, res) => { firstLoad: true, activityPubActor: ap.createActivityPubActor(eventID, domain, pair.public, marked(req.body.eventDescription), req.body.eventName, req.body.eventLocation, eventImageFilename, startUTC, endUTC, req.body.timezone), activityPubEvent: ap.createActivityPubEvent(req.body.eventName, startUTC, endUTC, req.body.timezone, req.body.eventDescription, req.body.eventLocation), - activityPubMessages: [ { id: `https://${domain}/${eventID}/m/featuredPost`, content: JSON.stringify(ap.createFeaturedPost(eventID, req.body.eventName, startUTC, endUTC, req.body.timezone, req.body.eventDescription, req.body.eventLocation)) } ], + activityPubMessages: [{ id: `https://${domain}/${eventID}/m/featuredPost`, content: JSON.stringify(ap.createFeaturedPost(eventID, req.body.eventName, startUTC, endUTC, req.body.timezone, req.body.eventDescription, req.body.eventLocation)) }], publicKey: pair.public, privateKey: pair.private }); @@ -697,7 +700,7 @@ router.post('/newevent', async (req, res) => { addToLog("createEvent", "success", "Event " + eventID + "created"); // Send email with edit link if (sendEmails) { - req.app.get('hbsInstance').renderView('./views/emails/createevent.handlebars', {eventID, editToken, siteName, siteLogo, domain, cache: true, layout: 'email.handlebars'}, function(err, html) { + req.app.get('hbsInstance').renderView('./views/emails/createevent.handlebars', { eventID, editToken, siteName, siteLogo, domain, cache: true, layout: 'email.handlebars' }, function (err, html) { const msg = { to: req.body.creatorEmail, from: { @@ -714,11 +717,11 @@ router.post('/newevent', async (req, res) => { }); } res.writeHead(302, { - 'Location': '/' + eventID + '?e=' + editToken + 'Location': '/' + eventID + '?e=' + editToken }); res.end(); }) - .catch((err) => { res.status(500).send('Database error, please try again :( - ' + err); addToLog("createEvent", "error", "Attempt to create event failed with error: " + err);}); + .catch((err) => { res.status(500).send('Database error, please try again :( - ' + err); addToLog("createEvent", "error", "Attempt to create event failed with error: " + err); }); }); router.post('/importevent', (req, res) => { @@ -763,19 +766,19 @@ router.post('/importevent', (req, res) => { addToLog("createEvent", "success", "Event " + eventID + " created"); // Send email with edit link if (sendEmails) { - req.app.get('hbsInstance').renderView('./views/emails/createevent.handlebars', {eventID, editToken, siteName, siteLogo, domain, cache: true, layout: 'email.handlebars'}, function(err, html) { + req.app.get('hbsInstance').renderView('./views/emails/createevent.handlebars', { eventID, editToken, siteName, siteLogo, domain, cache: true, layout: 'email.handlebars' }, function (err, html) { const msg = { - to: req.body.creatorEmail, - from: { - name: siteName, - email: contactEmail, - }, - subject: `${siteName}: ${importedEventData.summary}`, - html, + to: req.body.creatorEmail, + from: { + name: siteName, + email: contactEmail, + }, + subject: `${siteName}: ${importedEventData.summary}`, + html, }; sgMail.send(msg).catch(e => { - console.error(e.toString()); - res.status(500).end(); + console.error(e.toString()); + res.status(500).end(); }); }); } @@ -784,7 +787,7 @@ router.post('/importevent', (req, res) => { }); res.end(); }) - .catch((err) => { res.send('Database error, please try again :('); addToLog("createEvent", "error", "Attempt to create event failed with error: " + err);}); + .catch((err) => { res.send('Database error, please try again :('); addToLog("createEvent", "error", "Attempt to create event failed with error: " + err); }); } else { console.log("Files array is empty!") @@ -823,7 +826,7 @@ router.post('/neweventgroup', (req, res) => { addToLog("createEventGroup", "success", "Event group " + eventGroupID + " created"); // Send email with edit link if (sendEmails) { - req.app.get('hbsInstance').renderView('./views/emails/createeventgroup.handlebars', {eventGroupID, editToken, siteName, siteLogo, domain, cache: true, layout: 'email.handlebars'}, function(err, html) { + req.app.get('hbsInstance').renderView('./views/emails/createeventgroup.handlebars', { eventGroupID, editToken, siteName, siteLogo, domain, cache: true, layout: 'email.handlebars' }, function (err, html) { const msg = { to: req.body.creatorEmail, from: { @@ -844,7 +847,7 @@ router.post('/neweventgroup', (req, res) => { }); res.end(); }) - .catch((err) => { res.send('Database error, please try again :( - ' + err); addToLog("createEvent", "error", "Attempt to create event failed with error: " + err);}); + .catch((err) => { res.send('Database error, please try again :( - ' + err); addToLog("createEvent", "error", "Attempt to create event failed with error: " + err); }); }); router.post('/editevent/:eventID/:editToken', (req, res) => { @@ -852,220 +855,220 @@ router.post('/editevent/:eventID/:editToken', (req, res) => { let submittedEditToken = req.params.editToken; Event.findOne(({ id: req.params.eventID, - })) - .then(async (event) => { - if (event.editToken === submittedEditToken) { - // Token matches - - // If there is a new image, upload that first - let eventID = req.params.eventID; - let eventImageFilename = event.image; - if (req.files && Object.keys(req.files).length !== 0) { - let eventImageBuffer = req.files.imageUpload.data; - Jimp.read(eventImageBuffer, (err, img) => { - if (err) throw err; - img - .resize(920, Jimp.AUTO) // resize - .quality(80) // set JPEG - .write('./public/events/' + eventID + '.jpg'); // save - }); - eventImageFilename = eventID + '.jpg'; - } - let startUTC = moment.tz(req.body.eventStart, 'D MMMM YYYY, hh:mm a', req.body.timezone); - let endUTC = moment.tz(req.body.eventEnd, 'D MMMM YYYY, hh:mm a', req.body.timezone); - - let isPartOfEventGroup = false; - let eventGroup; - if (req.body.eventGroupCheckbox) { - eventGroup = await EventGroup.findOne({ - id: req.body.eventGroupID, - editToken: req.body.eventGroupEditToken - }) - if (eventGroup) { - isPartOfEventGroup = true; - } - } - const updatedEvent = { - name: req.body.eventName, - location: req.body.eventLocation, - start: startUTC, - end: endUTC, - timezone: req.body.timezone, - description: req.body.eventDescription, - url: req.body.eventURL, - hostName: req.body.hostName, - image: eventImageFilename, - usersCanAttend: req.body.joinCheckbox ? true : false, - showUsersList: req.body.guestlistCheckbox ? true : false, - usersCanComment: req.body.interactionCheckbox ? true : false, - maxAttendees: req.body.maxAttendeesCheckbox ? req.body.maxAttendees : null, - eventGroup: isPartOfEventGroup ? eventGroup._id : null, - activityPubActor: ap.updateActivityPubActor(JSON.parse(event.activityPubActor || null), req.body.eventDescription, req.body.eventName, req.body.eventLocation, eventImageFilename, startUTC, endUTC, req.body.timezone), - activityPubEvent: ap.updateActivityPubEvent(JSON.parse(event.activityPubEvent || null), req.body.eventName, req.body.startUTC, req.body.endUTC, req.body.timezone), - } - let diffText = '<p>This event was just updated with new information.</p><ul>'; - let displayDate; - if (event.name !== updatedEvent.name) { - diffText += `<li>the event name changed to ${updatedEvent.name}</li>`; - } - if (event.location !== updatedEvent.location) { - diffText += `<li>the location changed to ${updatedEvent.location}</li>`; - } - if (event.start.toISOString() !== updatedEvent.start.toISOString()) { - displayDate = moment.tz(updatedEvent.start, updatedEvent.timezone).format('dddd D MMMM YYYY h:mm a'); - diffText += `<li>the start time changed to ${displayDate}</li>`; - } - if (event.end.toISOString() !== updatedEvent.end.toISOString()) { - displayDate = moment.tz(updatedEvent.end, updatedEvent.timezone).format('dddd D MMMM YYYY h:mm a'); - diffText += `<li>the end time changed to ${displayDate}</li>`; - } - if (event.timezone !== updatedEvent.timezone) { - console.log(typeof event.timezone, JSON.stringify(event.timezone), JSON.stringify(updatedEvent.timezone)) - diffText += `<li>the time zone changed to ${updatedEvent.timezone}</li>`; - } - if (event.description !== updatedEvent.description) { - diffText += `<li>the event description changed</li>`; - } - diffText += `</ul>`; - Event.findOneAndUpdate({id: req.params.eventID}, updatedEvent, function(err, raw) { - if (err) { - addToLog("editEvent", "error", "Attempt to edit event " + req.params.eventID + " failed with error: " + err); - res.send(err); + })) + .then(async (event) => { + if (event.editToken === submittedEditToken) { + // Token matches + + // If there is a new image, upload that first + let eventID = req.params.eventID; + let eventImageFilename = event.image; + if (req.files && Object.keys(req.files).length !== 0) { + let eventImageBuffer = req.files.imageUpload.data; + Jimp.read(eventImageBuffer, (err, img) => { + if (err) throw err; + img + .resize(920, Jimp.AUTO) // resize + .quality(80) // set JPEG + .write('./public/events/' + eventID + '.jpg'); // save + }); + eventImageFilename = eventID + '.jpg'; } - }) - .then(() => { - addToLog("editEvent", "success", "Event " + req.params.eventID + " edited"); - // send update to ActivityPub subscribers - Event.findOne({id: req.params.eventID}, function(err,event) { - if (!event) return; - let attendees = event.attendees.filter(el => el.id); - if (!err) { - // broadcast an identical message to all followers, will show in home timeline - const guidObject = crypto.randomBytes(16).toString('hex'); - const jsonObject = { - "@context": "https://www.w3.org/ns/activitystreams", - "id": `https://${domain}/${req.params.eventID}/m/${guidObject}`, - "name": `RSVP to ${event.name}`, - "type": "Note", - 'cc': 'https://www.w3.org/ns/activitystreams#Public', - "content": `${diffText} See here: <a href="https://${domain}/${req.params.eventID}">https://${domain}/${req.params.eventID}</a>`, - } - ap.broadcastCreateMessage(jsonObject, event.followers, eventID) - // also broadcast an Update profile message to all followers so that at least Mastodon servers will update the local profile information - const jsonUpdateObject = JSON.parse(event.activityPubActor); - ap.broadcastUpdateMessage(jsonUpdateObject, event.followers, eventID) - // also broadcast an Update/Event for any calendar apps that are consuming our Events - const jsonEventObject = JSON.parse(event.activityPubEvent); - ap.broadcastUpdateMessage(jsonEventObject, event.followers, eventID) - - // DM to attendees - for (const attendee of attendees) { - const jsonObject = { - "@context": "https://www.w3.org/ns/activitystreams", - "name": `RSVP to ${event.name}`, - "type": "Note", - "content": `<span class=\"h-card\"><a href="${attendee.id}" class="u-url mention">@<span>${attendee.name}</span></a></span> ${diffText} See here: <a href="https://${domain}/${req.params.eventID}">https://${domain}/${req.params.eventID}</a>`, - "tag":[{"type":"Mention","href":attendee.id,"name":attendee.name}] - } - // send direct message to user - ap.sendDirectMessage(jsonObject, attendee.id, eventID); - } + let startUTC = moment.tz(req.body.eventStart, 'D MMMM YYYY, hh:mm a', req.body.timezone); + let endUTC = moment.tz(req.body.eventEnd, 'D MMMM YYYY, hh:mm a', req.body.timezone); + + let isPartOfEventGroup = false; + let eventGroup; + if (req.body.eventGroupCheckbox) { + eventGroup = await EventGroup.findOne({ + id: req.body.eventGroupID, + editToken: req.body.eventGroupEditToken + }) + if (eventGroup) { + isPartOfEventGroup = true; + } + } + const updatedEvent = { + name: req.body.eventName, + location: req.body.eventLocation, + start: startUTC, + end: endUTC, + timezone: req.body.timezone, + description: req.body.eventDescription, + url: req.body.eventURL, + hostName: req.body.hostName, + image: eventImageFilename, + usersCanAttend: req.body.joinCheckbox ? true : false, + showUsersList: req.body.guestlistCheckbox ? true : false, + usersCanComment: req.body.interactionCheckbox ? true : false, + maxAttendees: req.body.maxAttendeesCheckbox ? req.body.maxAttendees : null, + eventGroup: isPartOfEventGroup ? eventGroup._id : null, + activityPubActor: ap.updateActivityPubActor(JSON.parse(event.activityPubActor || null), req.body.eventDescription, req.body.eventName, req.body.eventLocation, eventImageFilename, startUTC, endUTC, req.body.timezone), + activityPubEvent: ap.updateActivityPubEvent(JSON.parse(event.activityPubEvent || null), req.body.eventName, req.body.startUTC, req.body.endUTC, req.body.timezone), + } + let diffText = '<p>This event was just updated with new information.</p><ul>'; + let displayDate; + if (event.name !== updatedEvent.name) { + diffText += `<li>the event name changed to ${updatedEvent.name}</li>`; + } + if (event.location !== updatedEvent.location) { + diffText += `<li>the location changed to ${updatedEvent.location}</li>`; + } + if (event.start.toISOString() !== updatedEvent.start.toISOString()) { + displayDate = moment.tz(updatedEvent.start, updatedEvent.timezone).format('dddd D MMMM YYYY h:mm a'); + diffText += `<li>the start time changed to ${displayDate}</li>`; + } + if (event.end.toISOString() !== updatedEvent.end.toISOString()) { + displayDate = moment.tz(updatedEvent.end, updatedEvent.timezone).format('dddd D MMMM YYYY h:mm a'); + diffText += `<li>the end time changed to ${displayDate}</li>`; + } + if (event.timezone !== updatedEvent.timezone) { + console.log(typeof event.timezone, JSON.stringify(event.timezone), JSON.stringify(updatedEvent.timezone)) + diffText += `<li>the time zone changed to ${updatedEvent.timezone}</li>`; + } + if (event.description !== updatedEvent.description) { + diffText += `<li>the event description changed</li>`; + } + diffText += `</ul>`; + Event.findOneAndUpdate({ id: req.params.eventID }, updatedEvent, function (err, raw) { + if (err) { + addToLog("editEvent", "error", "Attempt to edit event " + req.params.eventID + " failed with error: " + err); + res.send(err); } }) - if (sendEmails) { - Event.findOne({id: req.params.eventID}).distinct('attendees.email', function(error, ids) { - let attendeeEmails = ids; - if (!error && attendeeEmails !== ""){ - console.log("Sending emails to: " + attendeeEmails); - req.app.get('hbsInstance').renderView('./views/emails/editevent.handlebars', {diffText, eventID: req.params.eventID, siteName, siteLogo, domain, cache: true, layout: 'email.handlebars'}, function(err, html) { - const msg = { - to: attendeeEmails, - from: { - name: siteName, - email: contactEmail, - }, - subject: `${siteName}: ${event.name} was just edited`, - html, - }; - sgMail.sendMultiple(msg).catch(e => { - console.error(e.toString()); - res.status(500).end(); - }); - }); - } - else { - console.log("Nothing to send!"); + .then(() => { + addToLog("editEvent", "success", "Event " + req.params.eventID + " edited"); + // send update to ActivityPub subscribers + Event.findOne({ id: req.params.eventID }, function (err, event) { + if (!event) return; + let attendees = event.attendees.filter(el => el.id); + if (!err) { + // broadcast an identical message to all followers, will show in home timeline + const guidObject = crypto.randomBytes(16).toString('hex'); + const jsonObject = { + "@context": "https://www.w3.org/ns/activitystreams", + "id": `https://${domain}/${req.params.eventID}/m/${guidObject}`, + "name": `RSVP to ${event.name}`, + "type": "Note", + 'cc': 'https://www.w3.org/ns/activitystreams#Public', + "content": `${diffText} See here: <a href="https://${domain}/${req.params.eventID}">https://${domain}/${req.params.eventID}</a>`, + } + ap.broadcastCreateMessage(jsonObject, event.followers, eventID) + // also broadcast an Update profile message to all followers so that at least Mastodon servers will update the local profile information + const jsonUpdateObject = JSON.parse(event.activityPubActor); + ap.broadcastUpdateMessage(jsonUpdateObject, event.followers, eventID) + // also broadcast an Update/Event for any calendar apps that are consuming our Events + const jsonEventObject = JSON.parse(event.activityPubEvent); + ap.broadcastUpdateMessage(jsonEventObject, event.followers, eventID) + + // DM to attendees + for (const attendee of attendees) { + const jsonObject = { + "@context": "https://www.w3.org/ns/activitystreams", + "name": `RSVP to ${event.name}`, + "type": "Note", + "content": `<span class=\"h-card\"><a href="${attendee.id}" class="u-url mention">@<span>${attendee.name}</span></a></span> ${diffText} See here: <a href="https://${domain}/${req.params.eventID}">https://${domain}/${req.params.eventID}</a>`, + "tag": [{ "type": "Mention", "href": attendee.id, "name": attendee.name }] + } + // send direct message to user + ap.sendDirectMessage(jsonObject, attendee.id, eventID); + } + } + }) + if (sendEmails) { + Event.findOne({ id: req.params.eventID }).distinct('attendees.email', function (error, ids) { + let attendeeEmails = ids; + if (!error && attendeeEmails !== "") { + console.log("Sending emails to: " + attendeeEmails); + req.app.get('hbsInstance').renderView('./views/emails/editevent.handlebars', { diffText, eventID: req.params.eventID, siteName, siteLogo, domain, cache: true, layout: 'email.handlebars' }, function (err, html) { + const msg = { + to: attendeeEmails, + from: { + name: siteName, + email: contactEmail, + }, + subject: `${siteName}: ${event.name} was just edited`, + html, + }; + sgMail.sendMultiple(msg).catch(e => { + console.error(e.toString()); + res.status(500).end(); + }); + }); + } + else { + console.log("Nothing to send!"); + } + }) } + res.writeHead(302, { + 'Location': '/' + req.params.eventID + '?e=' + req.params.editToken + }); + res.end(); }) - } - res.writeHead(302, { - 'Location': '/' + req.params.eventID + '?e=' + req.params.editToken - }); - res.end(); - }) - .catch((err) => { console.error(err); res.send('Sorry! Something went wrong!'); addToLog("editEvent", "error", "Attempt to edit event " + req.params.eventID + " failed with error: " + err);}); - } - else { - // Token doesn't match - res.send('Sorry! Something went wrong'); - addToLog("editEvent", "error", "Attempt to edit event " + req.params.eventID + " failed with error: token does not match"); - } - }) - .catch((err) => { console.error(err); res.send('Sorry! Something went wrong!'); addToLog("editEvent", "error", "Attempt to edit event " + req.params.eventID + " failed with error: " + err);}); + .catch((err) => { console.error(err); res.send('Sorry! Something went wrong!'); addToLog("editEvent", "error", "Attempt to edit event " + req.params.eventID + " failed with error: " + err); }); + } + else { + // Token doesn't match + res.send('Sorry! Something went wrong'); + addToLog("editEvent", "error", "Attempt to edit event " + req.params.eventID + " failed with error: token does not match"); + } + }) + .catch((err) => { console.error(err); res.send('Sorry! Something went wrong!'); addToLog("editEvent", "error", "Attempt to edit event " + req.params.eventID + " failed with error: " + err); }); }); router.post('/editeventgroup/:eventGroupID/:editToken', (req, res) => { let submittedEditToken = req.params.editToken; EventGroup.findOne(({ id: req.params.eventGroupID, - })) - .then((eventGroup) => { - if (eventGroup.editToken === submittedEditToken) { - // Token matches - - // If there is a new image, upload that first - let eventGroupID = req.params.eventGroupID; - let eventGroupImageFilename = eventGroup.image; - if (req.files && Object.keys(req.files).length !== 0) { - let eventImageBuffer = req.files.eventGroupImageUpload.data; - Jimp.read(eventImageBuffer, (err, img) => { - if (err) throw err; - img - .resize(920, Jimp.AUTO) // resize - .quality(80) // set JPEG - .write('./public/events/' + eventGroupID + '.jpg'); // save - }); - eventGroupImageFilename = eventGroupID + '.jpg'; + })) + .then((eventGroup) => { + if (eventGroup.editToken === submittedEditToken) { + // Token matches + + // If there is a new image, upload that first + let eventGroupID = req.params.eventGroupID; + let eventGroupImageFilename = eventGroup.image; + if (req.files && Object.keys(req.files).length !== 0) { + let eventImageBuffer = req.files.eventGroupImageUpload.data; + Jimp.read(eventImageBuffer, (err, img) => { + if (err) throw err; + img + .resize(920, Jimp.AUTO) // resize + .quality(80) // set JPEG + .write('./public/events/' + eventGroupID + '.jpg'); // save + }); + eventGroupImageFilename = eventGroupID + '.jpg'; + } + const updatedEventGroup = { + name: req.body.eventGroupName, + description: req.body.eventGroupDescription, + url: req.body.eventGroupURL, + hostName: req.body.hostName, + image: eventGroupImageFilename + } + EventGroup.findOneAndUpdate({ id: req.params.eventGroupID }, updatedEventGroup, function (err, raw) { + if (err) { + addToLog("editEventGroup", "error", "Attempt to edit event group " + req.params.eventGroupID + " failed with error: " + err); + res.send(err); + } + }) + .then(() => { + addToLog("editEventGroup", "success", "Event group " + req.params.eventGroupID + " edited"); + res.writeHead(302, { + 'Location': '/group/' + req.params.eventGroupID + '?e=' + req.params.editToken + }); + res.end(); + }) + .catch((err) => { console.error(err); res.send('Sorry! Something went wrong!'); addToLog("editEventGroup", "error", "Attempt to edit event group " + req.params.eventGroupID + " failed with error: " + err); }); } - const updatedEventGroup = { - name: req.body.eventGroupName, - description: req.body.eventGroupDescription, - url: req.body.eventGroupURL, - hostName: req.body.hostName, - image: eventGroupImageFilename + else { + // Token doesn't match + res.send('Sorry! Something went wrong'); + addToLog("editEventGroup", "error", "Attempt to edit event group " + req.params.eventGroupID + " failed with error: token does not match"); } - EventGroup.findOneAndUpdate({id: req.params.eventGroupID}, updatedEventGroup, function(err, raw) { - if (err) { - addToLog("editEventGroup", "error", "Attempt to edit event group " + req.params.eventGroupID + " failed with error: " + err); - res.send(err); - } - }) - .then(() => { - addToLog("editEventGroup", "success", "Event group " + req.params.eventGroupID + " edited"); - res.writeHead(302, { - 'Location': '/group/' + req.params.eventGroupID + '?e=' + req.params.editToken - }); - res.end(); - }) - .catch((err) => { console.error(err); res.send('Sorry! Something went wrong!'); addToLog("editEventGroup", "error", "Attempt to edit event group " + req.params.eventGroupID + " failed with error: " + err);}); - } - else { - // Token doesn't match - res.send('Sorry! Something went wrong'); - addToLog("editEventGroup", "error", "Attempt to edit event group " + req.params.eventGroupID + " failed with error: token does not match"); - } - }) - .catch((err) => { console.error(err); res.send('Sorry! Something went wrong!'); addToLog("editEventGroup", "error", "Attempt to edit event group " + req.params.eventGroupID + " failed with error: " + err);}); + }) + .catch((err) => { console.error(err); res.send('Sorry! Something went wrong!'); addToLog("editEventGroup", "error", "Attempt to edit event group " + req.params.eventGroupID + " failed with error: " + err); }); }); router.post('/deleteimage/:eventID/:editToken', (req, res) => { @@ -1073,33 +1076,33 @@ router.post('/deleteimage/:eventID/:editToken', (req, res) => { Event.findOne(({ id: req.params.eventID, })) - .then((event) => { - if (event.editToken === submittedEditToken) { - // Token matches - if (event.image){ - eventImage = event.image; - } else { - res.status(500).send('This event doesn\'t have a linked image. What are you even doing'); - } - fs.unlink(global.appRoot + '/public/events/' + eventImage, (err) => { - if (err) { - res.status(500).send(err); - addToLog("deleteEventImage", "error", "Attempt to delete event image for event " + req.params.eventID + " failed with error: " + err); + .then((event) => { + if (event.editToken === submittedEditToken) { + // Token matches + if (event.image) { + eventImage = event.image; + } else { + res.status(500).send('This event doesn\'t have a linked image. What are you even doing'); } - // Image removed - addToLog("deleteEventImage", "success", "Image for event " + req.params.eventID + " deleted"); - event.image = ""; - event.save() - .then(response => { - res.status(200).send('Success'); - }) - .catch(err => { - res.status(500).send(err); - addToLog("deleteEventImage", "error", "Attempt to delete event image for event " + req.params.eventID + " failed with error: " + err); - }) - }); - } - }); + fs.unlink(global.appRoot + '/public/events/' + eventImage, (err) => { + if (err) { + res.status(500).send(err); + addToLog("deleteEventImage", "error", "Attempt to delete event image for event " + req.params.eventID + " failed with error: " + err); + } + // Image removed + addToLog("deleteEventImage", "success", "Image for event " + req.params.eventID + " deleted"); + event.image = ""; + event.save() + .then(response => { + res.status(200).send('Success'); + }) + .catch(err => { + res.status(500).send(err); + addToLog("deleteEventImage", "error", "Attempt to delete event image for event " + req.params.eventID + " failed with error: " + err); + }) + }); + } + }); }); router.post('/deleteevent/:eventID/:editToken', (req, res) => { @@ -1108,135 +1111,135 @@ router.post('/deleteevent/:eventID/:editToken', (req, res) => { Event.findOne(({ id: req.params.eventID, })) - .then((event) => { - if (event.editToken === submittedEditToken) { - // Token matches + .then((event) => { + if (event.editToken === submittedEditToken) { + // Token matches - let eventImage; - if (event.image){ - eventImage = event.image; - } + let eventImage; + if (event.image) { + eventImage = event.image; + } - // broadcast a Delete profile message to all followers so that at least Mastodon servers will delete their local profile information - const guidUpdateObject = crypto.randomBytes(16).toString('hex'); - const jsonUpdateObject = JSON.parse(event.activityPubActor); - // first broadcast AP messages, THEN delete from DB - ap.broadcastDeleteMessage(jsonUpdateObject, event.followers, req.params.eventID, function(statuses) { - Event.deleteOne({id: req.params.eventID}, function(err, raw) { - if (err) { - res.send(err); - addToLog("deleteEvent", "error", "Attempt to delete event " + req.params.eventID + " failed with error: " + err); - } - }) - .then(() => { - // Delete image - if (eventImage){ - fs.unlink(global.appRoot + '/public/events/' + eventImage, (err) => { - if (err) { + // broadcast a Delete profile message to all followers so that at least Mastodon servers will delete their local profile information + const guidUpdateObject = crypto.randomBytes(16).toString('hex'); + const jsonUpdateObject = JSON.parse(event.activityPubActor); + // first broadcast AP messages, THEN delete from DB + ap.broadcastDeleteMessage(jsonUpdateObject, event.followers, req.params.eventID, function (statuses) { + Event.deleteOne({ id: req.params.eventID }, function (err, raw) { + if (err) { res.send(err); - addToLog("deleteEvent", "error", "Attempt to delete event image for event " + req.params.eventID + " failed with error: " + err); + addToLog("deleteEvent", "error", "Attempt to delete event " + req.params.eventID + " failed with error: " + err); + } + }) + .then(() => { + // Delete image + if (eventImage) { + fs.unlink(global.appRoot + '/public/events/' + eventImage, (err) => { + if (err) { + res.send(err); + addToLog("deleteEvent", "error", "Attempt to delete event image for event " + req.params.eventID + " failed with error: " + err); + } + // Image removed + addToLog("deleteEvent", "success", "Event " + req.params.eventID + " deleted"); + }) } - // Image removed - addToLog("deleteEvent", "success", "Event " + req.params.eventID + " deleted"); + res.writeHead(302, { + 'Location': '/' + }); + res.end(); }) - } - res.writeHead(302, { - 'Location': '/' - }); - res.end(); - }) - .catch((err) => { res.send('Sorry! Something went wrong (error deleting): ' + err); addToLog("deleteEvent", "error", "Attempt to delete event " + req.params.eventID + " failed with error: " + err);}); - }); - // Send emails here otherwise they don't exist lol - if (sendEmails) { - Event.findOne({id: req.params.eventID}).distinct('attendees.email', function(error, ids) { - attendeeEmails = ids; - if (!error){ - console.log("Sending emails to: " + attendeeEmails); - req.app.get('hbsInstance').renderView('./views/emails/deleteevent.handlebars', {siteName, siteLogo, domain, eventName: event.name, cache: true, layout: 'email.handlebars'}, function(err, html) { - const msg = { - to: attendeeEmails, - from: { - name: siteName, - email: contactEmail, - }, - subject: `${siteName}: ${event.name} was deleted`, - html, - }; - sgMail.sendMultiple(msg).catch(e => { - console.error(e.toString()); - res.status(500).end(); + .catch((err) => { res.send('Sorry! Something went wrong (error deleting): ' + err); addToLog("deleteEvent", "error", "Attempt to delete event " + req.params.eventID + " failed with error: " + err); }); + }); + // Send emails here otherwise they don't exist lol + if (sendEmails) { + Event.findOne({ id: req.params.eventID }).distinct('attendees.email', function (error, ids) { + attendeeEmails = ids; + if (!error) { + console.log("Sending emails to: " + attendeeEmails); + req.app.get('hbsInstance').renderView('./views/emails/deleteevent.handlebars', { siteName, siteLogo, domain, eventName: event.name, cache: true, layout: 'email.handlebars' }, function (err, html) { + const msg = { + to: attendeeEmails, + from: { + name: siteName, + email: contactEmail, + }, + subject: `${siteName}: ${event.name} was deleted`, + html, + }; + sgMail.sendMultiple(msg).catch(e => { + console.error(e.toString()); + res.status(500).end(); + }); }); - }); } - else { - console.log("Nothing to send!"); - } - }); + else { + console.log("Nothing to send!"); + } + }); + } } - } - else { - // Token doesn't match - res.send('Sorry! Something went wrong'); - addToLog("deleteEvent", "error", "Attempt to delete event " + req.params.eventID + " failed with error: token does not match"); - } - }) - .catch((err) => { res.send('Sorry! Something went wrong: ' + err); addToLog("deleteEvent", "error", "Attempt to delete event " + req.params.eventID + " failed with error: " + err);}); + else { + // Token doesn't match + res.send('Sorry! Something went wrong'); + addToLog("deleteEvent", "error", "Attempt to delete event " + req.params.eventID + " failed with error: token does not match"); + } + }) + .catch((err) => { res.send('Sorry! Something went wrong: ' + err); addToLog("deleteEvent", "error", "Attempt to delete event " + req.params.eventID + " failed with error: " + err); }); }); router.post('/deleteeventgroup/:eventGroupID/:editToken', (req, res) => { let submittedEditToken = req.params.editToken; EventGroup.findOne(({ id: req.params.eventGroupID, - })) - .then(async (eventGroup) => { - if (eventGroup.editToken === submittedEditToken) { - // Token matches - - let linkedEvents = await Event.find({eventGroup: eventGroup._id}); + })) + .then(async (eventGroup) => { + if (eventGroup.editToken === submittedEditToken) { + // Token matches - let linkedEventIDs = linkedEvents.map(event => event._id); - let eventGroupImage = false; - if (eventGroup.image){ - eventGroupImage = eventGroup.image; - } + let linkedEvents = await Event.find({ eventGroup: eventGroup._id }); - EventGroup.deleteOne({id: req.params.eventGroupID}, function(err, raw) { - if (err) { - res.send(err); - addToLog("deleteEventGroup", "error", "Attempt to delete event group " + req.params.eventGroupID + " failed with error: " + err); + let linkedEventIDs = linkedEvents.map(event => event._id); + let eventGroupImage = false; + if (eventGroup.image) { + eventGroupImage = eventGroup.image; } - }) - .then(() => { - // Delete image - if (eventGroupImage){ - fs.unlink(global.appRoot + '/public/events/' + eventGroupImage, (err) => { - if (err) { + + EventGroup.deleteOne({ id: req.params.eventGroupID }, function (err, raw) { + if (err) { res.send(err); - addToLog("deleteEventGroup", "error", "Attempt to delete event image for event group " + req.params.eventGroupID + " failed with error: " + err); + addToLog("deleteEventGroup", "error", "Attempt to delete event group " + req.params.eventGroupID + " failed with error: " + err); + } + }) + .then(() => { + // Delete image + if (eventGroupImage) { + fs.unlink(global.appRoot + '/public/events/' + eventGroupImage, (err) => { + if (err) { + res.send(err); + addToLog("deleteEventGroup", "error", "Attempt to delete event image for event group " + req.params.eventGroupID + " failed with error: " + err); + } + }) } + Event.update({ _id: { $in: linkedEventIDs } }, { $set: { eventGroup: null } }, { multi: true }) + .then(response => { + console.log(response); + addToLog("deleteEventGroup", "success", "Event group " + req.params.eventGroupID + " deleted"); + res.writeHead(302, { + 'Location': '/' + }); + res.end(); + }) + .catch((err) => { res.send('Sorry! Something went wrong (error deleting): ' + err); addToLog("deleteEventGroup", "error", "Attempt to delete event group " + req.params.eventGroupID + " failed with error: " + err); }); }) - } - Event.update({_id: {$in: linkedEventIDs}}, { $set: { eventGroup: null } }, { multi: true }) - .then(response => { - console.log(response); - addToLog("deleteEventGroup", "success", "Event group " + req.params.eventGroupID + " deleted"); - res.writeHead(302, { - 'Location': '/' - }); - res.end(); - }) - .catch((err) => { res.send('Sorry! Something went wrong (error deleting): ' + err); addToLog("deleteEventGroup", "error", "Attempt to delete event group " + req.params.eventGroupID + " failed with error: " + err);}); - }) - .catch((err) => { res.send('Sorry! Something went wrong (error deleting): ' + err); addToLog("deleteEventGroup", "error", "Attempt to delete event group " + req.params.eventGroupID + " failed with error: " + err);}); - } - else { - // Token doesn't match - res.send('Sorry! Something went wrong'); - addToLog("deleteEventGroup", "error", "Attempt to delete event group " + req.params.eventGroupID + " failed with error: token does not match"); - } - }) - .catch((err) => { res.send('Sorry! Something went wrong: ' + err); addToLog("deleteEventGroup", "error", "Attempt to delete event group " + req.params.eventGroupID + " failed with error: " + err);}); + .catch((err) => { res.send('Sorry! Something went wrong (error deleting): ' + err); addToLog("deleteEventGroup", "error", "Attempt to delete event group " + req.params.eventGroupID + " failed with error: " + err); }); + } + else { + // Token doesn't match + res.send('Sorry! Something went wrong'); + addToLog("deleteEventGroup", "error", "Attempt to delete event group " + req.params.eventGroupID + " failed with error: token does not match"); + } + }) + .catch((err) => { res.send('Sorry! Something went wrong: ' + err); addToLog("deleteEventGroup", "error", "Attempt to delete event group " + req.params.eventGroupID + " failed with error: " + err); }); }); router.post('/attendevent/:eventID', (req, res) => { @@ -1249,22 +1252,58 @@ router.post('/attendevent/:eventID', (req, res) => { Event.findOne({ id: req.params.eventID, - }, function(err,event) { + }, function (err, event) { if (!event) return; event.attendees.push(newAttendee); event.save() - .then(() => { - addToLog("addEventAttendee", "success", "Attendee added to event " + req.params.eventID); + .then(() => { + addToLog("addEventAttendee", "success", "Attendee added to event " + req.params.eventID); + if (sendEmails) { + if (req.body.attendeeEmail) { + req.app.get('hbsInstance').renderView('./views/emails/addeventattendee.handlebars', { eventID: req.params.eventID, siteName, siteLogo, domain, cache: true, layout: 'email.handlebars' }, function (err, html) { + const msg = { + to: req.body.attendeeEmail, + from: { + name: siteName, + email: contactEmail, + }, + subject: `${siteName}: You're RSVPed to ${event.name}`, + html, + }; + sgMail.send(msg).catch(e => { + console.error(e.toString()); + res.status(500).end(); + }); + }); + } + } + res.writeHead(302, { + 'Location': '/' + req.params.eventID + }); + res.end(); + }) + .catch((err) => { res.send('Database error, please try again :('); addToLog("addEventAttendee", "error", "Attempt to add attendee to event " + req.params.eventID + " failed with error: " + err); }); + }); +}); + +router.post('/unattendevent/:eventID', (req, res) => { + Event.update( + { id: req.params.eventID }, + { $pull: { attendees: { removalPassword: req.body.removeAttendancePassword } } } + ) + .then(response => { + console.log(response) + addToLog("unattendEvent", "success", "Attendee removed self from event " + req.params.eventID); if (sendEmails) { - if (req.body.attendeeEmail){ - req.app.get('hbsInstance').renderView('./views/emails/addeventattendee.handlebars', {eventID: req.params.eventID, siteName, siteLogo, domain, cache: true, layout: 'email.handlebars'}, function(err, html) { + if (req.body.attendeeEmail) { + req.app.get('hbsInstance').renderView('./views/emails/unattendevent.handlebars', { eventID: req.params.eventID, siteName, siteLogo, domain, cache: true, layout: 'email.handlebars' }, function (err, html) { const msg = { to: req.body.attendeeEmail, from: { name: siteName, email: contactEmail, }, - subject: `${siteName}: You're RSVPed to ${event.name}`, + subject: `${siteName}: You have been removed from an event`, html, }; sgMail.send(msg).catch(e => { @@ -1276,47 +1315,12 @@ router.post('/attendevent/:eventID', (req, res) => { } res.writeHead(302, { 'Location': '/' + req.params.eventID - }); + }); res.end(); }) - .catch((err) => { res.send('Database error, please try again :('); addToLog("addEventAttendee", "error", "Attempt to add attendee to event " + req.params.eventID + " failed with error: " + err); }); - }); -}); - -router.post('/unattendevent/:eventID', (req, res) => { - Event.update( - { id: req.params.eventID }, - { $pull: { attendees: { removalPassword: req.body.removeAttendancePassword } } } - ) - .then(response => { - console.log(response) - addToLog("unattendEvent", "success", "Attendee removed self from event " + req.params.eventID); - if (sendEmails) { - if (req.body.attendeeEmail){ - req.app.get('hbsInstance').renderView('./views/emails/unattendevent.handlebars', {eventID: req.params.eventID, siteName, siteLogo, domain, cache: true, layout: 'email.handlebars'}, function(err, html) { const msg = { - to: req.body.attendeeEmail, - from: { - name: siteName, - email: contactEmail, - }, - subject: `${siteName}: You have been removed from an event`, - html, - }; - sgMail.send(msg).catch(e => { - console.error(e.toString()); - res.status(500).end(); - }); - }); - } - } - res.writeHead(302, { - 'Location': '/' + req.params.eventID - }); - res.end(); - }) - .catch((err) => { - res.send('Database error, please try again :('); addToLog("removeEventAttendee", "error", "Attempt to remove attendee from event " + req.params.eventID + " failed with error: " + err); - }); + .catch((err) => { + res.send('Database error, please try again :('); addToLog("removeEventAttendee", "error", "Attempt to remove attendee from event " + req.params.eventID + " failed with error: " + err); + }); }); // this is a one-click unattend that requires a secret URL that only the person who RSVPed over @@ -1328,75 +1332,77 @@ router.get('/oneclickunattendevent/:eventID/:attendeeID', (req, res) => { return res.sendStatus(200); } Event.update( - { id: req.params.eventID }, - { $pull: { attendees: { _id: req.params.attendeeID } } } + { id: req.params.eventID }, + { $pull: { attendees: { _id: req.params.attendeeID } } } ) - .then(response => { - addToLog("oneClickUnattend", "success", "Attendee removed via one click unattend " + req.params.eventID); - if (sendEmails) { - // currently this is never called because we don't have the email address - if (req.body.attendeeEmail){ - req.app.get('hbsInstance').renderView('./views/emails/removeeventattendee.handlebars', {eventName: req.params.eventName, siteName, domain, cache: true, layout: 'email.handlebars'}, function(err, html) { const msg = { - to: req.body.attendeeEmail, - from: { - name: siteName, - email: contactEmail, - }, - subject: `${siteName}: You have been removed from an event`, - html, - }; - sgMail.send(msg).catch(e => { - console.error(e.toString()); - res.status(500).end(); + .then(response => { + addToLog("oneClickUnattend", "success", "Attendee removed via one click unattend " + req.params.eventID); + if (sendEmails) { + // currently this is never called because we don't have the email address + if (req.body.attendeeEmail) { + req.app.get('hbsInstance').renderView('./views/emails/removeeventattendee.handlebars', { eventName: req.params.eventName, siteName, domain, cache: true, layout: 'email.handlebars' }, function (err, html) { + const msg = { + to: req.body.attendeeEmail, + from: { + name: siteName, + email: contactEmail, + }, + subject: `${siteName}: You have been removed from an event`, + html, + }; + sgMail.send(msg).catch(e => { + console.error(e.toString()); + res.status(500).end(); + }); }); - }); + } } - } - res.writeHead(302, { - 'Location': '/' + req.params.eventID + res.writeHead(302, { + 'Location': '/' + req.params.eventID }); - res.end(); - }) - .catch((err) => { - res.send('Database error, please try again :('); addToLog("removeEventAttendee", "error", "Attempt to remove attendee by admin from event " + req.params.eventID + " failed with error: " + err); - }); + res.end(); + }) + .catch((err) => { + res.send('Database error, please try again :('); addToLog("removeEventAttendee", "error", "Attempt to remove attendee by admin from event " + req.params.eventID + " failed with error: " + err); + }); }); router.post('/removeattendee/:eventID/:attendeeID', (req, res) => { Event.update( - { id: req.params.eventID }, - { $pull: { attendees: { _id: req.params.attendeeID } } } + { id: req.params.eventID }, + { $pull: { attendees: { _id: req.params.attendeeID } } } ) - .then(response => { - console.log(response) - addToLog("removeEventAttendee", "success", "Attendee removed by admin from event " + req.params.eventID); - if (sendEmails) { - // currently this is never called because we don't have the email address - if (req.body.attendeeEmail){ - req.app.get('hbsInstance').renderView('./views/emails/removeeventattendee.handlebars', {eventName: req.params.eventName, siteName, siteLogo, domain, cache: true, layout: 'email.handlebars'}, function(err, html) { const msg = { - to: req.body.attendeeEmail, - from: { - name: siteName, - email: contactEmail, - }, - subject: `${siteName}: You have been removed from an event`, - html, - }; - sgMail.send(msg).catch(e => { - console.error(e.toString()); - res.status(500).end(); + .then(response => { + console.log(response) + addToLog("removeEventAttendee", "success", "Attendee removed by admin from event " + req.params.eventID); + if (sendEmails) { + // currently this is never called because we don't have the email address + if (req.body.attendeeEmail) { + req.app.get('hbsInstance').renderView('./views/emails/removeeventattendee.handlebars', { eventName: req.params.eventName, siteName, siteLogo, domain, cache: true, layout: 'email.handlebars' }, function (err, html) { + const msg = { + to: req.body.attendeeEmail, + from: { + name: siteName, + email: contactEmail, + }, + subject: `${siteName}: You have been removed from an event`, + html, + }; + sgMail.send(msg).catch(e => { + console.error(e.toString()); + res.status(500).end(); + }); }); - }); + } } - } - res.writeHead(302, { - 'Location': '/' + req.params.eventID + res.writeHead(302, { + 'Location': '/' + req.params.eventID }); - res.end(); - }) - .catch((err) => { - res.send('Database error, please try again :('); addToLog("removeEventAttendee", "error", "Attempt to remove attendee by admin from event " + req.params.eventID + " failed with error: " + err); - }); + res.end(); + }) + .catch((err) => { + res.send('Database error, please try again :('); addToLog("removeEventAttendee", "error", "Attempt to remove attendee by admin from event " + req.params.eventID + " failed with error: " + err); + }); }); router.post('/post/comment/:eventID', (req, res) => { @@ -1410,56 +1416,56 @@ router.post('/post/comment/:eventID', (req, res) => { Event.findOne({ id: req.params.eventID, - }, function(err,event) { + }, function (err, event) { if (!event) return; event.comments.push(newComment); event.save() - .then(() => { - addToLog("addEventComment", "success", "Comment added to event " + req.params.eventID); - // broadcast an identical message to all followers, will show in their home timeline - // and in the home timeline of the event - const guidObject = crypto.randomBytes(16).toString('hex'); - const jsonObject = { - "@context": "https://www.w3.org/ns/activitystreams", - "id": `https://${domain}/${req.params.eventID}/m/${guidObject}`, - "name": `Comment on ${event.name}`, - "type": "Note", - 'cc': 'https://www.w3.org/ns/activitystreams#Public', - "content": `<p>${req.body.commentAuthor} commented: ${req.body.commentContent}.</p><p><a href="https://${domain}/${req.params.eventID}/">See the full conversation here.</a></p>`, - } - ap.broadcastCreateMessage(jsonObject, event.followers, req.params.eventID) - if (sendEmails) { - Event.findOne({id: req.params.eventID}).distinct('attendees.email', function(error, ids) { - let attendeeEmails = ids; - if (!error){ - console.log("Sending emails to: " + attendeeEmails); - req.app.get('hbsInstance').renderView('./views/emails/addeventcomment.handlebars', {siteName, siteLogo, domain, eventID: req.params.eventID, commentAuthor: req.body.commentAuthor, cache: true, layout: 'email.handlebars'}, function(err, html) { - const msg = { - to: attendeeEmails, - from: { - name: siteName, - email: contactEmail, - }, - subject: `${siteName}: New comment in ${event.name}`, - html, - }; - sgMail.sendMultiple(msg).catch(e => { - console.error(e.toString()); - res.status(500).end(); + .then(() => { + addToLog("addEventComment", "success", "Comment added to event " + req.params.eventID); + // broadcast an identical message to all followers, will show in their home timeline + // and in the home timeline of the event + const guidObject = crypto.randomBytes(16).toString('hex'); + const jsonObject = { + "@context": "https://www.w3.org/ns/activitystreams", + "id": `https://${domain}/${req.params.eventID}/m/${guidObject}`, + "name": `Comment on ${event.name}`, + "type": "Note", + 'cc': 'https://www.w3.org/ns/activitystreams#Public', + "content": `<p>${req.body.commentAuthor} commented: ${req.body.commentContent}.</p><p><a href="https://${domain}/${req.params.eventID}/">See the full conversation here.</a></p>`, + } + ap.broadcastCreateMessage(jsonObject, event.followers, req.params.eventID) + if (sendEmails) { + Event.findOne({ id: req.params.eventID }).distinct('attendees.email', function (error, ids) { + let attendeeEmails = ids; + if (!error) { + console.log("Sending emails to: " + attendeeEmails); + req.app.get('hbsInstance').renderView('./views/emails/addeventcomment.handlebars', { siteName, siteLogo, domain, eventID: req.params.eventID, commentAuthor: req.body.commentAuthor, cache: true, layout: 'email.handlebars' }, function (err, html) { + const msg = { + to: attendeeEmails, + from: { + name: siteName, + email: contactEmail, + }, + subject: `${siteName}: New comment in ${event.name}`, + html, + }; + sgMail.sendMultiple(msg).catch(e => { + console.error(e.toString()); + res.status(500).end(); + }); }); - }); - } - else { - console.log("Nothing to send!"); - } - }); - } - res.writeHead(302, { - 'Location': '/' + req.params.eventID + } + else { + console.log("Nothing to send!"); + } + }); + } + res.writeHead(302, { + 'Location': '/' + req.params.eventID }); - res.end(); - }) - .catch((err) => { res.send('Database error, please try again :(' + err); addToLog("addEventComment", "error", "Attempt to add comment to event " + req.params.eventID + " failed with error: " + err); }); + res.end(); + }) + .catch((err) => { res.send('Database error, please try again :(' + err); addToLog("addEventComment", "error", "Attempt to add comment to event " + req.params.eventID + " failed with error: " + err); }); }); }); @@ -1474,11 +1480,11 @@ router.post('/post/reply/:eventID/:commentID', (req, res) => { }; Event.findOne({ id: req.params.eventID, - }, function(err,event) { - if (!event) return; - var parentComment = event.comments.id(commentID); - parentComment.replies.push(newReply); - event.save() + }, function (err, event) { + if (!event) return; + var parentComment = event.comments.id(commentID); + parentComment.replies.push(newReply); + event.save() .then(() => { addToLog("addEventReply", "success", "Reply added to comment " + commentID + " in event " + req.params.eventID); // broadcast an identical message to all followers, will show in their home timeline @@ -1493,11 +1499,11 @@ router.post('/post/reply/:eventID/:commentID', (req, res) => { } ap.broadcastCreateMessage(jsonObject, event.followers, req.params.eventID) if (sendEmails) { - Event.findOne({id: req.params.eventID}).distinct('attendees.email', function(error, ids) { + Event.findOne({ id: req.params.eventID }).distinct('attendees.email', function (error, ids) { let attendeeEmails = ids; - if (!error){ + if (!error) { console.log("Sending emails to: " + attendeeEmails); - req.app.get('hbsInstance').renderView('./views/emails/addeventcomment.handlebars', {siteName, siteLogo, domain, eventID: req.params.eventID, commentAuthor: req.body.replyAuthor, cache: true, layout: 'email.handlebars'}, function(err, html) { + req.app.get('hbsInstance').renderView('./views/emails/addeventcomment.handlebars', { siteName, siteLogo, domain, eventID: req.params.eventID, commentAuthor: req.body.replyAuthor, cache: true, layout: 'email.handlebars' }, function (err, html) { const msg = { to: attendeeEmails, from: { @@ -1520,39 +1526,39 @@ router.post('/post/reply/:eventID/:commentID', (req, res) => { } res.writeHead(302, { 'Location': '/' + req.params.eventID - }); + }); res.end(); }) .catch((err) => { res.send('Database error, please try again :('); addToLog("addEventReply", "error", "Attempt to add reply to comment " + commentID + " in event " + req.params.eventID + " failed with error: " + err); }); - }); + }); }); router.post('/deletecomment/:eventID/:commentID/:editToken', (req, res) => { let submittedEditToken = req.params.editToken; Event.findOne(({ id: req.params.eventID, - })) - .then((event) => { - if (event.editToken === submittedEditToken) { - // Token matches - event.comments.id(req.params.commentID).remove(); - event.save() - .then(() => { - addToLog("deleteComment", "success", "Comment deleted from event " + req.params.eventID); - res.writeHead(302, { - 'Location': '/' + req.params.eventID + '?e=' + req.params.editToken - }); - res.end(); - }) - .catch((err) => { res.send('Sorry! Something went wrong (error deleting): ' + err); addToLog("deleteComment", "error", "Attempt to delete comment " + req.params.commentID + "from event " + req.params.eventID + " failed with error: " + err);}); - } - else { - // Token doesn't match - res.send('Sorry! Something went wrong'); - addToLog("deleteComment", "error", "Attempt to delete comment " + req.params.commentID + "from event " + req.params.eventID + " failed with error: token does not match"); - } - }) - .catch((err) => { res.send('Sorry! Something went wrong: ' + err); addToLog("deleteComment", "error", "Attempt to delete comment " + req.params.commentID + "from event " + req.params.eventID + " failed with error: " + err);}); + })) + .then((event) => { + if (event.editToken === submittedEditToken) { + // Token matches + event.comments.id(req.params.commentID).remove(); + event.save() + .then(() => { + addToLog("deleteComment", "success", "Comment deleted from event " + req.params.eventID); + res.writeHead(302, { + 'Location': '/' + req.params.eventID + '?e=' + req.params.editToken + }); + res.end(); + }) + .catch((err) => { res.send('Sorry! Something went wrong (error deleting): ' + err); addToLog("deleteComment", "error", "Attempt to delete comment " + req.params.commentID + "from event " + req.params.eventID + " failed with error: " + err); }); + } + else { + // Token doesn't match + res.send('Sorry! Something went wrong'); + addToLog("deleteComment", "error", "Attempt to delete comment " + req.params.commentID + "from event " + req.params.eventID + " failed with error: token does not match"); + } + }) + .catch((err) => { res.send('Sorry! Something went wrong: ' + err); addToLog("deleteComment", "error", "Attempt to delete comment " + req.params.commentID + "from event " + req.params.eventID + " failed with error: " + err); }); }); router.post('/activitypub/inbox', (req, res) => { @@ -1561,7 +1567,7 @@ router.post('/activitypub/inbox', (req, res) => { const signature = req.get('Signature'); let signature_header = signature.split(',').map(pair => { return pair.split('=').map(value => { - return value.replace(/^"/g, '').replace(/"$/g, '') + return value.replace(/^"/g, '').replace(/"$/g, '') }); }).reduce((acc, el) => { acc[el[0]] = el[1]; @@ -1575,7 +1581,8 @@ router.post('/activitypub/inbox', (req, res) => { headers: { 'Accept': 'application/activity+json', 'Content-Type': 'application/activity+json' - }}, function (error, response, actor) { + } + }, function (error, response, actor) { let publicKey = ''; try { @@ -1583,7 +1590,7 @@ router.post('/activitypub/inbox', (req, res) => { publicKey = JSON.parse(actor).publicKey.publicKeyPem; } } - catch(err) { + catch (err) { return res.status(500).send('Actor could not be parsed' + err); } @@ -1610,13 +1617,13 @@ router.post('/activitypub/inbox', (req, res) => { return res.status(401).send('Signature could not be verified.'); } } - catch(err) { + catch (err) { return res.status(401).send('Signature could not be verified: ' + err); } }); }); -router.use(function(req, res, next){ +router.use(function (req, res, next) { res.status(404); res.render('404', { url: req.url }); return; |