From 9702f93cf9245f532c3c3776eb34555bb21ecfc7 Mon Sep 17 00:00:00 2001 From: lesion Date: Mon, 11 Mar 2019 00:20:37 +0100 Subject: [PATCH] mail notification --- .env | 1 + Dockerfile | 2 +- app/api.js | 6 ++--- app/controller/event.js | 35 ++++++++++++++++++++++++------ app/controller/user.js | 13 +++++++---- app/cron.js | 23 +++++++++++--------- app/emails/event/html.pug | 7 +++++- app/model.js | 4 ++-- app/models/event.js | 17 +++++++++------ app/server.js | 3 ++- client/src/api.js | 2 +- client/src/components/Export.vue | 16 +++++++------- client/src/components/Settings.vue | 16 +++++--------- client/src/components/newEvent.vue | 2 +- client/src/filters.js | 3 ++- client/src/locale/it.js | 1 - client/vue.config.js | 3 ++- 17 files changed, 95 insertions(+), 59 deletions(-) diff --git a/.env b/.env index 87485af9..10d554a7 100644 --- a/.env +++ b/.env @@ -1,3 +1,4 @@ +NODE_ENV=production BASE_URL=http://localhost:12300 TITLE=Gancio diff --git a/Dockerfile b/Dockerfile index 96dc6f9b..a58108b3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,7 +7,7 @@ COPY package.json . COPY pm2.json . # install backend dependencies -RUN yarn --prod +RUN yarn # copy source COPY app app/ diff --git a/app/api.js b/app/api.js index d88fe22a..dd316d79 100644 --- a/app/api.js +++ b/app/api.js @@ -47,9 +47,9 @@ api.get('/event/meta', eventController.getMeta) // get unconfirmed events api.get('/event/unconfirmed', isAuth, isAdmin, eventController.getUnconfirmed) -// add event reminder -api.post('/event/reminder', eventController.addReminder) -// api.del('/event/reminder/:id', eventController.delReminder) +// add event notification +api.post('/event/notification', eventController.addNotification) +api.delete('/event/del_notification/:code', eventController.delNotification) // get event api.get('/event/:event_id', eventController.get) diff --git a/app/controller/event.js b/app/controller/event.js index 33d196bb..d542eb09 100644 --- a/app/controller/event.js +++ b/app/controller/event.js @@ -1,7 +1,9 @@ -const { User, Event, Comment, Tag, Place, Reminder } = require('../model') +const { User, Event, Comment, Tag, Place, Notification } = require('../model') const moment = require('moment') const { Op } = require('sequelize') const lodash = require('lodash') +const crypto = require('crypto') + const eventController = { async addComment (req, res) { @@ -23,7 +25,7 @@ const eventController = { res.json({ tags, places }) }, - async getReminders (event) { + async getNotifications (event) { function match (event, filters) { // matches if no filter specified if (!filters.tags.length && !filters.places.length) return true @@ -37,10 +39,10 @@ const eventController = { } } } - const reminders = await Reminder.findAll() + const notifications = await Notification.findAll() - // get reminder that matches with selected event - return reminders.filter(reminder => match(event, reminder.filters)) + // get notification that matches with selected event + return notifications.filter(notification => match(event, notification.filters)) }, async updateTag (req, res) { @@ -68,6 +70,11 @@ const eventController = { async confirm (req, res) { const id = req.params.event_id const event = await Event.findByPk(id) + + // insert notification + const notifications = await eventController.getNotifications(event) + await event.setNotifications(notifications) + try { await event.update({ is_visible: true }) res.send(200) @@ -87,14 +94,28 @@ const eventController = { res.json(events) }, - async addReminder (req, res) { + async addNotification (req, res) { try { - await Reminder.create(req.body) + const notification = req.body + notification.remove_code = crypto.randomBytes(16).toString('hex') + await Notification.create(req.body) res.sendStatus(200) } catch (e) { res.sendStatus(404) } }, + + async delNotification (req, res) { + const remove_code = req.params.code + try { + const notification = await Notification.findOne({ where: { remove_code: { [Op.eq]: remove_code } } }) + await notification.destroy() + } catch (e) { + return res.send('Error') + } + res.send('Ok, notification removed') + }, + async getAll (req, res) { const start = moment().year(req.params.year).month(req.params.month).startOf('month').subtract(1, 'week') const end = moment().year(req.params.year).month(req.params.month).endOf('month').add(1, 'week') diff --git a/app/controller/user.js b/app/controller/user.js index 9a84ba5d..a54e0b02 100644 --- a/app/controller/user.js +++ b/app/controller/user.js @@ -2,7 +2,7 @@ const jwt = require('jsonwebtoken') const Mastodon = require('mastodon-api') const User = require('../models/user') -const { Event, Tag, Place } = require('../models/event') +const { Event, Tag, Place, Notification } = require('../models/event') const eventController = require('./event') const config = require('../config') const mail = require('../mail') @@ -105,9 +105,14 @@ const userController = { event.save() } - // insert reminder - const reminders = await eventController.getReminders(event) - await event.setReminders(reminders) + if (req.user) { + // insert notifications + const notifications = await eventController.getNotifications(event) + await event.setNotifications(notifications) + } else { + const notification = await Notification.create({ type: 'admin_email' }) + await event.setNotification(notification) + } return res.json(event) }, diff --git a/app/cron.js b/app/cron.js index 4e184390..7a31eff1 100644 --- a/app/cron.js +++ b/app/cron.js @@ -1,20 +1,23 @@ const mail = require('./mail') -const { Event, Reminder, EventReminder, User, Place, Tag } = require('./model') +const { Event, Notification, EventNotification, User, Place, Tag } = require('./model') async function loop () { - console.log('nel loop') - // get all event reminder in queue - const eventReminders = await EventReminder.findAll() - const promises = eventReminders.map(async e => { + // get all event notification in queue + const eventNotifications = await EventNotification.findAll() + const promises = eventNotifications.map(async e => { const event = await Event.findByPk(e.eventId, { include: [User, Place, Tag] }) - console.log('EVENT ') - console.log(event) if (!event.place) return - const reminder = await Reminder.findByPk(e.reminderId) + const notification = await Notification.findByPk(e.notificationId) try { - await mail.send(reminder.email, 'event', { event }) + if (notification.type === 'mail') { + await mail.send(notification.email, 'event', { event }) + } else if (notification.type === 'mail_admin') { + const admins = await User.findAll({ where: { is_admin: true } }) + await Promise.all(admins.map(admin => + mail.send(admin.email, 'event', { event, to_confirm: true, notification }))) + } } catch (e) { - console.log('DENTRO CATCH!', e) + console.log('CATCH!', e) return false } return e.destroy() diff --git a/app/emails/event/html.pug b/app/emails/event/html.pug index 853ad236..8c397e48 100644 --- a/app/emails/event/html.pug +++ b/app/emails/event/html.pug @@ -6,5 +6,10 @@ br p #{event.description} #{config.baseurl}/event/#{event.id} +p #{event.tags.join(', ')} hr -#{config.title} - #{config.description} \ No newline at end of file +if to_confirm + p Puoi confermare questo evento #{config.apiurl}qui +else + p Puoi eliminare queste notifiche qui +#{config.title} - #{config.description} diff --git a/app/model.js b/app/model.js index 2ff5d4d3..81e07db1 100644 --- a/app/model.js +++ b/app/model.js @@ -1,4 +1,4 @@ const User = require('./models/user') -const { Event, Comment, Tag, Place, Reminder, EventReminder } = require('./models/event') +const { Event, Comment, Tag, Place, Notification, EventNotification } = require('./models/event') -module.exports = { User, Event, Comment, Tag, Place, Reminder, EventReminder } +module.exports = { User, Event, Comment, Tag, Place, Notification, EventNotification } diff --git a/app/models/event.js b/app/models/event.js index 0928c10e..334b8ef1 100644 --- a/app/models/event.js +++ b/app/models/event.js @@ -24,11 +24,14 @@ const Comment = db.define('comment', { text: Sequelize.STRING }) -const Reminder = db.define('reminder', { +const Notification = db.define('notification', { filters: Sequelize.JSON, email: Sequelize.STRING, - notify_on_add: Sequelize.BOOLEAN, - send_reminder: Sequelize.BOOLEAN + remove_code: Sequelize.STRING, + type: { + type: Sequelize.ENUM, + values: ['mail', 'admin_mail', 'activity_pub'] + } }) const Place = db.define('place', { @@ -42,9 +45,9 @@ Event.hasMany(Comment) Event.belongsToMany(Tag, { through: 'tagEvent' }) Tag.belongsToMany(Event, { through: 'tagEvent' }) -const EventReminder = db.define('EventReminder') -Event.belongsToMany(Reminder, { through: EventReminder }) -Reminder.belongsToMany(Event, { through: EventReminder }) +const EventNotification = db.define('EventNotification') +Event.belongsToMany(Notification, { through: EventNotification }) +Notification.belongsToMany(Event, { through: EventNotification }) Event.belongsTo(User) Event.belongsTo(Place) @@ -52,4 +55,4 @@ Event.belongsTo(Place) User.hasMany(Event) Place.hasMany(Event) -module.exports = { Event, Comment, Tag, Place, Reminder, EventReminder } +module.exports = { Event, Comment, Tag, Place, Notification, EventNotification } diff --git a/app/server.js b/app/server.js index e7006ffb..8b8b7be2 100644 --- a/app/server.js +++ b/app/server.js @@ -4,6 +4,7 @@ const bodyParser = require('body-parser') const api = require('./api') const cors = require('cors') const path = require('path') +const config = require('./config') const port = process.env.PORT || 9000 app.set('views', path.join(__dirname, 'views')) @@ -19,4 +20,4 @@ app.use('/js', express.static(path.join(__dirname, '..', 'client', 'dist', 'js') app.use('*', express.static(path.join(__dirname, '..', 'client', 'dist', 'index.html'))) app.listen(port) -console.log('Magic happens at http://localhost:' + port) +console.log(`[${config.title}] Started ${process.env.NODE_ENV} mode at ${config.baseurl} (api @ ${config.apiurl})`, config) diff --git a/client/src/api.js b/client/src/api.js index f7d73a48..d293039e 100644 --- a/client/src/api.js +++ b/client/src/api.js @@ -46,7 +46,7 @@ export default { getAllEvents: (month, year) => get(`/event/${year}/${month}/`), getUnconfirmedEvents: () => get('/event/unconfirmed'), confirmEvent: id => get(`/event/confirm/${id}`), - emailReminder: reminder => post('/event/reminder', reminder), + addNotification: notification => post('/event/notification', notification), addEvent: event => post('/user/event', event), updateEvent: event => put('/user/event', event), updatePlace: place => put('/place', place), diff --git a/client/src/components/Export.vue b/client/src/components/Export.vue index f89b8806..f5f86628 100644 --- a/client/src/components/Export.vue +++ b/client/src/components/Export.vue @@ -12,11 +12,11 @@ el-tab-pane.pt-1(label='email' name='email') p(v-html='$t(`export_email_explanation`)') b-form - el-switch(v-model='reminder.notify_on_add' :active-text="$t('notify_on_insert')") - br - //- el-switch.mt-2(v-model='reminder.send_reminder' :active-text="$t('send_reminder')") - el-input.mt-2(v-model='reminder.email' :placeholder="$t('Insert your address')") - el-button.mt-2.float-right(type='success' @click='add_reminder') {{$t('Send')}} + //- el-switch(v-model='notification.notify_on_add' :active-text="$t('notify_on_insert')") + //- br + //- el-switch.mt-2(v-model='notification.send_notification' :active-text="$t('send_notification')") + el-input.mt-2(v-model='notification.email' :placeholder="$t('Insert your address')") + el-button.mt-2.float-right(type='success' @click='add_notification') {{$t('Send')}} el-tab-pane.pt-1(label='feed rss' name='feed') span(v-html='$t(`export_feed_explanation`)') @@ -67,9 +67,9 @@ export default { return { type: 'email', link: '', - reminder: { notify_on_add: true, send_reminder: false }, export_list: true, script: ``, + notification: { email: '' }, } }, filters, @@ -82,8 +82,8 @@ export default { } }, methods: { - async add_reminder () { - await api.emailReminder({ ...this.reminder, filters: this.filters}) + async add_notification () { + await api.addNotification({ ...this.notification, filters: this.filters}) this.$refs.modal.hide() }, loadLink () { diff --git a/client/src/components/Settings.vue b/client/src/components/Settings.vue index 40b6e601..b4b96b14 100644 --- a/client/src/components/Settings.vue +++ b/client/src/components/Settings.vue @@ -1,14 +1,9 @@