Compare commits

...

4 Commits

Author SHA1 Message Date
Johannes Zellner
50c344033c Add 0.160.1 changes 2017-07-22 11:12:51 +02:00
Girish Ramakrishnan
0c269925c2 Add the dialog text to the email 2017-07-21 12:40:04 -07:00
Johannes Zellner
dcd84a9636 send lastLogin event timestamp with alive status 2017-07-19 23:05:14 +02:00
Johannes Zellner
fa7273025b Send update notification every 4 days regardless of update pattern 2017-07-18 14:50:53 +02:00
4 changed files with 80 additions and 64 deletions

View File

@@ -885,3 +885,5 @@
* Prevent email view from flickering
* Prepare for 1.0
[0.160.1]
* Improved update notification

View File

@@ -15,6 +15,7 @@ exports = module.exports = {
var assert = require('assert'),
config = require('./config.js'),
debug = require('debug')('box:appstore'),
eventlog = require('./eventlog.js'),
os = require('os'),
settings = require('./settings.js'),
superagent = require('superagent'),
@@ -127,45 +128,52 @@ function sendAliveStatus(data, callback) {
settings.getAll(function (error, result) {
if (error) return callback(new AppstoreError(AppstoreError.INTERNAL_ERROR, error));
var backendSettings = {
dnsConfig: {
provider: result[settings.DNS_CONFIG_KEY].provider,
wildcard: result[settings.DNS_CONFIG_KEY].provider === 'manual' ? result[settings.DNS_CONFIG_KEY].wildcard : undefined
},
tlsConfig: {
provider: result[settings.TLS_CONFIG_KEY].provider
},
backupConfig: {
provider: result[settings.BACKUP_CONFIG_KEY].provider
},
mailConfig: {
enabled: result[settings.MAIL_CONFIG_KEY].enabled
},
autoupdatePattern: result[settings.AUTOUPDATE_PATTERN_KEY],
timeZone: result[settings.TIME_ZONE_KEY]
};
eventlog.getAllPaged(eventlog.ACTION_USER_LOGIN, null, 1, 1, function (error, loginEvents) {
if (error) return callback(new AppstoreError(AppstoreError.INTERNAL_ERROR, error));
var data = {
domain: config.fqdn(),
version: config.version(),
provider: config.provider(),
backendSettings: backendSettings,
machine: {
cpus: os.cpus(),
totalmem: os.totalmem()
}
};
var backendSettings = {
dnsConfig: {
provider: result[settings.DNS_CONFIG_KEY].provider,
wildcard: result[settings.DNS_CONFIG_KEY].provider === 'manual' ? result[settings.DNS_CONFIG_KEY].wildcard : undefined
},
tlsConfig: {
provider: result[settings.TLS_CONFIG_KEY].provider
},
backupConfig: {
provider: result[settings.BACKUP_CONFIG_KEY].provider
},
mailConfig: {
enabled: result[settings.MAIL_CONFIG_KEY].enabled
},
autoupdatePattern: result[settings.AUTOUPDATE_PATTERN_KEY],
timeZone: result[settings.TIME_ZONE_KEY],
};
getAppstoreConfig(function (error, appstoreConfig) {
if (error) return callback(error);
var data = {
domain: config.fqdn(),
version: config.version(),
provider: config.provider(),
backendSettings: backendSettings,
machine: {
cpus: os.cpus(),
totalmem: os.totalmem()
},
events: {
lastLogin: loginEvents[0] ? (new Date(loginEvents[0].creationTime).getTime()) : 0
}
};
var url = config.apiServerOrigin() + '/api/v1/users/' + appstoreConfig.userId + '/cloudrons/' + appstoreConfig.cloudronId + '/alive';
superagent.post(url).send(data).query({ accessToken: appstoreConfig.token }).timeout(30 * 1000).end(function (error, result) {
if (error && !error.response) return callback(new AppstoreError(AppstoreError.EXTERNAL_ERROR, error));
if (result.statusCode === 404) return callback(new AppstoreError(AppstoreError.NOT_FOUND));
if (result.statusCode !== 201) return callback(new AppstoreError(AppstoreError.EXTERNAL_ERROR, util.format('Sending alive status failed. %s %j', result.status, result.body)));
getAppstoreConfig(function (error, appstoreConfig) {
if (error) return callback(error);
callback(null);
var url = config.apiServerOrigin() + '/api/v1/users/' + appstoreConfig.userId + '/cloudrons/' + appstoreConfig.cloudronId + '/alive';
superagent.post(url).send(data).query({ accessToken: appstoreConfig.token }).timeout(30 * 1000).end(function (error, result) {
if (error && !error.response) return callback(new AppstoreError(AppstoreError.EXTERNAL_ERROR, error));
if (result.statusCode === 404) return callback(new AppstoreError(AppstoreError.NOT_FOUND));
if (result.statusCode !== 201) return callback(new AppstoreError(AppstoreError.EXTERNAL_ERROR, util.format('Sending alive status failed. %s %j', result.status, result.body)));
callback(null);
});
});
});
});

View File

@@ -2,17 +2,21 @@
Dear <%= cloudronName %> Admin,
Version <%= newBoxVersion %> for Cloudron <%= fqdn %> is now available!
Cloudron Version <%= newBoxVersion %> is now available!
Your Cloudron will update automatically tonight. Alternately, update immediately at <%= webadminUrl %>.
Your Cloudron will update to 1.0 once you have selected a plan (https://cloudron.io/pricing.html).
Changelog:
<% for (var i = 0; i < changelog.length; i++) { %>
* <%- changelog[i] %>
<% } %>
With a paid plan, you get continuous updates for the Cloudron and apps just like you had until now.
This ensures you are running the latest versions of apps and keeps your server secure. All paid
plans come with support via email (support@cloudron.io) and live chat (https://chat.cloudron.io).
You can read more about our pricing changes in our blog at https://cloudron.io/blog/2017-06-06-pricing.html.
Visit our pricing page https://cloudron.io/pricing.html for pricing information.
Visit your Cloudron at <%= webadminUrl %> to perform the update.
Thank you,
your Cloudron
Cloudron.io team
<% } else { %>
@@ -24,20 +28,22 @@ your Cloudron
<div style="width: 650px; text-align: left;">
<p>
Version <b><%= newBoxVersion %></b> for Cloudron <%= fqdn %> is now available!
Cloudron Version <b><%= newBoxVersion %></b> is now available!
</p>
<p>
Your Cloudron will update automatically tonight.<br/>
Alternately, update immediately <a href="<%= webadminUrl %>">here</a>.
Your Cloudron will update to 1.0 once you have selected a <a href="https://cloudron.io/pricing.html">plan</a>.
</p>
<p>
With a paid plan, you get continuous updates for the Cloudron and apps just like you had until now. This ensures you are running the latest versions of apps and keeps your server secure. All paid plans come with support via <a href="mailto:support@cloudron.io">email</a> and <a target="_blank" href="https://chat.cloudron.io">live chat</a>.
</p>
<p>
You can read more about our pricing changes in our <a href="https://cloudron.io/blog/2017-06-06-pricing.html" target="_blank">blog</a>.
</p>
<h5>Changelog:</h5>
<ul>
<% for (var i = 0; i < changelogHTML.length; i++) { %>
<li><%- changelogHTML[i] %></li>
<% } %>
</ul>
<p>
Visit your Cloudron <a href="<%= webadminUrl %>">here</a> to perform the update.
</p>
<br/>
<br/>
@@ -52,4 +58,3 @@ your Cloudron
<img src="https://analytics.cloudron.io/piwik.php?idsite=2&rec=1&e_c=CloudronEmail&e_a=update" style="border:0" alt="" />
<% } %>

View File

@@ -12,7 +12,6 @@ exports = module.exports = {
var apps = require('./apps.js'),
appstore = require('./appstore.js'),
async = require('async'),
config = require('./config.js'),
constants = require('./constants.js'),
debug = require('debug')('box:updatechecker'),
mailer = require('./mailer.js'),
@@ -28,7 +27,7 @@ var NOOP_CALLBACK = function (error) { if (error) debug(error); };
function loadState() {
var state = safe.JSON.parse(safe.fs.readFileSync(paths.UPDATE_CHECKER_FILE, 'utf8'));
return state || { };
return state || {};
}
function saveState(mailedUser) {
@@ -111,7 +110,10 @@ function checkAppUpdates(callback) {
iteratorDone();
});
}, function () {
newState.box = loadState().box; // preserve the latest box state information
// preserve the latest box state information
newState.box = loadState().box;
newState.boxTimestamp = loadState().boxTimestamp;
saveState(newState);
callback();
});
@@ -143,22 +145,21 @@ function checkBoxUpdates(callback) {
// decide whether to send email
var state = loadState();
if (state.box === gBoxUpdateInfo.version) {
debug('Skipping notification of box update as user was already notified');
const NOTIFICATION_OFFSET = 1000 * 60 * 60 * 24 * 5; // 5 days
if (state.box === gBoxUpdateInfo.version && state.boxTimestamp > Date.now() - NOTIFICATION_OFFSET) {
debug('Skipping notification of box update as user was already notified within the last 5 days');
return callback();
}
state.boxTimestamp = Date.now();
state.box = updateInfo.version;
mailer.boxUpdateAvailable(updateInfo.version, updateInfo.changelog);
saveState(state);
// only send notifications if update pattern is 'never'
settings.getAutoupdatePattern(function (error, result) {
if (error) debug(error);
else if (result === constants.AUTOUPDATE_PATTERN_NEVER) mailer.boxUpdateAvailable(updateInfo.version, updateInfo.changelog);
callback();
});
callback();
});
});
}