summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml8
-rw-r--r--Dockerfile7
-rw-r--r--README.md4
-rw-r--r--config/database-docker.js3
-rw-r--r--config/domain-example.js4
-rw-r--r--docker-compose.yml10
-rw-r--r--public/images/gathio-email-logo.gifbin0 -> 2198 bytes
-rwxr-xr-xroutes.js112
-rwxr-xr-xtest.sh15
-rw-r--r--views/layouts/email.handlebars5
10 files changed, 110 insertions, 58 deletions
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..cdf8b48
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,8 @@
+language: shell
+os: linux
+
+services:
+ - docker
+
+script:
+ - ./test.sh \ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..a436239
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,7 @@
+FROM node:13-alpine
+WORKDIR /app
+ADD package.json package-lock.json /app/
+RUN npm install
+COPY . /app/
+RUN cp config/api-example.js config/api.js && cp config/domain-example.js config/domain.js && cp config/database-docker.js config/database.js
+CMD npm start
diff --git a/README.md b/README.md
index eb2403f..debd336 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,11 @@
# gathio
+[![Build Status](https://travis-ci.com/lowercasename/gathio.svg?branch=master)](https://travis-ci.com/lowercasename/gathio)
+
Self-destructing, shareable, no-registration event pages.
You can use the publicly hosted version [here](https://gath.io).
# Installation
-See [the wiki](https://github.com/lowercasename/gathio/wiki/install)
+See [the Wiki](https://github.com/lowercasename/gathio/wiki/install) for installation instructions.
diff --git a/config/database-docker.js b/config/database-docker.js
new file mode 100644
index 0000000..7847097
--- /dev/null
+++ b/config/database-docker.js
@@ -0,0 +1,3 @@
+module.exports = {
+ 'url' : 'mongodb://mongo:27017/gathio' // For dockerised MongoDB connection
+};
diff --git a/config/domain-example.js b/config/domain-example.js
index 3b77197..b84e210 100644
--- a/config/domain-example.js
+++ b/config/domain-example.js
@@ -3,5 +3,7 @@ module.exports = {
'domain' : 'localhost:3000' ,
'port': '3000',
'email': 'contact@example.com',
- 'sitename': 'gathio'
+ 'sitename': 'gathio',
+ // If left blank, this defaults to https://yourdomain.com/images/gathio-email-logo.gif. Set a full URL here to change it to your own logo (or just change the file itself)
+ 'logo_url': ''
};
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..d16e279
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,10 @@
+version: '3'
+services:
+ gathio:
+ build: .
+ links:
+ - mongo
+ ports:
+ - 3000:3000
+ mongo:
+ image: mongo:latest \ No newline at end of file
diff --git a/public/images/gathio-email-logo.gif b/public/images/gathio-email-logo.gif
new file mode 100644
index 0000000..7374176
--- /dev/null
+++ b/public/images/gathio-email-logo.gif
Binary files differ
diff --git a/routes.js b/routes.js
index f5ec0b3..8e480e6 100755
--- a/routes.js
+++ b/routes.js
@@ -27,6 +27,7 @@ const request = require('request');
const domain = require('./config/domain.js').domain;
const contactEmail = require('./config/domain.js').email;
const siteName = require('./config/domain.js').sitename
+const siteLogo = require('./config/domain.js').logo_url;
const ap = require('./activitypub.js');
// Extra marked renderer (used to render plaintext event description for page metadata)
@@ -671,7 +672,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, 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: {
@@ -698,12 +699,10 @@ router.post('/newevent', async (req, res) => {
router.post('/importevent', (req, res) => {
let eventID = shortid.generate();
let editToken = randomstring.generate();
- if (req.files && Object.keys(req.files).length != 0) {
- importediCalObject = ical.parseICS(req.files.icsImportControl.data.toString('utf8'));
- for (var key in importediCalObject) {
- importedEventData = importediCalObject[key];
- }
- console.log(importedEventData)
+ if (req.files && Object.keys(req.files).length !== 0) {
+ let iCalObject = ical.parseICS(req.files.icsImportControl.data.toString('utf8'));
+ let importedEventData = iCalObject[Object.keys(iCalObject)];
+
let creatorEmail;
if (req.body.creatorEmail) {
creatorEmail = req.body.creatorEmail
@@ -712,7 +711,7 @@ router.post('/importevent', (req, res) => {
} else {
res.status(500).send("Please supply an email address on the previous page.");
}
-
+
const event = new Event({
id: eventID,
type: 'public',
@@ -739,24 +738,24 @@ 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, domain, cache: true, layout: 'email.handlebars'}, function(err, html) {
- const msg = {
- to: req.body.creatorEmail,
- from: {
- name: siteName,
- email: contactEmail,
- },
- subject: `${siteName}: ${req.body.eventName}`,
- html,
- };
- sgMail.send(msg).catch(e => {
- console.error(e.toString());
- res.status(500).end();
- });
- });
+ 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,
+ };
+ sgMail.send(msg).catch(e => {
+ console.error(e.toString());
+ res.status(500).end();
+ });
+ });
}
res.writeHead(302, {
- 'Location': '/' + eventID + '?e=' + editToken
+ 'Location': '/' + eventID + '?e=' + editToken
});
res.end();
})
@@ -799,7 +798,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, 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: {
@@ -953,7 +952,7 @@ router.post('/editevent/:eventID/:editToken', (req, res) => {
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, domain, cache: true, layout: 'email.handlebars'}, function(err, html) {
+ 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: {
@@ -1093,6 +1092,7 @@ router.post('/deleteevent/:eventID/:editToken', (req, res) => {
eventImage = event.image;
}
+<<<<<<< HEAD
// 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);
@@ -1123,33 +1123,33 @@ router.post('/deleteevent/:eventID/:editToken', (req, res) => {
})
.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) {
- let attendeeEmails = ids;
- if (!error){
- console.log("Sending emails to: " + attendeeEmails);
- req.app.get('hbsInstance').renderView('./views/emails/deleteevent.handlebars', {siteName, 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();
- });
+ // 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
@@ -1233,7 +1233,7 @@ router.post('/attendevent/:eventID', (req, res) => {
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, domain, cache: true, layout: 'email.handlebars'}, function(err, html) {
+ 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: {
@@ -1269,7 +1269,7 @@ router.post('/unattendevent/:eventID', (req, res) => {
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, domain, cache: true, layout: 'email.handlebars'}, function(err, html) { const msg = {
+ 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,
@@ -1349,7 +1349,7 @@ router.post('/removeattendee/:eventID/:attendeeID', (req, res) => {
if (sendEmails) {
// currently this is never called because we don't have the email address
if (req.body.attendeeEmail){
- 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 = {
+ 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,
@@ -1409,7 +1409,7 @@ router.post('/post/comment/:eventID', (req, res) => {
let attendeeEmails = ids;
if (!error){
console.log("Sending emails to: " + attendeeEmails);
- req.app.get('hbsInstance').renderView('./views/emails/addeventcomment.handlebars', {siteName, domain, eventID: req.params.eventID, commentAuthor: req.body.commentAuthor, 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.commentAuthor, cache: true, layout: 'email.handlebars'}, function(err, html) {
const msg = {
to: attendeeEmails,
from: {
@@ -1473,7 +1473,7 @@ router.post('/post/reply/:eventID/:commentID', (req, res) => {
let attendeeEmails = ids;
if (!error){
console.log("Sending emails to: " + attendeeEmails);
- req.app.get('hbsInstance').renderView('./views/emails/addeventcomment.handlebars', {siteName, 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: {
diff --git a/test.sh b/test.sh
new file mode 100755
index 0000000..6626437
--- /dev/null
+++ b/test.sh
@@ -0,0 +1,15 @@
+#!/usr/bin/env bash
+
+set -eux -o pipefail
+
+cleanup() {
+ docker-compose kill
+}
+trap cleanup 0
+
+docker-compose up --build &
+
+while [[ "$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3000/)" -ne "200" ]]; do sleep 5; done
+curl -v http://localhost:3000/new/event/public
+
+cleanup \ No newline at end of file
diff --git a/views/layouts/email.handlebars b/views/layouts/email.handlebars
index 6158ddb..2b54d6e 100644
--- a/views/layouts/email.handlebars
+++ b/views/layouts/email.handlebars
@@ -106,6 +106,11 @@
<td class="wrapper" style="font-family: sans-serif; font-size: 14px; vertical-align: top; box-sizing: border-box; padding: 20px;">
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;">
<tr>
+ <td style="font-family: sans-serif; font-size: 14px; vertical-align: top; text-align: right; padding-bottom: 14px;">
+ <img src="{{#if siteLogo}}{{siteLogo}}{{else}}https://{{domain}}/images/gathio-email-logo.gif{{/if}}">
+ </td>
+ </tr>
+ <tr>
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;">
{{{ body }}}
</td>