diff options
author | lowercasename <raphaelkabo@gmail.com> | 2020-06-12 17:35:41 +0100 |
---|---|---|
committer | lowercasename <raphaelkabo@gmail.com> | 2020-06-12 17:35:41 +0100 |
commit | 2ae20b09e6369202b4235b7fced87cc0daf6dff5 (patch) | |
tree | 9861f0118feb628609a36ef2c2cb18c175adba1d /routes.js | |
parent | b9a71a9e009465791e7f0bbb8f1b4bdcf2ad02c6 (diff) |
Remove debugging
Diffstat (limited to 'routes.js')
-rwxr-xr-x | routes.js | 1284 |
1 files changed, 636 insertions, 648 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,34 +102,28 @@ router.use(fileUpload()); const schedule = require('node-schedule'); -// const deleteOldEvents = schedule.scheduleJob('59 23 * * *', function(fireDate){ -function deleteOldEvents() { +const deleteOldEvents = schedule.scheduleJob('59 23 * * *', function(fireDate){ const too_old = moment.tz('Etc/UTC').subtract(7, 'days').toDate(); console.log("Old event deletion running! Deleting all events concluding before ", too_old); Event.find({ end: { $lte: too_old } }).then((oldEvents) => { - console.log("=== OLD EVENTS ==="); - oldEvents.forEach(event => { - console.log(event.id); - }) - 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 @@ -139,8 +133,8 @@ function deleteOldEvents() { 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); }); }); @@ -150,11 +144,9 @@ function deleteOldEvents() { } }) }).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 @@ -194,19 +186,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, @@ -223,7 +215,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", @@ -239,34 +231,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 }); + .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)); } else { - 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 }); - } + 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 @@ -278,40 +270,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) { - 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); + .then((event) => { + if (!event) { res.status(404); res.render('404', { url: req.url }); - return; - }); + } + 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; + }); } }); 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>]'); } @@ -323,11 +315,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(); @@ -337,14 +329,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 { @@ -353,7 +345,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); } @@ -366,7 +358,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 { @@ -374,16 +366,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) { @@ -394,7 +386,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 }; @@ -453,7 +445,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); @@ -468,7 +460,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); } @@ -481,7 +473,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); @@ -490,31 +482,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; @@ -529,7 +521,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); } @@ -542,7 +534,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 { @@ -552,7 +544,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 }; @@ -590,7 +582,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) { @@ -636,7 +628,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; @@ -691,7 +683,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 }); @@ -700,7 +692,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: { @@ -717,11 +709,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) => { @@ -766,19 +758,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(); }); }); } @@ -787,7 +779,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!") @@ -826,7 +818,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: { @@ -847,7 +839,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) => { @@ -855,220 +847,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>`; + })) + .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); } - 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(() => { - 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'); + }) + .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", - "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); - } + "@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}] } - }) - 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!"); - } - }) + // 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(); }) - .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); }); + } + 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);}); }); 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'; - } - 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); }); + })) + .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'; } - 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"); + const updatedEventGroup = { + name: req.body.eventGroupName, + description: req.body.eventGroupDescription, + url: req.body.eventGroupURL, + hostName: req.body.hostName, + image: eventGroupImageFilename } - }) - .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); }); + 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);}); }); router.post('/deleteimage/:eventID/:editToken', (req, res) => { @@ -1076,33 +1068,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); - } - // 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); - }) - }); + .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); + } + // 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) => { @@ -1111,135 +1103,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) { + // 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) { 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) { - 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"); - }) + addToLog("deleteEvent", "error", "Attempt to delete event image for event " + req.params.eventID + " failed with error: " + err); } - res.writeHead(302, { - 'Location': '/' - }); - res.end(); + // Image removed + addToLog("deleteEvent", "success", "Event " + req.params.eventID + " deleted"); }) - .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(); - }); + } + 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(); }); + }); } - 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"); + else { + console.log("Nothing to send!"); + } + }); } - }) - .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 + })) + .then(async (eventGroup) => { + if (eventGroup.editToken === submittedEditToken) { + // Token matches - let linkedEvents = await Event.find({ eventGroup: eventGroup._id }); + let linkedEvents = await Event.find({eventGroup: eventGroup._id}); - let linkedEventIDs = linkedEvents.map(event => event._id); - let eventGroupImage = false; - if (eventGroup.image) { - eventGroupImage = eventGroup.image; - } + let linkedEventIDs = linkedEvents.map(event => event._id); + let eventGroupImage = false; + if (eventGroup.image){ + eventGroupImage = eventGroup.image; + } - EventGroup.deleteOne({ id: req.params.eventGroupID }, function (err, raw) { - if (err) { + 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); + } + }) + .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 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); - } - }) + 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); }); }) - .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); }); + } + 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);}); }); router.post('/attendevent/:eventID', (req, res) => { @@ -1252,58 +1244,22 @@ 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); - 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); + .then(() => { + addToLog("addEventAttendee", "success", "Attendee added to 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) { + 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 have been removed from an event`, + subject: `${siteName}: You're RSVPed to ${event.name}`, html, }; sgMail.send(msg).catch(e => { @@ -1315,12 +1271,47 @@ router.post('/unattendevent/:eventID', (req, res) => { } 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("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); + }); }); // this is a one-click unattend that requires a secret URL that only the person who RSVPed over @@ -1332,77 +1323,75 @@ 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) => { @@ -1416,56 +1405,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.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.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); }); }); }); @@ -1480,11 +1469,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 @@ -1499,11 +1488,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: { @@ -1526,39 +1515,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) => { @@ -1567,7 +1556,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]; @@ -1581,8 +1570,7 @@ 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 { @@ -1590,7 +1578,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); } @@ -1617,13 +1605,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; |