diff --git a/CHANGES b/CHANGES index b78d365a0..0acdde68f 100644 --- a/CHANGES +++ b/CHANGES @@ -1753,4 +1753,5 @@ [4.4.2] * Fix crash when reporting that DKIM is not setup correctly * Stopped apps cannot be updated or auto-updated +* eventlog: track support ticket creation and remote support status diff --git a/src/appstore.js b/src/appstore.js index a8b24c4ca..ff6f9d494 100644 --- a/src/appstore.js +++ b/src/appstore.js @@ -447,13 +447,14 @@ function registerWithLoginCredentials(options, callback) { }); } -function createTicket(info, callback) { +function createTicket(info, auditSource, callback) { assert.strictEqual(typeof info, 'object'); assert.strictEqual(typeof info.email, 'string'); assert.strictEqual(typeof info.displayName, 'string'); assert.strictEqual(typeof info.type, 'string'); assert.strictEqual(typeof info.subject, 'string'); assert.strictEqual(typeof info.description, 'string'); + assert.strictEqual(typeof auditSource, 'object'); assert.strictEqual(typeof callback, 'function'); function collectAppInfoIfNeeded(callback) { @@ -478,6 +479,8 @@ function createTicket(info, callback) { if (result.statusCode === 422) return callback(new BoxError(BoxError.LICENSE_ERROR, result.body.message)); if (result.statusCode !== 201) return callback(new BoxError(BoxError.EXTERNAL_ERROR, util.format('Bad response: %s %s', result.statusCode, result.text))); + eventlog.add(eventlog.ACTION_SUPPORT_TICKET, auditSource, info); + callback(null); }); }); diff --git a/src/eventlog.js b/src/eventlog.js index 780736b79..1450dd3da 100644 --- a/src/eventlog.js +++ b/src/eventlog.js @@ -57,6 +57,9 @@ exports = module.exports = { ACTION_DYNDNS_UPDATE: 'dyndns.update', + ACTION_SUPPORT_TICKET: 'support.ticket', + ACTION_SUPPORT_SSH: 'support.ssh', + ACTION_PROCESS_CRASH: 'system.crash' }; diff --git a/src/routes/support.js b/src/routes/support.js index 5787ea663..ecf86ceb1 100644 --- a/src/routes/support.js +++ b/src/routes/support.js @@ -9,6 +9,7 @@ exports = module.exports = { var appstore = require('../appstore.js'), assert = require('assert'), + auditSource = require('../auditsource.js'), custom = require('../custom.js'), HttpError = require('connect-lastmile').HttpError, HttpSuccess = require('connect-lastmile').HttpSuccess, @@ -29,7 +30,7 @@ function createTicket(req, res, next) { if (req.body.appId && typeof req.body.appId !== 'string') return next(new HttpError(400, 'appId must be string')); if (req.body.altEmail && typeof req.body.altEmail !== 'string') return next(new HttpError(400, 'altEmail must be string')); - appstore.createTicket(_.extend({ }, req.body, { email: req.user.email, displayName: req.user.displayName }), function (error) { + appstore.createTicket(_.extend({ }, req.body, { email: req.user.email, displayName: req.user.displayName }), auditSource.fromRequest(req), function (error) { if (error) return next(new HttpError(503, `Error contacting cloudron.io: ${error.message}. Please email ${custom.spec().support.email}`)); next(new HttpSuccess(201, { message: `An email for sent to ${custom.spec().support.email}. We will get back shortly!` })); @@ -43,7 +44,7 @@ function enableRemoteSupport(req, res, next) { if (typeof req.body.enable !== 'boolean') return next(new HttpError(400, 'enabled is required')); - support.enableRemoteSupport(req.body.enable, function (error) { + support.enableRemoteSupport(req.body.enable, auditSource.fromRequest(req), function (error) { if (error) return next(new HttpError(503, 'Error enabling remote support. Try running "cloudron-support --enable-ssh" on the server')); next(new HttpSuccess(202, {})); diff --git a/src/support.js b/src/support.js index 4d40a455f..b4c994ad0 100644 --- a/src/support.js +++ b/src/support.js @@ -8,11 +8,12 @@ exports = module.exports = { let assert = require('assert'), BoxError = require('./boxerror.js'), constants = require('./constants.js'), - shell = require('./shell.js'), + eventlog = require('./eventlog.js'), once = require('once'), path = require('path'), paths = require('./paths.js'), - settings = require('./settings.js'); + settings = require('./settings.js'), + shell = require('./shell.js'); // the logic here is also used in the cloudron-support tool const AUTHORIZED_KEYS_CMD = path.join(__dirname, 'scripts/remotesupport.sh'); @@ -48,13 +49,17 @@ function getRemoteSupport(callback) { cp.stdout.on('data', (data) => result = result + data.toString('utf8')); } -function enableRemoteSupport(enable, callback) { +function enableRemoteSupport(enable, auditSource, callback) { + assert.strictEqual(typeof enable, 'boolean'); + assert.strictEqual(typeof auditSource, 'object'); assert.strictEqual(typeof callback, 'function'); let si = sshInfo(); shell.sudo('support', [ AUTHORIZED_KEYS_CMD, enable ? 'enable' : 'disable', si.filePath, si.user ], {}, function (error) { if (error) callback(new BoxError(BoxError.FS_ERROR, error)); + eventlog.add(eventlog.ACTION_SUPPORT_SSH, auditSource, { enable }); + callback(); }); }