diff --git a/src/digest.js b/src/digest.js index 87b3f2547..dc53672f9 100644 --- a/src/digest.js +++ b/src/digest.js @@ -33,31 +33,38 @@ function maybeSend(callback) { var hasSubscription = result && result.plan.id !== 'free' && result.plan.id !== 'undecided'; - eventlog.getByActionLastWeek(eventlog.ACTION_APP_UPDATE, function (error, appUpdates) { + eventlog.getByCreationTime(new Date(new Date() - 7*86400000), function (error, events) { if (error) return callback(error); - eventlog.getByActionLastWeek(eventlog.ACTION_UPDATE, function (error, boxUpdates) { - if (error) return callback(error); + var appUpdates = events.filter(function (e) { return e.action === eventlog.ACTION_APP_UPDATE; }).map(function (e) { return e.data; }); + var boxUpdates = events.filter(function (e) { return e.action === eventlog.ACTION_UPDATE; }).map(function (e) { return e.data; }); + var certRenewals = events.filter(function (e) { return e.action === eventlog.ACTION_CERTIFICATE_RENEWAL; }).map(function (e) { return e.data; }); + var usersAdded = events.filter(function (e) { return e.action === eventlog.ACTION_USER_ADD; }).map(function (e) { return e.data; }); + var usersRemoved = events.filter(function (e) { return e.action === eventlog.ACTION_USER_REMOVE; }).map(function (e) { return e.data; }); + var finishedBackups = events.filter(function (e) { return e.action === eventlog.ACTION_BACKUP_FINISH; }).map(function (e) { return e.data; }); - var info = { - hasSubscription: hasSubscription, + if (error) return callback(error); - pendingAppUpdates: pendingAppUpdates, - pendingBoxUpdate: updateInfo.box || null, + var info = { + hasSubscription: hasSubscription, - finishedAppUpdates: (appUpdates || []).map(function (e) { return e.data; }), - finishedBoxUpdates: (boxUpdates || []).map(function (e) { return e.data; }) - }; + pendingAppUpdates: pendingAppUpdates, + pendingBoxUpdate: updateInfo.box || null, - if (info.pendingAppUpdates.length || info.pendingBoxUpdate || info.finishedAppUpdates.length || info.finishedBoxUpdates.length) { - debug('maybeSend: sending digest email', info); - mailer.sendDigest(info); - } else { - debug('maybeSend: nothing happened, NOT sending digest email'); - } + finishedAppUpdates: appUpdates, + finishedBoxUpdates: boxUpdates, - callback(); - }); + certRenewals: certRenewals, + finishedBackups: finishedBackups, + usersAdded: usersAdded, + usersRemoved: usersRemoved // unused because we don't have username to work with + }; + + // always send digest for backup failure notification + debug('maybeSend: sending digest email', info); + mailer.sendDigest(info); + + callback(); }); }); }); diff --git a/src/eventlog.js b/src/eventlog.js index 6fef19c8d..6678a4046 100644 --- a/src/eventlog.js +++ b/src/eventlog.js @@ -6,7 +6,7 @@ exports = module.exports = { add: add, get: get, getAllPaged: getAllPaged, - getByActionLastWeek: getByActionLastWeek, + getByCreationTime: getByCreationTime, cleanup: cleanup, // keep in sync with webadmin index.js filter and CLI tool @@ -98,21 +98,21 @@ function getAllPaged(action, search, page, perPage, callback) { assert.strictEqual(typeof perPage, 'number'); assert.strictEqual(typeof callback, 'function'); - eventlogdb.getAllPaged(action, search, page, perPage, function (error, boxes) { + eventlogdb.getAllPaged(action, search, page, perPage, function (error, events) { if (error) return callback(new EventLogError(EventLogError.INTERNAL_ERROR, error)); - callback(null, boxes); + callback(null, events); }); } -function getByActionLastWeek(action, callback) { - assert(typeof action === 'string' || action === null); +function getByCreationTime(creationTime, callback) { + assert(util.isDate(creationTime)); assert.strictEqual(typeof callback, 'function'); - eventlogdb.getByActionLastWeek(action, function (error, boxes) { + eventlogdb.getByCreationTime(creationTime, function (error, events) { if (error) return callback(new EventLogError(EventLogError.INTERNAL_ERROR, error)); - callback(null, boxes); + callback(null, events); }); } @@ -120,7 +120,7 @@ function cleanup(callback) { callback = callback || NOOP_CALLBACK; var d = new Date(); - d.setDate(d.getDate() - 7); // 7 days ago + d.setDate(d.getDate() - 10); // 10 days ago // only cleanup high frequency events var actions = [ diff --git a/src/eventlogdb.js b/src/eventlogdb.js index 9cf0c98a2..98ebda415 100644 --- a/src/eventlogdb.js +++ b/src/eventlogdb.js @@ -3,7 +3,7 @@ exports = module.exports = { get: get, getAllPaged: getAllPaged, - getByActionLastWeek: getByActionLastWeek, + getByCreationTime: getByCreationTime, add: add, count: count, delByCreationTime: delByCreationTime, @@ -73,12 +73,12 @@ function getAllPaged(action, search, page, perPage, callback) { }); } -function getByActionLastWeek(action, callback) { - assert(typeof action === 'string' || action === null); +function getByCreationTime(creationTime, callback) { + assert(util.isDate(creationTime)); assert.strictEqual(typeof callback, 'function'); - var query = 'SELECT ' + EVENTLOGS_FIELDS + ' FROM eventlog WHERE action=? AND creationTime >= DATE_SUB(NOW(), INTERVAL 1 WEEK) ORDER BY creationTime DESC'; - database.query(query, [ action ], function (error, results) { + var query = 'SELECT ' + EVENTLOGS_FIELDS + ' FROM eventlog WHERE creationTime >= ?'; + database.query(query, [ creationTime ], function (error, results) { if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error)); results.forEach(postProcess); diff --git a/src/mail_templates/digest.ejs b/src/mail_templates/digest.ejs index b8de231fa..8f4cc6581 100644 --- a/src/mail_templates/digest.ejs +++ b/src/mail_templates/digest.ejs @@ -3,6 +3,18 @@ Dear <%= cloudronName %> Admin, This is the weekly summary of activities on your Cloudron <%= fqdn %>. +<% if (info.usersAdded.length) { -%> + +The following users were added: +<% for (var i = 0; i < info.usersAdded.length; i++) { -%> + * <%- info.usersAdded[i].email %> +<% }} -%> +<% if (info.certRenewals.length) { -%> + +The certificates of the following apps was renewed: +<% for (var i = 0; i < info.certRenewals.length; i++) { -%> + * <%- info.certRenewals[i].domain %> - <%- info.certRenewals[i].errorMessage || 'Success' %> +<% }} -%> <% if (info.pendingBoxUpdate) { -%> Cloudron v<%- info.pendingBoxUpdate.version %> is available: @@ -33,6 +45,14 @@ The following apps were updated: <% for (var j = 0; j < info.finishedAppUpdates[i].toManifest.changelog.trim().split('\n').length; j++) { -%> <%= info.finishedAppUpdates[i].toManifest.changelog.trim().split('\n')[j] %> <% }}} -%> +<% if (info.finishedBackups.length) { -%> + +Last successful backup: <%- info.finishedBackups[0].filename %> +<% } else { -%> + +This Cloudron did **not** backup successfully in the last week! +<% } -%> + <% if (!info.hasSubscription) { -%> *Keep your Cloudron automatically up-to-date and secure by upgrading to a paid plan at* <%= webadminUrl %>/#/settings @@ -56,6 +76,24 @@ Sent at: <%= new Date().toUTCString() %>
+ <% if (info.usersAdded.length) { -%> +

The following users were added:

+ + <% } %> + + <% if (info.certRenewals.length) { -%> +

The certificates of the following apps were renewed:

+ + <% } %> + <% if (info.pendingBoxUpdate) { -%>

Cloudron v<%- info.pendingBoxUpdate.version %> is available:

<% } %> + <% if (info.finishedBackups.length) { %> +

Last successful backup : <%= info.finishedBackups[0].filename %>

+ <% } else { %> +

This Cloudron did not backup successfully in the last week!

+ <% } %> +
<% if (!info.hasSubscription) { %> @@ -123,12 +167,12 @@ Sent at: <%= new Date().toUTCString() %>

-

+

Powered by Cloudron
Sent on <%= new Date().toUTCString() %>
-

+