diff --git a/src/digest.js b/src/digest.js deleted file mode 100644 index 509eb9c1a..000000000 --- a/src/digest.js +++ /dev/null @@ -1,65 +0,0 @@ -'use strict'; - -var assert = require('assert'), - async = require('async'), - debug = require('debug')('box:digest'), - eventlog = require('./eventlog.js'), - mailer = require('./mailer.js'), - settings = require('./settings.js'), - updatechecker = require('./updatechecker.js'), - users = require('./users.js'); - -exports = module.exports = { - send: send -}; - -function send(callback) { - assert.strictEqual(typeof callback, 'function'); - - settings.getEmailDigest(function (error, enabled) { - if (error) return callback(error); - - if (!enabled) { - debug('send: email digest is disabled'); - return callback(); - } - - var updateInfo = updatechecker.getUpdateInfo(); - var pendingAppUpdates = updateInfo.apps || {}; - pendingAppUpdates = Object.keys(pendingAppUpdates).map(function (key) { return pendingAppUpdates[key]; }); - - eventlog.getByCreationTime(new Date(new Date() - 7*86400000), function (error, events) { - 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 && e.data.boxUpdateInfo; }).map(function (e) { return e.data.boxUpdateInfo; }); - 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 && !e.errorMessage; }).map(function (e) { return e.data; }); - - if (error) return callback(error); - - var info = { - pendingAppUpdates: pendingAppUpdates, - pendingBoxUpdate: updateInfo.box || null, - - finishedAppUpdates: appUpdates, - finishedBoxUpdates: boxUpdates, - - certRenewals: certRenewals, - finishedBackups: finishedBackups, // only the successful backups - usersAdded: usersAdded, - usersRemoved: usersRemoved // unused because we don't have username to work with - }; - - debug('send: sending digest email', info); - - users.getAllAdmins(function (error, admins) { - if (error) return callback(error); - - async.eachSeries(admins, (admin, done) => mailer.sendDigest(admin.email, info, done), callback); - }); - }); - }); -} diff --git a/src/mail_templates/digest.ejs b/src/mail_templates/digest.ejs deleted file mode 100644 index 29f192121..000000000 --- a/src/mail_templates/digest.ejs +++ /dev/null @@ -1,174 +0,0 @@ -<% if (format === 'text') { -%> - -Dear <%= cloudronName %> Admin, - -This is a summary of the activities on your Cloudron. -<% 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: -<% for (var i = 0; i < info.pendingBoxUpdate.changelog.length; i++) { -%> - * <%- info.pendingBoxUpdate.changelog[i] %> -<% }} -%> -<% if (info.pendingAppUpdates.length) { -%> - -One or more app updates are available: -<% for (var i = 0; i < info.pendingAppUpdates.length; i++) { -%> - - <%= info.pendingAppUpdates[i].manifest.title %> package v<%= info.pendingAppUpdates[i].manifest.version %> -<% for (var j = 0; j < info.pendingAppUpdates[i].manifest.changelog.trim().split('\n').length; j++) { -%> - <%= info.pendingAppUpdates[i].manifest.changelog.trim().split('\n')[j] %> -<% }}} -%> -<% if (info.finishedBoxUpdates.length) { -%> - -Cloudron was updated with the following releases: -<% for (var i = 0; i < info.finishedBoxUpdates.length; i++) { -%> - - Version <%= info.finishedBoxUpdates[i].boxUpdateInfo.version %> -<% for (var j = 0; j < info.finishedBoxUpdates[i].boxUpdateInfo.changelog.length; j++) { -%> - * <%= info.finishedBoxUpdates[i].boxUpdateInfo.changelog[j] %> -<% }}} -%> -<% if (info.finishedAppUpdates.length) { -%> - -The following apps were updated: -<% for (var i = 0; i < info.finishedAppUpdates.length; i++) { -%> - - <%= info.finishedAppUpdates[i].toManifest.title %> package v<%= info.finishedAppUpdates[i].toManifest.version %> -<% 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].backupId || info.finishedBackups[0].filename %> -<% } else { -%> - -This Cloudron did **not** backup successfully in the last week! -<%= webadminUrl %>/#/backups -<% } -%> - -Powered by https://cloudron.io - -Sent at: <%= new Date().toUTCString() %> - -<% } else { %> - -
-
-
- -
- -
- -

This is a summary of the activities on your Cloudron <%= cloudronName %> last week.

- - <% 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.pendingAppUpdates.length) { %> -

Available app updates:

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

Your Cloudron was updated with the following releases:

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

The following apps were updated:

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

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

- <% } else { %> -

- The Cloudron did not backup successfully in the last week! -
-
- - - -

- <% } %> - -
-
-
- -
- - Powered by Cloudron
- Sent on <%= new Date().toUTCString() %> -
-
-
-
- -<% } %> diff --git a/src/mailer.js b/src/mailer.js index 7150b9b0c..1abb8b64e 100644 --- a/src/mailer.js +++ b/src/mailer.js @@ -6,7 +6,6 @@ exports = module.exports = { adminChanged: adminChanged, passwordReset: passwordReset, appUpdatesAvailable: appUpdatesAvailable, - sendDigest: sendDigest, sendInvite: sendInvite, @@ -358,39 +357,6 @@ function appUpdatesAvailable(mailTo, apps, hasSubscription, callback) { }); } -function sendDigest(mailTo, info, callback) { - assert.strictEqual(typeof mailTo, 'string'); - assert.strictEqual(typeof info, 'object'); - assert.strictEqual(typeof callback, 'function'); - - getMailConfig(function (error, mailConfig) { - if (error) return debug('Error getting mail details:', error); - - var templateData = { - webadminUrl: config.adminOrigin(), - cloudronName: mailConfig.cloudronName, - cloudronAvatarUrl: config.adminOrigin() + '/api/v1/cloudron/avatar', - info: info - }; - - var templateDataText = JSON.parse(JSON.stringify(templateData)); - templateDataText.format = 'text'; - - var templateDataHTML = JSON.parse(JSON.stringify(templateData)); - templateDataHTML.format = 'html'; - - var mailOptions = { - from: mailConfig.notificationFrom, - to: mailTo, - subject: util.format('[%s] Weekly activity digest', mailConfig.cloudronName), - text: render('digest.ejs', templateDataText), - html: render('digest.ejs', templateDataHTML) - }; - - sendMail(mailOptions, callback); - }); -} - function backupFailed(mailTo, errorMessage, logUrl) { assert.strictEqual(typeof mailTo, 'string'); diff --git a/src/routes/sysadmin.js b/src/routes/sysadmin.js index 57fde4b28..c400ed020 100644 --- a/src/routes/sysadmin.js +++ b/src/routes/sysadmin.js @@ -5,8 +5,6 @@ exports = module.exports = { update: update, retire: retire, - testDigest: testDigest, - importAppDatabase: importAppDatabase }; @@ -17,7 +15,6 @@ var apps = require('../apps.js'), backups = require('../backups.js'), BackupsError = require('../backups.js').BackupsError, cloudron = require('../cloudron.js'), - digest = require('../digest.js'), debug = require('debug')('box:routes/sysadmin'), HttpError = require('connect-lastmile').HttpError, HttpSuccess = require('connect-lastmile').HttpSuccess, @@ -72,13 +69,3 @@ function importAppDatabase(req, res, next) { }); }); } - -function testDigest(req, res, next) { - debug('test digest'); - - digest.send(function (error) { - if (error) return next(new HttpError(500, error)); - - next(new HttpSuccess(202, {})); - }); -} diff --git a/src/server.js b/src/server.js index 22fc732c7..de813b767 100644 --- a/src/server.js +++ b/src/server.js @@ -355,9 +355,6 @@ function initializeSysadminExpressSync() { router.post('/api/v1/retire', routes.sysadmin.retire); router.post('/api/v1/apps/:id/import', routes.sysadmin.importAppDatabase); - // routes to test features otherwise hard to test - router.post('/api/v1/test/digest', routes.sysadmin.testDigest); - return httpServer; } diff --git a/src/settings.js b/src/settings.js index 3ea8782e5..20dea7c41 100644 --- a/src/settings.js +++ b/src/settings.js @@ -29,9 +29,6 @@ exports = module.exports = { getCaasConfig: getCaasConfig, - getEmailDigest: getEmailDigest, - setEmailDigest: setEmailDigest, - getPlatformConfig: getPlatformConfig, setPlatformConfig: setPlatformConfig, @@ -49,7 +46,6 @@ exports = module.exports = { // booleans. if you add an entry here, be sure to fix getAll DYNAMIC_DNS_KEY: 'dynamic_dns', - EMAIL_DIGEST: 'email_digest', UNSTABLE_APPS_KEY: 'unstable_apps', // json. if you add an entry here, be sure to fix getAll @@ -105,7 +101,6 @@ var gDefaults = (function () { intervalSecs: 24 * 60 * 60 // ~1 day }; result[exports.CAAS_CONFIG_KEY] = {}; - result[exports.EMAIL_DIGEST] = true; result[exports.PLATFORM_CONFIG_KEY] = {}; return result; @@ -366,30 +361,6 @@ function setBackupConfig(backupConfig, callback) { }); } -function getEmailDigest(callback) { - assert.strictEqual(typeof callback, 'function'); - - settingsdb.get(exports.EMAIL_DIGEST, function (error, enabled) { - if (error && error.reason === DatabaseError.NOT_FOUND) return callback(null, gDefaults[exports.EMAIL_DIGEST]); - if (error) return callback(new SettingsError(SettingsError.INTERNAL_ERROR, error)); - - callback(null, !!enabled); // settingsdb holds string values only - }); -} - -function setEmailDigest(enabled, callback) { - assert.strictEqual(typeof enabled, 'boolean'); - assert.strictEqual(typeof callback, 'function'); - - settingsdb.set(exports.EMAIL_DIGEST, enabled ? 'enabled' : '', function (error) { - if (error) return callback(new SettingsError(SettingsError.INTERNAL_ERROR, error)); - - notifyChange(exports.EMAIL_DIGEST, enabled); - - callback(null); - }); -} - function getCaasConfig(callback) { assert.strictEqual(typeof callback, 'function'); diff --git a/src/test/digest-test.js b/src/test/digest-test.js deleted file mode 100644 index 3a8bc3e27..000000000 --- a/src/test/digest-test.js +++ /dev/null @@ -1,153 +0,0 @@ -/* global it:false */ -/* global describe:false */ -/* global before:false */ -/* global after:false */ - -'use strict'; - -var async = require('async'), - config = require('../config.js'), - database = require('../database.js'), - digest = require('../digest.js'), - eventlog = require('../eventlog.js'), - expect = require('expect.js'), - maildb = require('../maildb.js'), - mailer = require('../mailer.js'), - mail = require('../mail.js'), - domains = require('../domains.js'), - paths = require('../paths.js'), - safe = require('safetydance'), - settings = require('../settings.js'), - updatechecker = require('../updatechecker.js'), - userdb = require('../userdb.js'), - users = require('../users.js'); - -// owner -var USER_0 = { - username: 'username0', - password: 'Username0pass?1234', - email: 'user0@email.com', - fallbackEmail: 'user0fallback@email.com', - displayName: 'User 0' -}; - -const DOMAIN_0 = { - domain: 'example.com', - zoneName: 'example.com', - config: {}, - provider: 'manual', - fallbackCertificate: null, - tlsConfig: { provider: 'fallback' } -}; - -var AUDIT_SOURCE = { - ip: '1.2.3.4' -}; - -function checkMails(number, email, done) { - // mails are enqueued async - setTimeout(function () { - expect(mailer._mailQueue.length).to.equal(number); - - if (number) { - expect(mailer._mailQueue[0].to).to.equal(email); - } - - mailer._mailQueue = []; - done(); - }, 500); -} - -describe('digest', function () { - before(function (done) { - config._reset(); - config.set('fqdn', 'domain.com'); - config.set('apiServerOrigin', 'http://localhost:4444'); - config.set('provider', 'notcaas'); - config.setFqdn(DOMAIN_0.domain); - safe.fs.unlinkSync(paths.UPDATE_CHECKER_FILE); - - mailer._mailQueue = []; - - async.series([ - database.initialize, - database._clear, - domains.add.bind(null, DOMAIN_0.domain, DOMAIN_0, AUDIT_SOURCE), - mail.addDomain.bind(null, DOMAIN_0.domain), - users.createOwner.bind(null, USER_0.username, USER_0.password, USER_0.email, USER_0.displayName, AUDIT_SOURCE), - function (callback) { - userdb.getByUsername(USER_0.username, function (error, result) { - if (error) return callback(error); - - USER_0.id = result.id; - - users.update(USER_0.id, { fallbackEmail: USER_0.fallbackEmail }, AUDIT_SOURCE, callback); - }); - }, - eventlog.add.bind(null, eventlog.ACTION_UPDATE, AUDIT_SOURCE, { taskId: 12, boxUpdateInfo: { sourceTarballUrl: 'xx', version: '1.2.3', changelog: [ 'good stuff' ] } }), - maildb.update.bind(null, DOMAIN_0.domain, { enabled: true }), - ], done); - }); - - after(function (done) { - mailer._mailQueue = []; - safe.fs.unlinkSync(paths.UPDATE_CHECKER_FILE); - - async.series([ - database._clear, - database.uninitialize - ], done); - }); - - describe('disabled', function () { - before(function (done) { - settings.setEmailDigest(false, done); - }); - - it('does not send mail with digest disabled', function (done) { - digest.send(function (error) { - if (error) return done(error); - checkMails(0, null, done); - }); - }); - - }); - - describe('enabled', function () { - before(function (done) { - settings.setEmailDigest(true, done); - }); - - it('sends mail for box update', function (done) { - digest.send(function (error) { - if (error) return done(error); - - checkMails(1, `${USER_0.email}`, done); - }); - }); - - it('sends mail for pending update', function (done) { - updatechecker._setUpdateInfo({ box: null, apps: { 'appid': { manifest: { version: '1.2.5', changelog: 'noop\nreally' } } } }); - - digest.send(function (error) { - if (error) return done(error); - - checkMails(1, `${USER_0.email}`, done); - }); - }); - - it('sends mail for pending update to owner account email', function (done) { - updatechecker._setUpdateInfo({ box: null, apps: { 'appid': { manifest: { version: '1.2.5', changelog: 'noop\nreally' } } } }); - - maildb.update(DOMAIN_0.domain, { enabled: true }, function (error) { - if (error) return done(error); - - digest.send(function (error) { - if (error) return done(error); - - checkMails(1, `${USER_0.email}`, done); - }); - }); - }); - }); -}); diff --git a/src/test/settings-test.js b/src/test/settings-test.js index f6714c102..243da2c08 100644 --- a/src/test/settings-test.js +++ b/src/test/settings-test.js @@ -117,21 +117,6 @@ describe('Settings', function () { }); }); - it('can enable mail digest', function (done) { - settings.setEmailDigest(true, function (error) { - expect(error).to.be(null); - done(); - }); - }); - - it('can get mail digest', function (done) { - settings.getEmailDigest(function (error, enabled) { - expect(error).to.be(null); - expect(enabled).to.be(true); - done(); - }); - }); - it('can get default unstable apps setting', function (done) { settings.getUnstableAppsConfig(function (error, enabled) { expect(error).to.be(null);