diff --git a/src/mailer.js b/src/mailer.js index eb99e6dd7..c8d2b0f05 100644 --- a/src/mailer.js +++ b/src/mailer.js @@ -171,6 +171,7 @@ function getAdminEmails(callback) { if (admins.length === 0) return callback(new Error('No admins on this cloudron')); // box not activated yet var adminEmails = [ ]; + if (admins[0].alternateEmail) adminEmails.push(admins[0].alternateEmail); admins.forEach(function (admin) { adminEmails.push(admin.email); }); callback(null, adminEmails); @@ -428,34 +429,29 @@ function sendDigest(info) { cloudronName = 'Cloudron'; } - appstore.getAccount(function (error, appstoreProfile) { - if (error && error.reason !== AppstoreError.BILLING_REQUIRED) console.error(error); - if (appstoreProfile) adminEmails.push(appstoreProfile.email); + var templateData = { + fqdn: config.fqdn(), + webadminUrl: config.adminOrigin(), + cloudronName: cloudronName, + cloudronAvatarUrl: config.adminOrigin() + '/api/v1/cloudron/avatar', + info: info + }; - var templateData = { - fqdn: config.fqdn(), - webadminUrl: config.adminOrigin(), - cloudronName: cloudronName, - cloudronAvatarUrl: config.adminOrigin() + '/api/v1/cloudron/avatar', - info: info - }; + var templateDataText = JSON.parse(JSON.stringify(templateData)); + templateDataText.format = 'text'; - var templateDataText = JSON.parse(JSON.stringify(templateData)); - templateDataText.format = 'text'; + var templateDataHTML = JSON.parse(JSON.stringify(templateData)); + templateDataHTML.format = 'html'; - var templateDataHTML = JSON.parse(JSON.stringify(templateData)); - templateDataHTML.format = 'html'; + var mailOptions = { + from: mailConfig().from, + to: adminEmails.join(', '), + subject: util.format('[%s] Cloudron - Weekly activity digest', config.fqdn()), + text: render('digest.ejs', templateDataText), + html: render('digest.ejs', templateDataHTML) + }; - var mailOptions = { - from: mailConfig().from, - to: adminEmails.join(', '), - subject: util.format('[%s] Cloudron - Weekly activity digest', config.fqdn()), - text: render('digest.ejs', templateDataText), - html: render('digest.ejs', templateDataHTML) - }; - - enqueue(mailOptions); - }); + enqueue(mailOptions); }); }); } diff --git a/src/test/digest-test.js b/src/test/digest-test.js index 2eef10180..07e627b08 100644 --- a/src/test/digest-test.js +++ b/src/test/digest-test.js @@ -16,6 +16,7 @@ var async = require('async'), paths = require('../paths.js'), safe = require('safetydance'), settings = require('../settings.js'), + settingsdb = require('../settingsdb.js'), updatechecker = require('../updatechecker.js'), user = require('../user.js'); @@ -113,7 +114,7 @@ describe('digest', function () { }); }); - it('sends mail for pending update to appstore account email (caas)', function (done) { + it('sends mail for pending update to owner account email', function (done) { var subscription = { id: 'caas', created: 0, @@ -123,23 +124,16 @@ describe('digest', function () { }; updatechecker._setUpdateInfo({ box: null, apps: { 'appid': { manifest: { version: '1.2.5', changelog: 'noop\nreally' } } } }); - var fake1 = nock(config.apiServerOrigin()).post(function (uri) { return uri.indexOf('/api/v1/users/test-user/cloudrons') >= 0; }).reply(201, { cloudron: { id: 'test-cloudron' }}); - var fake2 = nock(config.apiServerOrigin()).get(function (uri) { return uri.indexOf('/api/v1/users/test-user/cloudrons/test-cloudron/subscription') >= 0; }).reply(200, { subscription: subscription }); - var fake3 = nock(config.apiServerOrigin()).get('/api/v1/users/test-user?accessToken=test-token').reply(200, { profile: { id: 'test-user', email: 'test@email.com' } }); - settings.setAppstoreConfig({ userId: 'test-user', token: 'test-token', cloudronId: 'test-cloudron' }, function (error) { + settingsdb.set(settings.MAIL_CONFIG_KEY, JSON.stringify({ enabled: true }), function (error) { if (error) return done(error); digest.maybeSend(function (error) { if (error) return done(error); - checkMails(1, 'test@email.com', function (error) { + checkMails(1, [ 'user0@email.com, username0@localhost' ], function (error) { if (error) return done(error); - expect(fake1.isDone()).to.be.ok(); - expect(fake2.isDone()).to.be.ok(); - expect(fake3.isDone()).to.be.ok(); - done(); }); }); diff --git a/src/userdb.js b/src/userdb.js index 99dee6aad..7e0ad714e 100644 --- a/src/userdb.js +++ b/src/userdb.js @@ -71,14 +71,14 @@ function getByEmail(email, callback) { function getOwner(callback) { assert.strictEqual(typeof callback, 'function'); - // the first created user it the admin + // the first created user it the 'owner' database.query('SELECT ' + USERS_FIELDS + ' FROM users, groupMembers WHERE groupMembers.groupId = ? AND users.id = groupMembers.userId ORDER BY createdAt LIMIT 1', - [ constants.ADMIN_GROUP_ID ], function (error, result) { - if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error)); - if (result.length === 0) return callback(new DatabaseError(DatabaseError.NOT_FOUND)); + [ constants.ADMIN_GROUP_ID ], function (error, result) { + if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error)); + if (result.length === 0) return callback(new DatabaseError(DatabaseError.NOT_FOUND)); - callback(null, postProcess(result[0])); - }); + callback(null, postProcess(result[0])); + }); } function getByResetToken(resetToken, callback) { @@ -116,7 +116,8 @@ function getAllWithGroupIds(callback) { function getAllAdmins(callback) { assert.strictEqual(typeof callback, 'function'); - database.query('SELECT ' + USERS_FIELDS + ' FROM users, groupMembers WHERE groupMembers.groupId = ? AND users.id = groupMembers.userId ORDER BY username', [ constants.ADMIN_GROUP_ID ], function (error, results) { + // the mailer code relies on the first object being the 'owner' (thus the ORDER) + database.query('SELECT ' + USERS_FIELDS + ' FROM users, groupMembers WHERE groupMembers.groupId = ? AND users.id = groupMembers.userId ORDER BY createdAt', [ constants.ADMIN_GROUP_ID ], function (error, results) { if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error)); results.forEach(postProcess);