Skip to content

Commit

Permalink
[NEW] Alert for new versions
Browse files Browse the repository at this point in the history
  • Loading branch information
rodrigok committed Feb 21, 2018
1 parent e92e59b commit b81b366
Show file tree
Hide file tree
Showing 16 changed files with 251 additions and 13 deletions.
1 change: 1 addition & 0 deletions .meteor/packages
Original file line number Diff line number Diff line change
Expand Up @@ -184,3 +184,4 @@ steffo:meteor-accounts-saml
todda00:friendly-slugs
yasaricli:slugify
yasinuslu:blaze-meta
rocketchat:version-check
1 change: 1 addition & 0 deletions .meteor/versions
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ rocketchat:ui-message@0.1.0
rocketchat:ui-sidenav@0.1.0
rocketchat:ui-vrecord@0.0.1
rocketchat:version@1.0.0
rocketchat:version-check@0.0.1
rocketchat:videobridge@0.2.0
rocketchat:webrtc@0.0.1
rocketchat:wordpress@0.0.1
Expand Down
3 changes: 3 additions & 0 deletions packages/rocketchat-i18n/i18n/en.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,7 @@
"Closing_chat": "Closing chat",
"Collapse_Embedded_Media_By_Default": "Collapse Embedded Media by Default",
"Color": "Color",
"Contains_Security_Fixes": "Contains Security Fixes",
"Commands": "Commands",
"Comment_to_leave_on_closing_session": "Comment to Leave on Closing Session",
"Common_Access": "Common Access",
Expand Down Expand Up @@ -1356,6 +1357,7 @@
"New_role": "New role",
"New_Room_Notification": "New Room Notification",
"New_Trigger": "New Trigger",
"New_version_available_(s)": "New version available (%s)",
"New_videocall_request": "New Video Call Request",
"No_available_agents_to_transfer": "No available agents to transfer",
"No_channel_with_name_%s_was_found": "No channel with name <strong>\"%s\"</strong> was found!",
Expand Down Expand Up @@ -1996,6 +1998,7 @@
"Unread_Tray_Icon_Alert": "Unread Tray Icon Alert",
"Unstar_Message": "Remove Star",
"Updated_at": "Updated at",
"Update_your_RocketChat": "Update your Rocket.Chat",
"Upload_user_avatar": "Upload avatar",
"Upload_file_description": "File description",
"Upload_file_name": "File name",
Expand Down
20 changes: 20 additions & 0 deletions packages/rocketchat-lib/server/models/Users.js
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,26 @@ class ModelUsers extends RocketChat.models._Base {
return this.update(_id, update);
}

addBannerById(_id, banner) {
const update = {
$set: {
[`banners.${ banner.id }`]: banner
}
};

return this.update({ _id }, update);
}

removeBannerById(_id, banner) {
const update = {
$unset: {
[`banners.${ banner.id }`]: true
}
};

return this.update({ _id }, update);
}

// INSERT
create(data) {
const user = {
Expand Down
18 changes: 9 additions & 9 deletions packages/rocketchat-ui-admin/client/admin.html
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@
<div class="setting-field">
{{#if $eq type 'string'}}
{{#if multiline}}
<textarea class="input-monitor rc-input__element" name="{{_id}}" rows="4" style="height: auto" {{isDisabled}}>{{value}}</textarea>
<textarea class="input-monitor rc-input__element" name="{{_id}}" rows="4" style="height: auto" {{isDisabled}} {{isReadonly}}>{{value}}</textarea>
{{else}}
<input class="input-monitor rc-input__element" type="text" name="{{_id}}" value="{{value}}" placeholder="{{placeholder}}" {{isDisabled}}/>
<input class="input-monitor rc-input__element" type="text" name="{{_id}}" value="{{value}}" placeholder="{{placeholder}}" {{isDisabled}} {{isReadonly}}/>
{{/if}}
{{/if}}

Expand All @@ -65,28 +65,28 @@
{{/if}}

{{#if $eq type 'password'}}
<input class="input-monitor rc-input__element" type="password" name="{{_id}}" value="{{value}}" placeholder="{{placeholder}}" {{isDisabled}}/>
<input class="input-monitor rc-input__element" type="password" name="{{_id}}" value="{{value}}" placeholder="{{placeholder}}" {{isDisabled}} {{isReadonly}}/>
{{/if}}

{{#if $eq type 'int'}}
<input class="input-monitor rc-input__element" type="number" name="{{_id}}" value="{{value}}" placeholder="{{placeholder}}" {{isDisabled}}/>
<input class="input-monitor rc-input__element" type="number" name="{{_id}}" value="{{value}}" placeholder="{{placeholder}}" {{isDisabled}} {{isReadonly}}/>
{{/if}}

{{#if $eq type 'boolean'}}
<label><input class="input-monitor" type="radio" name="{{_id}}" value="1" checked="{{$eq value true}}" {{isDisabled}}/> {{_ "True"}}</label>
<label><input class="input-monitor" type="radio" name="{{_id}}" value="0" checked="{{$eq value false}}" {{isDisabled}}/> {{_ "False"}}</label>
<label><input class="input-monitor" type="radio" name="{{_id}}" value="1" checked="{{$eq value true}}" {{isDisabled}} {{isReadonly}}/> {{_ "True"}}</label>
<label><input class="input-monitor" type="radio" name="{{_id}}" value="0" checked="{{$eq value false}}" {{isDisabled}} {{isReadonly}}/> {{_ "False"}}</label>
{{/if}}

{{#if $eq type 'select'}}
<select class="input-monitor rc-input__element" name="{{_id}}" {{isDisabled}}>
<select class="input-monitor rc-input__element" name="{{_id}}" {{isDisabled}} {{isReadonly}}>
{{#each values}}
<option value="{{key}}" selected="{{selectedOption ../_id key}}">{{_ i18nLabel}}</option>
{{/each}}
</select>
{{/if}}

{{#if $eq type 'language'}}
<select class="input-monitor rc-input__element" name="{{_id}}" {{isDisabled}}>
<select class="input-monitor rc-input__element" name="{{_id}}" {{isDisabled}} {{isReadonly}}>
{{#each languages}}
<option value="{{key}}" selected="{{appLanguage key}}" dir="auto">{{name}}</option>
{{/each}}
Expand Down Expand Up @@ -118,7 +118,7 @@
{{/if}}

{{#if $eq type 'font'}}
<input class="input-monitor rc-input__element" type="text" name="{{_id}}" value="{{value}}" {{isDisabled}}/>
<input class="input-monitor rc-input__element" type="text" name="{{_id}}" value="{{value}}" {{isDisabled}} {{isReadonly}}/>
{{/if}}

{{#if $eq type 'code'}}
Expand Down
7 changes: 4 additions & 3 deletions packages/rocketchat-ui/client/views/app/alerts.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
this.alerts = {
renderedAlert: null,
open(config) {
this.close();
this.close(false);

config.closable = typeof(config.closable) === typeof(true) ? config.closable : true;

Expand All @@ -12,7 +12,7 @@ this.alerts = {

this.renderedAlert = Blaze.renderWithData(Template.alerts, config, document.body, document.body.querySelector('#alert-anchor'));
},
close() {
close(dismiss = true) {
if (this.timer) {
clearTimeout(this.timer);
delete this.timer;
Expand All @@ -27,6 +27,8 @@ this.alerts = {
if (activeElement) {
$(activeElement).removeClass('active');
}

dismiss && this.renderedAlert.dataVar.curValue.onClose && this.renderedAlert.dataVar.curValue.onClose();
}
};

Expand All @@ -49,7 +51,6 @@ Template.alerts.onDestroyed(function() {
if (this.data.onDestroyed) {
this.data.onDestroyed();
}
this.data.onClose && this.data.onClose();
});

Template.alerts.events({
Expand Down
28 changes: 28 additions & 0 deletions packages/rocketchat-version-check/client/client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* globals alerts */

Meteor.startup(function() {
Tracker.autorun(() => {
const user = Meteor.user();

if (user && Object.keys(user.banners || {}).length > 0) {
const firstBanner = Object.values(user.banners).sort((a, b) => b.priority - a.priority)[0];
firstBanner.textArguments = firstBanner.textArguments || [];

alerts.open({
title: TAPi18n.__(firstBanner.title),
text: TAPi18n.__(firstBanner.text, ...firstBanner.textArguments),
modifiers: firstBanner.modifiers,
action() {
if (firstBanner.link) {
window.open(firstBanner.link, '_system');
}
},
onClose() {
Meteor.call('banner/dismiss', {
id: firstBanner.id
});
}
});
}
});
});
19 changes: 19 additions & 0 deletions packages/rocketchat-version-check/package.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Package.describe({
name: 'rocketchat:version-check',
version: '0.0.1',
summary: 'Check for new avaiable versions',
git: ''
});

Package.onUse(function(api) {
api.use([
'mongo',
'ecmascript',
'rocketchat:lib',
'rocketchat:logger',
'percolate:synced-cron'
]);

api.mainModule('client/client.js', 'client');
api.mainModule('server/server.js', 'server');
});
8 changes: 8 additions & 0 deletions packages/rocketchat-version-check/server/addSettings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
RocketChat.settings.addGroup('General', function() {
this.section('Update', function() {
this.add('Update_LatestAvailableVersion', '0.0.0', {
type: 'string',
readonly: true
});
});
});
14 changes: 14 additions & 0 deletions packages/rocketchat-version-check/server/checkUpdate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export default {
versions: [{
version: '0.61.2',
security: true,
infoUrl: 'https://rocket.chat'
}],
alerts: [{
timestamp: '2018-02-19T22:56:23.290Z',
title: 'Alert title',
description: 'Alert description',
infoUrl: 'https://rocket.chat',
infoTitle: 'More information'
}]
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import semver from 'semver';
import getNewUpdates from './getNewUpdates';
import logger from '../logger';

export default () => {
logger.info('Checking for version updates');

const { versions } = getNewUpdates();

const update = {
exists: false,
lastestVersion: null,
security: false
};

const lastCheckedVersion = RocketChat.settings.get('Update_LatestAvailableVersion');
versions.forEach(version => {
if (semver.lte(version.version, lastCheckedVersion)) {
return;
}

if (semver.lte(version.version, RocketChat.Info.version)) {
return;
}

update.exists = true;
update.lastestVersion = version;

if (version.security === true) {
update.security = true;
}
});

if (update.exists) {
RocketChat.settings.updateById('Update_LatestAvailableVersion', update.lastestVersion.version);
RocketChat.models.Roles.findUsersInRole('admin').forEach(adminUser => {
const msg = {
msg: `*${ TAPi18n.__('Update_your_RocketChat', adminUser.language) }*\n${ TAPi18n.__('New_version_available_(s)', update.lastestVersion.version, adminUser.language) }\n${ update.lastestVersion.infoUrl }`,
rid: [adminUser._id, 'rocket.cat'].sort().join('')
};

Meteor.runAsUser('rocket.cat', () => Meteor.call('sendMessage', msg));

RocketChat.models.Users.addBannerById(adminUser._id, {
id: 'versionUpdate',
priority: 10,
title: 'Update_your_RocketChat',
text: 'New_version_available_(s)',
textArguments: [update.lastestVersion.version],
link: update.lastestVersion.infoUrl
});
});
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/* global MongoInternals */
import os from 'os';
import { HTTP } from 'meteor/http';
import logger from '../logger';
// import checkUpdate from '../checkUpdate';

export default () => {
try {
const uniqueID = RocketChat.models.Settings.findOne('uniqueID');
const _oplogHandle = MongoInternals.defaultRemoteCollectionDriver().mongo._oplogHandle;
const oplogEnabled = _oplogHandle && _oplogHandle.onOplogEntry && RocketChat.settings.get('Force_Disable_OpLog_For_Cache') !== true;

const data = {
uniqueId: uniqueID.value,
installedAt: uniqueID.createdAt,
version: RocketChat.Info.version,
oplogEnabled,
osType: os.type(),
osPlatform: os.platform(),
osArch: os.arch(),
osRelease: os.release(),
nodeVersion: process.version,
deployMethod: process.env.DEPLOY_METHOD || 'tar',
deployPlatform: process.env.DEPLOY_PLATFORM || 'selfinstall'
};

const result = HTTP.get('https://releases.rocket.chat/updates/check', {
params: data
});

// const result = {
// data: {
// ...checkUpdate
// }
// };

return result.data;
} catch (error) {
// console.log(error);
logger.error('Failed to get version updates', error);

return {
versions: [],
alerts: []
};
}
};
1 change: 1 addition & 0 deletions packages/rocketchat-version-check/server/logger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default new Logger('VersionCheck');
11 changes: 11 additions & 0 deletions packages/rocketchat-version-check/server/methods/banner_dismiss.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Meteor.methods({
'banner/dismiss'({ id }) {
if (!Meteor.userId()) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'banner/dismiss' });
}

RocketChat.models.Users.removeBannerById(this.userId, {
id
});
}
});
29 changes: 29 additions & 0 deletions packages/rocketchat-version-check/server/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/* globals SyncedCron */

import checkVersionUpdate from './functions/checkVersionUpdate';
import './methods/banner_dismiss';
import './addSettings';

const jobName = 'version_check';

if (SyncedCron.nextScheduledAtDate(jobName)) {
SyncedCron.remove(jobName);
}

SyncedCron.add({
name: jobName,
schedule: parser => parser.text('at 2:00 am'),
job() {
checkVersionUpdate();
}
});

SyncedCron.start();

Meteor.startup(() => {
checkVersionUpdate();
});

// Send email to admins
// Save latest alert
// ENV var to disable the check for update for our cloud
3 changes: 2 additions & 1 deletion server/publications/userData.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ Meteor.publish('userData', function() {
requirePasswordChangeReason: 1,
'services.password.bcrypt': 1,
'services.totp.enabled': 1,
statusLivechat: 1
statusLivechat: 1,
banners: 1
}
});
});

0 comments on commit b81b366

Please sign in to comment.