diff --git a/src/apptask.js b/src/apptask.js index 52332e475..7c0145008 100644 --- a/src/apptask.js +++ b/src/apptask.js @@ -25,6 +25,7 @@ var addons = require('./addons.js'), apps = require('./apps.js'), assert = require('assert'), async = require('async'), + auditsource = require('./auditsource.js'), backups = require('./backups.js'), config = require('./config.js'), database = require('./database.js'), @@ -34,6 +35,7 @@ var addons = require('./addons.js'), domains = require('./domains.js'), DomainsError = domains.DomainsError, ejs = require('ejs'), + eventlog = require('./eventlog.js'), fs = require('fs'), manifestFormat = require('cloudron-manifestformat'), mkdirp = require('mkdirp'), @@ -789,7 +791,7 @@ function update(app, callback) { debugApp(app, 'Error updating app: %s', error); updateApp(app, { installationState: appdb.ISTATE_ERROR, installationProgress: error.message, updateTime: new Date() }, callback.bind(null, error)); } else { - callback(null); + eventlog.add(eventlog.ACTION_APP_UPDATE_FINISH, auditsource.APP_TASK, { app: app, success: true }, callback); } }); } diff --git a/src/auditsource.js b/src/auditsource.js index c9a0bc608..82073f2a9 100644 --- a/src/auditsource.js +++ b/src/auditsource.js @@ -5,6 +5,7 @@ exports = module.exports = { HEALTH_MONITOR: { userId: null, username: 'healthmonitor' }, SYSADMIN: { userId: null, username: 'sysadmin' }, TASK_MANAGER: { userId: null, username: 'taskmanager' }, + APP_TASK: { userId: null, username: 'apptask' }, fromRequest: fromRequest }; diff --git a/src/eventlog.js b/src/eventlog.js index 09a0ed8fa..bf3c5109c 100644 --- a/src/eventlog.js +++ b/src/eventlog.js @@ -17,6 +17,7 @@ exports = module.exports = { ACTION_APP_RESTORE: 'app.restore', ACTION_APP_UNINSTALL: 'app.uninstall', ACTION_APP_UPDATE: 'app.update', + ACTION_APP_UPDATE_FINISH: 'app.update.finish', ACTION_APP_LOGIN: 'app.login', ACTION_APP_OOM: 'app.oom', ACTION_APP_UP: 'app.up', diff --git a/src/mail_templates/app_updated.ejs b/src/mail_templates/app_updated.ejs new file mode 100644 index 000000000..5389eb1c2 --- /dev/null +++ b/src/mail_templates/app_updated.ejs @@ -0,0 +1,13 @@ +<%if (format === 'text') { %> + +Dear Cloudron Admin, + +The application '<%= title %>' installed at <%= appFqdn %> was updated to app package version <%= version %>. + +Powered by https://cloudron.io + +Sent at: <%= new Date().toUTCString() %> + +<% } else { %> + +<% } %> diff --git a/src/notifications.js b/src/notifications.js index c132e8d66..37827a627 100644 --- a/src/notifications.js +++ b/src/notifications.js @@ -230,6 +230,17 @@ function appDied(eventId, app, callback) { }, callback); } +function appUpdated(eventId, app, callback) { + assert.strictEqual(typeof eventId, 'string'); + assert.strictEqual(typeof app, 'object'); + assert.strictEqual(typeof callback, 'function'); + + actionForAllAdmins([], function (admin, done) { + mailer.appUpdated(admin.email, app); + add(admin.id, eventId, `App ${app.fqdn} updated`, `The application ${app.manifest.title} installed at ${app.fqdn} was updated to version ${app.manifest.version}.`, done); + }, callback); +} + function certificateRenewalError(eventId, vhost, errorMessage, callback) { assert.strictEqual(typeof eventId, 'string'); assert.strictEqual(typeof vhost, 'string'); @@ -328,6 +339,9 @@ function onEvent(id, action, source, data, callback) { case eventlog.ACTION_APP_UP: return appUp(id, data.app, callback); + case eventlog.ACTION_APP_UPDATE_FINISH: + return appUpdated(id, data.app, callback); + case eventlog.ACTION_CERTIFICATE_RENEWAL: case eventlog.ACTION_CERTIFICATE_NEW: if (!data.errorMessage) return callback();