diff --git a/packages/rocketchat-api/server/api.js b/packages/rocketchat-api/server/api.js
index c7816e0afad..d53bd9b6e63 100644
--- a/packages/rocketchat-api/server/api.js
+++ b/packages/rocketchat-api/server/api.js
@@ -66,6 +66,15 @@ class API extends Restivus {
};
}
+ notFound(msg) {
+ return {
+ statusCode: 404,
+ body: {
+ success: false,
+ error: msg ? msg : 'Resource not found'
+ }
+ };
+ }
unauthorized(msg) {
return {
diff --git a/packages/rocketchat-google-vision/.npm/package/npm-shrinkwrap.json b/packages/rocketchat-google-vision/.npm/package/npm-shrinkwrap.json
index 788d7c87977..00561635dcd 100644
--- a/packages/rocketchat-google-vision/.npm/package/npm-shrinkwrap.json
+++ b/packages/rocketchat-google-vision/.npm/package/npm-shrinkwrap.json
@@ -1085,13 +1085,13 @@
"from": "mime@>=1.2.11 <2.0.0"
},
"mime-db": {
- "version": "1.29.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.29.0.tgz",
- "from": "mime-db@>=1.29.0 <1.30.0"
+ "version": "1.30.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
+ "from": "mime-db@>=1.30.0 <1.31.0"
},
"mime-types": {
- "version": "2.1.16",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.16.tgz",
+ "version": "2.1.17",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
"from": "mime-types@>=2.0.8 <3.0.0"
},
"minimatch": {
diff --git a/packages/rocketchat-lib/client/lib/startup/commands.js b/packages/rocketchat-lib/client/lib/startup/commands.js
index 01d97477c1f..91456a9eed6 100644
--- a/packages/rocketchat-lib/client/lib/startup/commands.js
+++ b/packages/rocketchat-lib/client/lib/startup/commands.js
@@ -1,11 +1,17 @@
-Meteor.startup(function _loadDynamicallyDefinedCommands() {
- // The reason there is a 500 millisecond delay is so that we are
- // a little "easier" on the server during start up
- setTimeout(() => {
- RocketChat.API.v1.get('commands.list').then(function _loadedCommands(result) {
- result.commands.forEach((command) => {
- RocketChat.slashCommands.commands[command.command] = command;
+//Track logins and when they login, get the commands
+(() => {
+ let oldUserId = null;
+
+ Meteor.autorun(() => {
+ const newUserId = Meteor.userId();
+ if (oldUserId === null && newUserId) {
+ RocketChat.API.v1.get('commands.list').then(function _loadedCommands(result) {
+ result.commands.forEach((command) => {
+ RocketChat.slashCommands.commands[command.command] = command;
+ });
});
- });
- }, 500);
-});
+ }
+
+ oldUserId = Meteor.userId();
+ });
+})();
diff --git a/packages/rocketchat-rocketlets/assets/stylesheets/rocketlets.css b/packages/rocketchat-rocketlets/assets/stylesheets/rocketlets.css
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/packages/rocketchat-rocketlets/client/admin/rocketlets.html b/packages/rocketchat-rocketlets/client/admin/rocketlets.html
index 62c73ba09a9..74fbb58e9f4 100644
--- a/packages/rocketchat-rocketlets/client/admin/rocketlets.html
+++ b/packages/rocketchat-rocketlets/client/admin/rocketlets.html
@@ -9,7 +9,11 @@
{{#requiresPermission 'manage-rocketlets'}}
-
Hello
+ {{#each rocketlets}}
+
+ {{/each}}
{{/requiresPermission}}
diff --git a/packages/rocketchat-rocketlets/client/admin/rocketlets.js b/packages/rocketchat-rocketlets/client/admin/rocketlets.js
index bf10e3895b2..a869c96ec1c 100644
--- a/packages/rocketchat-rocketlets/client/admin/rocketlets.js
+++ b/packages/rocketchat-rocketlets/client/admin/rocketlets.js
@@ -1,3 +1,22 @@
Template.rocketlets.onCreated(function() {
- console.log('hello');
+ const instance = this;
+ this.ready = new ReactiveVar(false);
+ this.rocketlets = new ReactiveVar([]);
+
+ RocketChat.API.get('rocketlets').then((result) => {
+ instance.rocketlets.set(result.rocketlets);
+ });
+});
+
+Template.rocketlets.helpers({
+ isReady() {
+ if (Template.instance().ready != null) {
+ return Template.instance().ready.get();
+ }
+
+ return false;
+ },
+ rocketlets() {
+ return Template.instance().rocketlets.get();
+ }
});
diff --git a/packages/rocketchat-rocketlets/client/communication/websockets.js b/packages/rocketchat-rocketlets/client/communication/websockets.js
index 5288636a3d0..b7aef6dc1df 100644
--- a/packages/rocketchat-rocketlets/client/communication/websockets.js
+++ b/packages/rocketchat-rocketlets/client/communication/websockets.js
@@ -3,12 +3,19 @@ export class RocketletWebsocketReceiver {
this.orch = orch;
this.streamer = new Meteor.Streamer('rocketlets');
+ this.streamer.on('rocketlet/added', this.onRocketletAdded.bind(this));
this.streamer.on('command/added', this.onCommandAdded.bind(this));
this.streamer.on('command/disabled', this.onCommandDisabled.bind(this));
this.streamer.on('command/updated', this.onCommandUpdated.bind(this));
this.streamer.on('command/removed', this.onCommandDisabled.bind(this));
}
+ onRocketletAdded(rocketletId) {
+ RocketChat.API.get(`rocketlets/${ rocketletId }`).then((result) => {
+ this.orch.parseAndLoadLanguages(result.rocketlet.languages);
+ });
+ }
+
onCommandAdded(command) {
RocketChat.API.v1.get('commands.getOne', { command }).then((result) => {
RocketChat.slashCommands.commands[command] = result.command;
diff --git a/packages/rocketchat-rocketlets/client/orchestrator.js b/packages/rocketchat-rocketlets/client/orchestrator.js
index 4bedcc9e56b..d2ff6dd0211 100644
--- a/packages/rocketchat-rocketlets/client/orchestrator.js
+++ b/packages/rocketchat-rocketlets/client/orchestrator.js
@@ -5,6 +5,7 @@ class RocketletClientOrchestrator {
this.ws = new RocketletWebsocketReceiver(this);
this._addAdminMenuOption();
+ setTimeout(() => this._loadLanguages(), 500);
}
getWsListener() {
@@ -20,6 +21,28 @@ class RocketletClientOrchestrator {
}
});
}
+
+ _loadLanguages() {
+ if (!Meteor.user()) {
+ return;
+ }
+
+ RocketChat.API.get('rocketlets?languagesOnly=true').then((info) => {
+ info.rocketlets.forEach((rlInfo) => this.parseAndLoadLanguages(rlInfo.languages));
+ });
+ }
+
+ parseAndLoadLanguages(languages) {
+ Object.keys(languages).forEach((key) => {
+ try {
+ const json = JSON.parse(languages[key]);
+
+ TAPi18next.addResourceBundle(key, 'project', json);
+ } catch (e) {
+ // Failed to parse the json
+ }
+ });
+ }
}
Meteor.startup(function _rlClientOrch() {
diff --git a/packages/rocketchat-rocketlets/package.js b/packages/rocketchat-rocketlets/package.js
index 0071297ed1a..5ea4ba27e3e 100644
--- a/packages/rocketchat-rocketlets/package.js
+++ b/packages/rocketchat-rocketlets/package.js
@@ -25,6 +25,7 @@ Package.onUse(function(api) {
// Bridges
api.addFiles([
+ 'server/bridges/activation.js',
'server/bridges/bridges.js',
'server/bridges/commands.js',
'server/bridges/environmental.js',
@@ -67,6 +68,8 @@ Package.onUse(function(api) {
'client/admin/rocketlets.js'
], 'client');
+ api.addFiles('assets/stylesheets/rocketlets.css', 'client');
+
// Client orchestrator
api.addFiles('client/orchestrator.js', 'client');
@@ -76,6 +79,6 @@ Package.onUse(function(api) {
Npm.depends({
'busboy': '0.2.13',
- 'temporary-rocketlets-server': '0.1.23',
- 'temporary-rocketlets-ts-definition': '0.6.25'
+ 'temporary-rocketlets-server': '0.1.26',
+ 'temporary-rocketlets-ts-definition': '0.6.26'
});
diff --git a/packages/rocketchat-rocketlets/server/bridges/activation.js b/packages/rocketchat-rocketlets/server/bridges/activation.js
new file mode 100644
index 00000000000..6833622fbec
--- /dev/null
+++ b/packages/rocketchat-rocketlets/server/bridges/activation.js
@@ -0,0 +1,35 @@
+export class RocketletActivationBridge {
+ constructor(orch) {
+ this.orch = orch;
+ }
+
+ rocketletEnabled(rocketlet) {
+ console.log(`The Rocketlet ${ rocketlet.getName() } (${ rocketlet.getID() }) has been enabled.`);
+ }
+
+ rocketletDisabled(rocketlet) {
+ console.log(`The Rocketlet ${ rocketlet.getName() } (${ rocketlet.getID() }) has been disabled.`);
+ }
+
+ rocketletLoaded(rocketlet, enabled) {
+ console.log(`The Rocketlet ${ rocketlet.getName() } (${ rocketlet.getID() }) has been loaded and enabled? ${ enabled }`);
+
+ if (enabled) {
+ this.orch.getNotifier().rocketletAdded(rocketlet.getID());
+ }
+ }
+
+ rocketletUpdated(rocketlet, enabled) {
+ console.log(`The Rocketlet ${ rocketlet.getName() } (${ rocketlet.getID() }) has been updated and enabled? ${ enabled }`);
+
+ if (enabled) {
+ this.orch.getNotifier().rocketletUpdated(rocketlet.getID());
+ }
+ }
+
+ rocketletRemoved(rocketlet) {
+ console.log(`The Rocketlet ${ rocketlet.getName() } (${ rocketlet.getID() }) has been removed.`);
+
+ this.orch.getNotifier().rocketletRemoved(rocketlet.getID());
+ }
+}
diff --git a/packages/rocketchat-rocketlets/server/bridges/bridges.js b/packages/rocketchat-rocketlets/server/bridges/bridges.js
index 07f5d182a9d..3afa40d44a9 100644
--- a/packages/rocketchat-rocketlets/server/bridges/bridges.js
+++ b/packages/rocketchat-rocketlets/server/bridges/bridges.js
@@ -1,4 +1,6 @@
import { RocketletBridges } from 'temporary-rocketlets-server/server/bridges';
+
+import { RocketletActivationBridge } from './activation';
import { RocketletCommandsBridge } from './commands';
import { RocketletEnvironmentalVariableBridge } from './environmental';
import { RocketletHttpBridge } from './http';
@@ -12,6 +14,7 @@ export class RealRocketletBridges extends RocketletBridges {
constructor(orch) {
super();
+ this._actBridge = new RocketletActivationBridge(orch);
this._cmdBridge = new RocketletCommandsBridge(orch);
this._envBridge = new RocketletEnvironmentalVariableBridge(orch);
this._httpBridge = new RocketletHttpBridge();
@@ -42,6 +45,10 @@ export class RealRocketletBridges extends RocketletBridges {
return this._persistBridge;
}
+ getRocketletActivationBridge() {
+ return this._actBridge;
+ }
+
getRoomBridge() {
return this._roomBridge;
}
diff --git a/packages/rocketchat-rocketlets/server/bridges/index.js b/packages/rocketchat-rocketlets/server/bridges/index.js
index 6f6662360c7..f464cffcb32 100644
--- a/packages/rocketchat-rocketlets/server/bridges/index.js
+++ b/packages/rocketchat-rocketlets/server/bridges/index.js
@@ -1,4 +1,5 @@
import { RealRocketletBridges } from './bridges';
+import { RocketletActivationBridge } from './activation';
import { RocketletCommandsBridge } from './commands';
import { RocketletEnvironmentalVariableBridge } from './environmental';
import { RocketletHttpBridge } from './http';
@@ -10,6 +11,7 @@ import { RocketletUserBridge } from './users';
export {
RealRocketletBridges,
+ RocketletActivationBridge,
RocketletCommandsBridge,
RocketletEnvironmentalVariableBridge,
RocketletHttpBridge,
diff --git a/packages/rocketchat-rocketlets/server/bridges/settings.js b/packages/rocketchat-rocketlets/server/bridges/settings.js
index 25ea83df39f..0971e0cb9e2 100644
--- a/packages/rocketchat-rocketlets/server/bridges/settings.js
+++ b/packages/rocketchat-rocketlets/server/bridges/settings.js
@@ -2,12 +2,29 @@ export class RocketletSettingBridge {
constructor(orch) {
this.orch = orch;
this.allowedGroups = [];
- this.allowedSettings = [];
+ this.disallowedSettings = [
+ 'Accounts_RegistrationForm_SecretURL', 'CROWD_APP_USERNAME', 'CROWD_APP_PASSWORD', 'Direct_Reply_Username',
+ 'Direct_Reply_Password', 'SMTP_Username', 'SMTP_Password', 'FileUpload_S3_AWSAccessKeyId', 'FileUpload_S3_AWSSecretAccessKey',
+ 'FileUpload_S3_BucketURL', 'FileUpload_GoogleStorage_Bucket', 'FileUpload_GoogleStorage_AccessId',
+ 'FileUpload_GoogleStorage_Secret', 'GoogleVision_ServiceAccount', 'Allow_Invalid_SelfSigned_Certs', 'GoogleTagManager_id',
+ 'Bugsnag_api_key', 'LDAP_CA_Cert', 'LDAP_Reject_Unauthorized', 'LDAP_Domain_Search_User', 'LDAP_Domain_Search_Password',
+ 'Livechat_secret_token', 'Livechat_Knowledge_Apiai_Key', 'AutoTranslate_GoogleAPIKey', 'MapView_GMapsAPIKey',
+ 'Meta_fb_app_id', 'Meta_google-site-verification', 'Meta_msvalidate01', 'Accounts_OAuth_Dolphin_secret',
+ 'Accounts_OAuth_Drupal_secret', 'Accounts_OAuth_Facebook_secret', 'Accounts_OAuth_Github_secret', 'API_GitHub_Enterprise_URL',
+ 'Accounts_OAuth_GitHub_Enterprise_secret', 'API_Gitlab_URL', 'Accounts_OAuth_Gitlab_secret', 'Accounts_OAuth_Google_secret',
+ 'Accounts_OAuth_Linkedin_secret', 'Accounts_OAuth_Meteor_secret', 'Accounts_OAuth_Twitter_secret', 'API_Wordpress_URL',
+ 'Accounts_OAuth_Wordpress_secret', 'Push_apn_passphrase', 'Push_apn_key', 'Push_apn_cert', 'Push_apn_dev_passphrase',
+ 'Push_apn_dev_key', 'Push_apn_dev_cert', 'Push_gcm_api_key', 'Push_gcm_project_number', 'SAML_Custom_Default_cert',
+ 'SAML_Custom_Default_private_key', 'SlackBridge_APIToken', 'Smarsh_Email', 'SMS_Twilio_Account_SID', 'SMS_Twilio_authToken'
+ ];
}
getAll(rocketletId) {
console.log(`The Rocketlet ${ rocketletId } is getting all the settings.`);
- throw new Error('Method not implemented.');
+
+ return RocketChat.models.Settings.find({ _id: { $nin: this.disallowedSettings } }).fetch().map((s) => {
+ this.orch.getConverters().get('settings').convertToRocketlet(s);
+ });
}
getOneById(id, rocketletId) {
@@ -38,7 +55,7 @@ export class RocketletSettingBridge {
isReadableById(id, rocketletId) {
console.log(`The Rocketlet ${ rocketletId } is checking if they can read the setting ${ id }.`);
- return this.allowedSettings.includes(id);
+ return !this.disallowedSettings.includes(id);
}
updateOne(setting, rocketletId) {
diff --git a/packages/rocketchat-rocketlets/server/communication/rest.js b/packages/rocketchat-rocketlets/server/communication/rest.js
index 0b6bc515379..50aff66c52b 100644
--- a/packages/rocketchat-rocketlets/server/communication/rest.js
+++ b/packages/rocketchat-rocketlets/server/communication/rest.js
@@ -40,7 +40,19 @@ export class RocketletsRestApi {
this.api.addRoute('', { authRequired: true }, {
get() {
- const rocketlets = manager.get().map(prl => prl.getInfo());
+ const rocketlets = manager.get().map(prl => {
+ if (this.queryParams.languagesOnly) {
+ return {
+ id: prl.getID(),
+ languages: prl.getStorageItem().languageFiles
+ };
+ } else {
+ const info = prl.getInfo();
+ info.languages = prl.getStorageItem().languageFiles;
+
+ return info;
+ }
+ });
return { success: true, rocketlets };
},
@@ -60,9 +72,16 @@ export class RocketletsRestApi {
this.api.addRoute(':id', { authRequired: true }, {
get() {
console.log('Getting:', this.urlParams.id);
- const rocketlet = manager.getOneById(this.urlParams.id).getInfo();
+ const prl = manager.getOneById(this.urlParams.id);
- return { success: true, rocketlet };
+ if (prl) {
+ const info = prl.getInfo();
+ info.languages = prl.getStorageItem().languageFiles;
+
+ return { success: true, rocketlet: info };
+ } else {
+ return RocketChat.API.v1.notFound(`No Rocketlet found by the id of: ${ this.urlParams.id }`);
+ }
},
post() {
console.log('Updating:', this.urlParams.id);
diff --git a/packages/rocketchat-rocketlets/server/converters/settings.js b/packages/rocketchat-rocketlets/server/converters/settings.js
index edce911c6cf..f6a6d3dabdd 100644
--- a/packages/rocketchat-rocketlets/server/converters/settings.js
+++ b/packages/rocketchat-rocketlets/server/converters/settings.js
@@ -8,6 +8,10 @@ export class RocketletSettingsConverter {
convertById(settingId) {
const setting = RocketChat.models.Settings.findOneById(settingId);
+ return this.convertToRocketlet(setting);
+ }
+
+ convertToRocketlet(setting) {
return {
id: setting._id,
type: this._convertTypeToRocketlet(setting.type),