diff --git a/src/cloudron.js b/src/cloudron.js index 38dd0a9c5..be1aa677e 100644 --- a/src/cloudron.js +++ b/src/cloudron.js @@ -19,8 +19,7 @@ exports = module.exports = { reboot: reboot, migrate: migrate, backup: backup, - ensureBackup: ensureBackup -}; + ensureBackup: ensureBackup}; var apps = require('./apps.js'), AppsError = require('./apps.js').AppsError, @@ -33,6 +32,7 @@ var apps = require('./apps.js'), debug = require('debug')('box:cloudron'), fs = require('fs'), locker = require('./locker.js'), + mailer = require('./mailer.js'), path = require('path'), paths = require('./paths.js'), progress = require('./progress.js'), @@ -634,4 +634,3 @@ function backupBoxAndApps(callback) { }); }); } - diff --git a/src/mailer.js b/src/mailer.js index 1639a5e68..9068230b3 100644 --- a/src/mailer.js +++ b/src/mailer.js @@ -15,7 +15,11 @@ exports = module.exports = { sendCrashNotification: sendCrashNotification, - appDied: appDied + appDied: appDied, + + FEEDBACK_TYPE_FEEDBACK: 'feedback', + FEEDBACK_TYPE_TICKET: 'ticket', + sendFeedback: sendFeedback }; var assert = require('assert'), @@ -277,3 +281,22 @@ function sendCrashNotification(program, context) { enqueue(mailOptions); } + +function sendFeedback(user, type, subject, description, callback) { + assert.strictEqual(typeof user, 'object'); + assert.strictEqual(typeof type, 'string'); + assert.strictEqual(typeof subject, 'string'); + assert.strictEqual(typeof description, 'string'); + assert.strictEqual(typeof callback, 'function'); + + assert(type === exports.FEEDBACK_TYPE_TICKET || type === exports.FEEDBACK_TYPE_FEEDBACK); + + var mailOptions = { + from: config.get('adminEmail'), + to: 'johannes@cloudron.io', + subject: util.format('[%s] %s - %s', type, config.fqdn(), subject), + text: render('feedback.ejs', { fqdn: config.fqdn(), adminEmail: config.get('adminEmail'), type: type, user: user, subject: subject, description: description}) + }; + + enqueue(mailOptions); +} diff --git a/src/routes/cloudron.js b/src/routes/cloudron.js index d2a9b58c7..a9f338a54 100644 --- a/src/routes/cloudron.js +++ b/src/routes/cloudron.js @@ -11,7 +11,8 @@ exports = module.exports = { getConfig: getConfig, update: update, migrate: migrate, - setCertificate: setCertificate + setCertificate: setCertificate, + feedback: feedback }; var assert = require('assert'), @@ -157,3 +158,16 @@ function setCertificate(req, res, next) { next(new HttpSuccess(202, {})); }); } + +function feedback(req, res, next) { + assert.strictEqual(typeof req.user, 'object'); + + if (typeof req.body.type !== 'string') return next(new HttpError(400, 'type must be either "ticket" or "feedback"')); + if (typeof req.body.subject !== 'string') return next(new HttpError(400, 'subject must be string')); + if (typeof req.body.description !== 'string') return next(new HttpError(400, 'description must be string')); + + cloudron.feedback(req.user, req.body.type, req.body.subject, req.body.description, function (error) { + if (error) return next(new HttpError(500, error)); + next(new HttpSuccess(201, {})); + }); +} diff --git a/src/server.js b/src/server.js index 739285ba3..da43dca20 100644 --- a/src/server.js +++ b/src/server.js @@ -102,6 +102,9 @@ function initializeExpressSync() { router.post('/api/v1/cloudron/certificate', rootScope, multipart, routes.cloudron.setCertificate); router.get ('/api/v1/cloudron/graphs', rootScope, routes.graphs.getGraphs); + // feedback + router.post('/api/v1/cloudron/feedback', usersScope, routes.cloudron.feedback); + router.get ('/api/v1/profile', profileScope, routes.user.profile); router.get ('/api/v1/users', usersScope, routes.user.list);