diff --git a/components/Calendar.vue b/components/Calendar.vue index 61cbfbce..62d88cfd 100644 --- a/components/Calendar.vue +++ b/components/Calendar.vue @@ -25,8 +25,8 @@ export default { page: { month, year}, } }, - watch: { + // month selected page () { this.updateEvents(this.page) } diff --git a/config.example.js b/config.example.js index 38ba8953..b5af33fb 100644 --- a/config.example.js +++ b/config.example.js @@ -1,18 +1,19 @@ -/** - * GANCIO CONFIGURATION - */ -const env = process.env.NODE_ENV || 'development' +const path = require('path') /** - * Database configuration + * -[ GANCIO CONFIGURATION ]- + * + * -[ Database configuration ]- * `development` configuration is enabled running `yarn dev` * while `production` with `yarn start` * ref: http://docs.sequelizejs.com/class/lib/sequelize.js~Sequelize.html#instance-constructor-constructor + * */ + const DB_CONF = { development: { - storage: __dirname + '/db.sqlite', - dialect: 'sqlite', + storage: path.join(__dirname, 'db.sqlite'), + dialect: 'sqlite' }, production: { username: '', @@ -21,16 +22,32 @@ const DB_CONF = { host: 'localhost', dialect: 'postgres', logging: false - }, + } } -const SECRET_CONF = { +const env = process.env.NODE_ENV || 'development' + +/** + * -[ Main configuration ]- + * + */ +const config = { + server: { + port: '3000', + host: '0', + // uncomment to use unix socket to serve gancio + // path: '/tmp/gancio_socket', + }, + locale: 'it', + title: 'GANCIO', + description: 'A shared agenda for radical communities', + baseurl: '' || 'http://localhost:3000', + // where events/users confirmation email are sent - admin: 'gancio@example.com', + admin: '', - db: DB_CONF[env], - - // jwt salt secret (generate it randomly) + // jwt salt secret, generate it randomly with + // < /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c${1:-32};echo; secret: '', // smtp account to send email @@ -42,17 +59,7 @@ const SECRET_CONF = { pass: process.env.SMTP_PASS || '' } }, + db: DB_CONF[env] } -/** - * Main Gancio configuration - */ -const SHARED_CONF = { - locale: 'it', - title: 'GANCIO', - description: 'A calendar for radical communities', - baseurl: '' || 'http://localhost:3000', - env -} - -module.exports = { SHARED_CONF, SECRET_CONF, ...SECRET_CONF.db } +module.exports = config diff --git a/nuxt.config.js b/nuxt.config.js index 42ae54ef..1dc4f014 100644 --- a/nuxt.config.js +++ b/nuxt.config.js @@ -2,7 +2,7 @@ const argv = require('yargs').argv const path = require('path') const config_path = path.resolve(argv.config || './config.js') -const config = require(config_path).SHARED_CONF +const config = require(config_path) module.exports = { mode: 'universal', @@ -36,7 +36,9 @@ module.exports = { 'element-ui/lib/theme-chalk/index.css' ], env: { - config + baseurl: config.baseurl, + title: config.title, + description: config.description }, /* ** Plugins to load before mounting the App @@ -83,9 +85,22 @@ module.exports = { ** Build configuration */ build: { + optimization: { + splitChunks: { + cacheGroups: { + element: { + test: /[\\/]node_modules[\\/](element-ui)[\\/]/, + name: 'element-ui', + chunks: 'all' + } + } + } + }, transpile: [/^element-ui/, /^vue-awesome/], splitChunks: { layouts: true - } + }, + cache: true, + parallel: true } } diff --git a/pages/export.vue b/pages/export.vue index 80bdbcdb..73ef1891 100644 --- a/pages/export.vue +++ b/pages/export.vue @@ -107,7 +107,7 @@ export default { params.push(`places=${this.filters.places}`) } - return `` + return `` }, link () { const tags = this.filters.tags.join(',') @@ -123,7 +123,7 @@ export default { } } - return `/api/export/${this.type}${query}` + return `${process.env.baseurl}/api/export/${this.type}${query}` }, showLink () { return (['feed', 'ics'].indexOf(this.type)>-1) diff --git a/server/api/controller/export.js b/server/api/controller/export.js index ff920e52..14c308ca 100644 --- a/server/api/controller/export.js +++ b/server/api/controller/export.js @@ -42,7 +42,7 @@ const exportController = { feed(res, events) { res.type('application/rss+xml; charset=UTF-8') - res.render('feed/rss.pug', { events, config: process.env.config, moment }) + res.render('feed/rss.pug', { events, config: process.env, moment }) }, ics(res, events) { diff --git a/server/api/controller/settings.js b/server/api/controller/settings.js index 4830c85f..16c31ba0 100644 --- a/server/api/controller/settings.js +++ b/server/api/controller/settings.js @@ -1,8 +1,6 @@ const Mastodon = require('mastodon-api') const { setting: Setting } = require('../models') -const baseurl = process.env.baseurl - const settingsController = { async setAdminSetting(key, value) { @@ -20,7 +18,7 @@ const settingsController = { async getAuthURL(req, res) { const instance = req.body.instance - const callback = `${baseurl}/api/settings/oauth` + const callback = `${process.env.baseurl}/api/settings/oauth` const { client_id, client_secret } = await Mastodon.createOAuthApp(`https://${instance}/api/v1/apps`, 'gancio', 'read write', callback) const url = await Mastodon.getAuthorizationUrl(client_id, client_secret, @@ -33,7 +31,7 @@ const settingsController = { async code(req, res) { const code = req.query.code let client_id, client_secret, instance - const callback = `${baseurl}/api/settings/oauth` + const callback = `${process.env.baseurl}/api/settings/oauth` const settings = await settingsController.settings() diff --git a/server/api/controller/user.js b/server/api/controller/user.js index 401c9e54..475f80cb 100644 --- a/server/api/controller/user.js +++ b/server/api/controller/user.js @@ -30,7 +30,7 @@ const userController = { email: user.email, scope: [user.is_admin ? 'admin' : 'user'] }, - config.SECRET_CONF.secret + config.secret ) res.json({ token: accessToken }) @@ -164,7 +164,7 @@ const userController = { if (!user) return res.sendStatus(200) user.recover_code = crypto.randomBytes(16).toString('hex') - mail.send(user.email, 'recover', { user, config: config.SHARED_CONF }) + mail.send(user.email, 'recover', { user, config }) await user.save() res.sendStatus(200) @@ -208,7 +208,7 @@ const userController = { const user = await User.findByPk(req.body.id) if (user) { if (!user.is_active && req.body.is_active) { - await mail.send(user.email, 'confirm', { user, config: config.SHARED_CONF }) + await mail.send(user.email, 'confirm', { user, config }) } await user.update(req.body) res.json(user) @@ -229,7 +229,7 @@ const userController = { const user = await User.create(req.body) try { - mail.send([user.email, config.SECRET_CONF.admin], 'register', { user, config: config.SHARED_CONF }) + mail.send([user.email, config.admin], 'register', { user, config }) } catch (e) { return res.status(400).json(e) } @@ -238,7 +238,7 @@ const userController = { email: user.email, scope: [user.is_admin ? 'admin' : 'user'] } - const token = jwt.sign(payload, config.SECRET_CONF.secret) + const token = jwt.sign(payload, config.secret) res.json({ token, user }) } catch (e) { res.status(404).json(e) diff --git a/server/api/index.js b/server/api/index.js index 29a74c13..f193a412 100644 --- a/server/api/index.js +++ b/server/api/index.js @@ -22,7 +22,7 @@ api.use(bodyParser.urlencoded({ extended: false })) api.use(bodyParser.json()) const jwt = expressJwt({ - secret: config.SECRET_CONF.secret, + secret: config.secret, credentialsRequired: false }) diff --git a/server/api/mail.js b/server/api/mail.js index bba20259..5941e85a 100644 --- a/server/api/mail.js +++ b/server/api/mail.js @@ -3,7 +3,7 @@ const path = require('path') const moment = require('moment') const config = require('../config') -moment.locale(config.SHARED_CONF.locale) +moment.locale(config.locale) const mail = { send(addresses, template, locals) { const email = new Email({ @@ -17,25 +17,25 @@ const mail = { } }, message: { - from: `${config.SHARED_CONF.title} <${config.SECRET_CONF.smtp.auth.user}>` + from: `${config.title} <${config.smtp.auth.user}>` }, send: true, i18n: { directory: path.join(__dirname, '..', '..', 'locales', 'email'), - defaultLocale: config.SHARED_CONF.locale + defaultLocale: config.locale }, - transport: config.SECRET_CONF.smtp + transport: config.smtp }) const msg = { template, message: { to: addresses, - bcc: config.SECRET_CONF.admin + bcc: config.admin }, locals: { ...locals, - locale: config.SHARED_CONF.locale, - config: config.SHARED_CONF, + locale: config.locale, + config: { title: config.title, baseurl: config.baseurl, description: config.description }, datetime: datetime => moment(datetime).format('ddd, D MMMM HH:mm') } } diff --git a/server/api/models/index.js b/server/api/models/index.js index d1a23202..a9ad2343 100644 --- a/server/api/models/index.js +++ b/server/api/models/index.js @@ -4,10 +4,10 @@ const path = require('path') const Sequelize = require('sequelize') const config_path = path.resolve(argv.config || './config.js') const basename = path.basename(__filename) -const config = require(config_path).SECRET_CONF.db +const config = require(config_path) const db = {} -const sequelize = new Sequelize(config) +const sequelize = new Sequelize(config.db) fs .readdirSync(__dirname) diff --git a/server/config.js b/server/config.js index 9d657f2a..58df4115 100644 --- a/server/config.js +++ b/server/config.js @@ -3,5 +3,3 @@ const path = require('path') const config_path = path.resolve(argv.config || './config.js') module.exports = require(config_path) - - diff --git a/server/firstrun.js b/server/firstrun.js index 502912dc..53fbc78b 100644 --- a/server/firstrun.js +++ b/server/firstrun.js @@ -10,8 +10,8 @@ if (!fs.existsSync(config_path)) { process.exit(1) } -const { SECRET_CONF, SHARED_CONF } = require(config_path) -if (!SECRET_CONF.secret) { +const config = require(config_path) +if (!config.secret) { console.error(`Please specify a random 'secret' in '${config_path}'!`) process.exit(1) } @@ -19,9 +19,9 @@ if (!SECRET_CONF.secret) { const Sequelize = require('sequelize') let db try { - db = new Sequelize(SECRET_CONF.db) + db = new Sequelize(config.db) } catch (e) { - console.error(`DB Error: check '${SHARED_CONF.env}' configuration.\n (sequelize error -> ${e})`) + console.error(`DB Error: check '${config.env}' configuration.\n (sequelize error -> ${e})`) process.exit(1) } @@ -29,13 +29,13 @@ try { module.exports = db.authenticate() .then(() => { require('./api/models') - if (SHARED_CONF.env === 'development') { + if (config.env === 'development') { console.error('DB Force sync') return db.sync({ force: true }) } }) .catch(e => { console.error(e) - console.error(`DB Error: check '${SHARED_CONF.env}' configuration\n (sequelize error -> ${e})`) + console.error(`DB Error: check '${config.env}' configuration\n (sequelize error -> ${e})`) process.exit(1) }) diff --git a/server/index.js b/server/index.js index d205da28..c32e04d2 100644 --- a/server/index.js +++ b/server/index.js @@ -6,17 +6,18 @@ const morgan = require('morgan') const { Nuxt, Builder } = require('nuxt') const firstRun = require('./firstrun') // Import and Set Nuxt.js options -const config = require('../nuxt.config.js') +const nuxt_config = require('../nuxt.config.js') +const config = require('./config') const app = express() async function start() { // Init Nuxt.js - const nuxt = new Nuxt(config) + const nuxt = new Nuxt(nuxt_config) - const { host, port } = nuxt.options.server + // const { host, port } = nuxt.options.server // Build only in dev mode - if (config.dev) { + if (nuxt_config.dev) { const builder = new Builder(nuxt) await builder.build() } else { @@ -29,10 +30,26 @@ async function start() { app.use(nuxt.render) // Listen the server - app.listen(port, host) - consola.ready({ - message: `Server listening on http://${host}:${port}`, - badge: true + const server = app.listen(config.server) + + // close connections/port/unix socket + function shutdown() { + consola.info(`Closing connections..`) + server.close() + } + process.on('SIGTERM', shutdown) + process.on('SIGINT', shutdown) + + server.on('error', e => { + consola.error(e) + }) + + server.on('listening', () => { + const address = server.address() + consola.ready({ + message: `Server listening on ${(typeof address) === 'object' ? `${address.address}:${address.port}` : address}`, + badge: true + }) }) } diff --git a/server/notifier.js b/server/notifier.js index 0a40082f..946cba5e 100644 --- a/server/notifier.js +++ b/server/notifier.js @@ -1,7 +1,7 @@ -// const mail = require('./mail') +const mail = require('./mail') const bot = require('./api/controller/bot') const settingsController = require('./api/controller/settings') -// const config = require('./config.js') +const config = require('./config.js') const { Event, Notification, EventNotification, User, Place, Tag } = require('./api/models') @@ -12,10 +12,10 @@ async function sendNotification(notification, event, eventNotification) { switch (notification.type) { // case 'mail': // return mail.send(notification.email, 'event', { event, config, notification }) - // case 'admin_email': + case 'admin_email': // const admins = await User.findAll({ where: { is_admin: true } }) // const admin_emails = admins.map(admin => admin.email) - // return mail.send(admin_emails, 'event', { event, to_confirm: true, notification }) + return mail.send(admin_emails, 'event', { event, to_confirm: true, notification }) case 'mastodon': // instance publish if (settings.mastodon_auth.instance && settings.mastodon_auth.access_token) { @@ -58,8 +58,4 @@ function startLoop(seconds) { interval = setInterval(notify, seconds * 1000) } -function stopLoop() { - stopInterval(interval) -} - -module.exports = { startLoop, stopLoop } +startLoop(26000) diff --git a/server/api/views/feed/rss.pug b/views/feed/rss.pug similarity index 100% rename from server/api/views/feed/rss.pug rename to views/feed/rss.pug