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:
+The certificates of the following apps were renewed:
+Cloudron v<%- info.pendingBoxUpdate.version %> is available:
Last successful backup : <%= info.finishedBackups[0].filename %>
+ <% } else { %> +This Cloudron did not backup successfully in the last week!
+ <% } %> ++