diff --git a/.eslintrc b/.eslintrc index 6edb1a5fb690..37217240f006 100644 --- a/.eslintrc +++ b/.eslintrc @@ -4,7 +4,6 @@ "globals": { "__meteor_bootstrap__" : false, "__meteor_runtime_config__" : false, - "Apps" : false, "Assets" : false, "chrome" : false, "DynamicCss" : false, diff --git a/packages/rocketchat-api/client/index.js b/packages/rocketchat-api/client/index.js deleted file mode 100644 index 7e1df916437f..000000000000 --- a/packages/rocketchat-api/client/index.js +++ /dev/null @@ -1 +0,0 @@ -export { API } from './lib/RestApiClient'; diff --git a/packages/rocketchat-api/package.js b/packages/rocketchat-api/package.js index 0be138498da1..76c9f8bd5200 100644 --- a/packages/rocketchat-api/package.js +++ b/packages/rocketchat-api/package.js @@ -20,7 +20,5 @@ Package.onUse(function(api) { 'rocketchat:file-upload', 'rocketchat:authorization', ]); - - api.mainModule('client/index.js', 'client'); api.mainModule('server/index.js', 'server'); }); diff --git a/packages/rocketchat-apps/client/admin/appInstall.js b/packages/rocketchat-apps/client/admin/appInstall.js index df6ea61b65f7..2ed6f546b8db 100644 --- a/packages/rocketchat-apps/client/admin/appInstall.js +++ b/packages/rocketchat-apps/client/admin/appInstall.js @@ -10,7 +10,7 @@ import { ReactiveVar } from 'meteor/reactive-var'; import { FlowRouter } from 'meteor/kadira:flow-router'; import { Template } from 'meteor/templating'; -import { API } from 'meteor/rocketchat:api'; +import { APIClient } from 'meteor/rocketchat:utils'; Template.appInstall.helpers({ appFile() { @@ -73,9 +73,9 @@ Template.appInstall.events({ let result; if (isUpdating) { - result = await API.post(`apps/${ t.isUpdatingId.get() }`, { url }); + result = await APIClient.post(`apps/${ t.isUpdatingId.get() }`, { url }); } else { - result = await API.post('apps', { url }); + result = await APIClient.post('apps', { url }); } if (result.compilerErrors.length !== 0 || result.app.status === 'compiler_error') { @@ -116,9 +116,9 @@ Template.appInstall.events({ let result; if (isUpdating) { - result = await API.upload(`apps/${ t.isUpdatingId.get() }`, data); + result = await APIClient.upload(`apps/${ t.isUpdatingId.get() }`, data); } else { - result = await API.upload('apps', data); + result = await APIClient.upload('apps', data); } console.log('install result', result); diff --git a/packages/rocketchat-apps/client/admin/appLogs.js b/packages/rocketchat-apps/client/admin/appLogs.js index 11f1c419b951..29810bf46e85 100644 --- a/packages/rocketchat-apps/client/admin/appLogs.js +++ b/packages/rocketchat-apps/client/admin/appLogs.js @@ -2,7 +2,7 @@ import { ReactiveVar } from 'meteor/reactive-var'; import { FlowRouter } from 'meteor/kadira:flow-router'; import { Template } from 'meteor/templating'; import { TAPi18n } from 'meteor/tap:i18n'; -import { API } from 'meteor/rocketchat:api'; +import { APIClient } from 'meteor/rocketchat:utils'; import moment from 'moment'; import hljs from 'highlight.js'; @@ -18,8 +18,8 @@ Template.appLogs.onCreated(function() { const id = this.id.get(); Promise.all([ - API.get(`apps/${ id }`), - API.get(`apps/${ id }/logs`), + APIClient.get(`apps/${ id }`), + APIClient.get(`apps/${ id }/logs`), ]).then((results) => { instance.app.set(results[0].app); diff --git a/packages/rocketchat-apps/client/admin/appManage.js b/packages/rocketchat-apps/client/admin/appManage.js index b0a54ad45c36..1bd1f97ac9e6 100644 --- a/packages/rocketchat-apps/client/admin/appManage.js +++ b/packages/rocketchat-apps/client/admin/appManage.js @@ -4,15 +4,16 @@ import { FlowRouter } from 'meteor/kadira:flow-router'; import { Template } from 'meteor/templating'; import { TAPi18n } from 'meteor/tap:i18n'; import { TAPi18next } from 'meteor/tap:i18n'; -import { isEmail } from 'meteor/rocketchat:utils'; -import { API } from 'meteor/rocketchat:api'; +import { isEmail, Info, APIClient } from 'meteor/rocketchat:utils'; +import { settings } from 'meteor/rocketchat:settings'; +import { Markdown } from 'meteor/rocketchat:markdown'; import _ from 'underscore'; import s from 'underscore.string'; import toastr from 'toastr'; import { AppEvents } from '../communication'; import { Utilities } from '../../lib/misc/Utilities'; - +import { Apps } from '../orchestrator'; import semver from 'semver'; const HOST = 'https://marketplace.rocket.chat'; // TODO move this to inside RocketChat.API @@ -21,8 +22,8 @@ function getApps(instance) { const id = instance.id.get(); return Promise.all([ - fetch(`${ HOST }/v1/apps/${ id }?version=${ RocketChat.Info.marketplaceApiVersion }`).then((data) => data.json()), - API.get('apps/').then((result) => result.apps.filter((app) => app.id === id)), + fetch(`${ HOST }/v1/apps/${ id }?version=${ Info.marketplaceApiVersion }`).then((data) => data.json()), + APIClient.get('apps/').then((result) => result.apps.filter((app) => app.id === id)), ]).then(([remoteApps, [localApp]]) => { remoteApps = remoteApps.sort((a, b) => { if (semver.gt(a.version, b.version)) { @@ -46,10 +47,10 @@ function getApps(instance) { instance.onSettingUpdated({ appId: id }); - window.Apps.getWsListener().unregisterListener(AppEvents.APP_STATUS_CHANGE, instance.onStatusChanged); - window.Apps.getWsListener().unregisterListener(AppEvents.APP_SETTING_UPDATED, instance.onSettingUpdated); - window.Apps.getWsListener().registerListener(AppEvents.APP_STATUS_CHANGE, instance.onStatusChanged); - window.Apps.getWsListener().registerListener(AppEvents.APP_SETTING_UPDATED, instance.onSettingUpdated); + Apps.getWsListener().unregisterListener(AppEvents.APP_STATUS_CHANGE, instance.onStatusChanged); + Apps.getWsListener().unregisterListener(AppEvents.APP_SETTING_UPDATED, instance.onSettingUpdated); + Apps.getWsListener().registerListener(AppEvents.APP_STATUS_CHANGE, instance.onStatusChanged); + Apps.getWsListener().registerListener(AppEvents.APP_SETTING_UPDATED, instance.onSettingUpdated); } instance.app.set(localApp || remoteApp); @@ -77,7 +78,7 @@ Template.appManage.onCreated(function() { const id = this.id.get(); this.getApis = async() => { - this.apis.set(await window.Apps.getAppApis(id)); + this.apis.set(await Apps.getAppApis(id)); }; this.getApis(); @@ -115,7 +116,7 @@ Template.appManage.onCreated(function() { return; } - API.get(`apps/${ id }/settings`).then((result) => { + APIClient.get(`apps/${ id }/settings`).then((result) => { _morphSettings(result.settings); }); }; @@ -124,8 +125,8 @@ Template.appManage.onCreated(function() { Template.apps.onDestroyed(function() { const instance = this; - window.Apps.getWsListener().unregisterListener(AppEvents.APP_STATUS_CHANGE, instance.onStatusChanged); - window.Apps.getWsListener().unregisterListener(AppEvents.APP_SETTING_UPDATED, instance.onSettingUpdated); + Apps.getWsListener().unregisterListener(AppEvents.APP_STATUS_CHANGE, instance.onStatusChanged); + Apps.getWsListener().unregisterListener(AppEvents.APP_SETTING_UPDATED, instance.onSettingUpdated); }); Template.appManage.helpers({ @@ -155,7 +156,7 @@ Template.appManage.helpers({ return result; }, appLanguage(key) { - const setting = RocketChat.settings.get('Language'); + const setting = settings.get('Language'); return setting && setting.split('-').shift().toLowerCase() === key; }, selectedOption(_id, val) { @@ -230,7 +231,7 @@ Template.appManage.helpers({ return Template.instance().apis.get(); }, parseDescription(i18nDescription) { - const item = RocketChat.Markdown.parseMessageNotEscaped({ html: Template.instance().__(i18nDescription) }); + const item = Markdown.parseMessageNotEscaped({ html: Template.instance().__(i18nDescription) }); item.tokens.forEach((t) => item.html = item.html.replace(t.token, t.text)); @@ -264,7 +265,7 @@ async function setActivate(actiavate, e, t) { const status = actiavate ? 'manually_enabled' : 'manually_disabled'; try { - const result = await API.post(`apps/${ t.id.get() }/status`, { status }); + const result = await APIClient.post(`apps/${ t.id.get() }/status`, { status }); const info = t.app.get(); info.status = result.status; t.app.set(info); @@ -302,7 +303,7 @@ Template.appManage.events({ 'click .js-uninstall': async(e, t) => { t.ready.set(false); try { - await API.delete(`apps/${ t.id.get() }`); + await APIClient.delete(`apps/${ t.id.get() }`); FlowRouter.go('/admin/apps'); } catch (err) { console.warn('Error:', err); @@ -322,7 +323,7 @@ Template.appManage.events({ const api = app.newVersion ? `apps/${ t.id.get() }` : 'apps/'; - API.post(api, { url }).then(() => { + APIClient.post(api, { url }).then(() => { getApps(t).then(() => { el.prop('disabled', false); el.removeClass('loading'); @@ -372,7 +373,7 @@ Template.appManage.events({ if (toSave.length === 0) { throw 'Nothing to save..'; } - const result = await API.post(`apps/${ t.id.get() }/settings`, undefined, { settings: toSave }); + const result = await APIClient.post(`apps/${ t.id.get() }/settings`, undefined, { settings: toSave }); console.log('Updating results:', result); result.updated.forEach((setting) => { settings[setting.id].value = settings[setting.id].oldValue = setting.value; diff --git a/packages/rocketchat-apps/client/admin/appWhatIsIt.js b/packages/rocketchat-apps/client/admin/appWhatIsIt.js index 5da60b4b05b9..6272ffac7d81 100644 --- a/packages/rocketchat-apps/client/admin/appWhatIsIt.js +++ b/packages/rocketchat-apps/client/admin/appWhatIsIt.js @@ -2,6 +2,7 @@ import { Meteor } from 'meteor/meteor'; import { ReactiveVar } from 'meteor/reactive-var'; import { FlowRouter } from 'meteor/kadira:flow-router'; import { Template } from 'meteor/templating'; +import { Apps } from '../orchestrator'; Template.appWhatIsIt.onCreated(function() { this.isLoading = new ReactiveVar(false); @@ -36,7 +37,7 @@ Template.appWhatIsIt.events({ return; } - window.Apps.load(true); + Apps.load(true); FlowRouter.go('/admin/apps'); }); diff --git a/packages/rocketchat-apps/client/admin/apps.js b/packages/rocketchat-apps/client/admin/apps.js index ceae49ed5234..7f394d516837 100644 --- a/packages/rocketchat-apps/client/admin/apps.js +++ b/packages/rocketchat-apps/client/admin/apps.js @@ -2,9 +2,9 @@ import toastr from 'toastr'; import { ReactiveVar } from 'meteor/reactive-var'; import { FlowRouter } from 'meteor/kadira:flow-router'; import { Template } from 'meteor/templating'; -import { t } from 'meteor/rocketchat:utils'; +import { t, Info, APIClient } from 'meteor/rocketchat:utils'; import { AppEvents } from '../communication'; -import { API } from 'meteor/rocketchat:api'; +import { Apps } from '../orchestrator'; const ENABLED_STATUS = ['auto_enabled', 'manually_enabled']; const HOST = 'https://marketplace.rocket.chat'; @@ -36,7 +36,7 @@ const tagAlreadyInstalledApps = (installedApps, apps) => { const getApps = (instance) => { instance.isLoading.set(true); - fetch(`${ HOST }/v1/apps?version=${ RocketChat.Info.marketplaceApiVersion }`) + fetch(`${ HOST }/v1/apps?version=${ Info.marketplaceApiVersion }`) .then((response) => response.json()) .then((data) => { const tagged = tagAlreadyInstalledApps(instance.installedApps.get(), data); @@ -49,7 +49,7 @@ const getApps = (instance) => { const getInstalledApps = (instance) => { - API.get('apps').then((data) => { + APIClient.get('apps').then((data) => { const apps = data.apps.map((app) => ({ latest: app })); instance.installedApps.set(apps); @@ -109,15 +109,15 @@ Template.apps.onCreated(function() { instance.apps.set(apps); }; - window.Apps.getWsListener().registerListener(AppEvents.APP_ADDED, instance.onAppAdded); - window.Apps.getWsListener().registerListener(AppEvents.APP_REMOVED, instance.onAppAdded); + Apps.getWsListener().registerListener(AppEvents.APP_ADDED, instance.onAppAdded); + Apps.getWsListener().registerListener(AppEvents.APP_REMOVED, instance.onAppAdded); }); Template.apps.onDestroyed(function() { const instance = this; - window.Apps.getWsListener().unregisterListener(AppEvents.APP_ADDED, instance.onAppAdded); - window.Apps.getWsListener().unregisterListener(AppEvents.APP_REMOVED, instance.onAppAdded); + Apps.getWsListener().unregisterListener(AppEvents.APP_ADDED, instance.onAppAdded); + Apps.getWsListener().unregisterListener(AppEvents.APP_REMOVED, instance.onAppAdded); }); Template.apps.helpers({ @@ -257,7 +257,7 @@ Template.apps.events({ // play animation e.currentTarget.parentElement.classList.add('loading'); - API.post('apps/', { url }) + APIClient.post('apps/', { url }) .then(() => { getApps(template); getInstalledApps(template); diff --git a/packages/rocketchat-apps/client/communication/websockets.js b/packages/rocketchat-apps/client/communication/websockets.js index 248331cd0ff8..3b8a611438c1 100644 --- a/packages/rocketchat-apps/client/communication/websockets.js +++ b/packages/rocketchat-apps/client/communication/websockets.js @@ -1,5 +1,6 @@ import { Meteor } from 'meteor/meteor'; -import { API } from 'meteor/rocketchat:api'; +import { slashCommands, APIClient } from 'meteor/rocketchat:utils'; +import { CachedCollectionManager } from 'meteor/rocketchat:ui-cached-collection'; export const AppEvents = Object.freeze({ APP_ADDED: 'app/added', @@ -18,7 +19,7 @@ export class AppWebsocketReceiver { this.orch = orch; this.streamer = new Meteor.Streamer('apps'); - RocketChat.CachedCollectionManager.onLogin(() => { + CachedCollectionManager.onLogin(() => { this.listenStreamerEvents(); }); @@ -50,7 +51,7 @@ export class AppWebsocketReceiver { } onAppAdded(appId) { - API.get(`apps/${ appId }/languages`).then((result) => { + APIClient.get(`apps/${ appId }/languages`).then((result) => { this.orch.parseAndLoadLanguages(result.languages, appId); }); @@ -74,18 +75,18 @@ export class AppWebsocketReceiver { } onCommandAdded(command) { - API.v1.get('commands.get', { command }).then((result) => { - RocketChat.slashCommands.commands[command] = result.command; + APIClient.v1.get('commands.get', { command }).then((result) => { + slashCommands.commands[command] = result.command; }); } onCommandDisabled(command) { - delete RocketChat.slashCommands.commands[command]; + delete slashCommands.commands[command]; } onCommandUpdated(command) { - API.v1.get('commands.get', { command }).then((result) => { - RocketChat.slashCommands.commands[command] = result.command; + APIClient.v1.get('commands.get', { command }).then((result) => { + slashCommands.commands[command] = result.command; }); } } diff --git a/packages/rocketchat-apps/client/index.js b/packages/rocketchat-apps/client/index.js new file mode 100644 index 000000000000..d6b092029f5c --- /dev/null +++ b/packages/rocketchat-apps/client/index.js @@ -0,0 +1,11 @@ +export { Apps } from './orchestrator'; +import './admin/apps.html'; +import './admin/apps'; +import './admin/appInstall.html'; +import './admin/appInstall'; +import './admin/appLogs.html'; +import './admin/appLogs'; +import './admin/appManage.html'; +import './admin/appManage'; +import './admin/appWhatIsIt.html'; +import './admin/appWhatIsIt'; diff --git a/packages/rocketchat-apps/client/orchestrator.js b/packages/rocketchat-apps/client/orchestrator.js index ebe4067a8540..b85e612c77d6 100644 --- a/packages/rocketchat-apps/client/orchestrator.js +++ b/packages/rocketchat-apps/client/orchestrator.js @@ -4,7 +4,12 @@ import { Utilities } from '../lib/misc/Utilities'; import { FlowRouter } from 'meteor/kadira:flow-router'; import { BlazeLayout } from 'meteor/kadira:blaze-layout'; import { TAPi18next } from 'meteor/tap:i18n'; -import { API } from 'meteor/rocketchat:api'; +import { APIClient } from 'meteor/rocketchat:utils'; +import { AdminBox } from 'meteor/rocketchat:ui-utils'; +import { CachedCollectionManager } from 'meteor/rocketchat:ui-cached-collection'; +import { hasAtLeastOnePermission } from 'meteor/rocketchat:authorization'; + +export let Apps; class AppClientOrchestrator { constructor() { @@ -61,18 +66,18 @@ class AppClientOrchestrator { } _addAdminMenuOption() { - RocketChat.AdminBox.addOption({ + AdminBox.addOption({ icon: 'cube', href: 'apps', i18nLabel: 'Apps', permissionGranted() { - return RocketChat.authz.hasAtLeastOnePermission(['manage-apps']); + return hasAtLeastOnePermission(['manage-apps']); }, }); } _loadLanguages() { - return API.get('apps/languages').then((info) => { + return APIClient.get('apps/languages').then((info) => { info.apps.forEach((rlInfo) => this.parseAndLoadLanguages(rlInfo.languages, rlInfo.id)); }); } @@ -93,23 +98,23 @@ class AppClientOrchestrator { } async getAppApis(appId) { - const result = await API.get(`apps/${ appId }/apis`); + const result = await APIClient.get(`apps/${ appId }/apis`); return result.apis; } } Meteor.startup(function _rlClientOrch() { - window.Apps = new AppClientOrchestrator(); + Apps = new AppClientOrchestrator(); - RocketChat.CachedCollectionManager.onLogin(() => { + CachedCollectionManager.onLogin(() => { Meteor.call('apps/is-enabled', (error, isEnabled) => { - window.Apps.load(isEnabled); + Apps.load(isEnabled); }); }); }); const appsRouteAction = function _theRealAction(whichCenter) { - Meteor.defer(() => window.Apps.getLoadingPromise().then((isEnabled) => { + Meteor.defer(() => Apps.getLoadingPromise().then((isEnabled) => { if (isEnabled) { BlazeLayout.render('main', { center: whichCenter, old: true }); // TODO remove old } else { @@ -150,7 +155,7 @@ FlowRouter.route('/admin/apps/:appId/logs', { FlowRouter.route('/admin/app/what-is-it', { name: 'app-what-is-it', action() { - Meteor.defer(() => window.Apps.getLoadingPromise().then((isEnabled) => { + Meteor.defer(() => Apps.getLoadingPromise().then((isEnabled) => { if (isEnabled) { FlowRouter.go('apps'); } else { diff --git a/packages/rocketchat-apps/lib/Apps.js b/packages/rocketchat-apps/lib/Apps.js deleted file mode 100644 index 2a232ab0d0b2..000000000000 --- a/packages/rocketchat-apps/lib/Apps.js +++ /dev/null @@ -1,2 +0,0 @@ -// Please see both server and client's repsective "orchestrator" file for the contents -Apps = {}; diff --git a/packages/rocketchat-apps/package.js b/packages/rocketchat-apps/package.js index 82f2f351214c..323b0da07b04 100644 --- a/packages/rocketchat-apps/package.js +++ b/packages/rocketchat-apps/package.js @@ -6,84 +6,22 @@ Package.describe({ Package.onUse(function(api) { api.use([ 'ecmascript', - 'rocketchat:lib', - 'rocketchat:api', + 'rocketchat:markdown', 'rocketchat:utils', + 'rocketchat:settings', + 'rocketchat:models', + 'rocketchat:notifications', + 'rocketchat:ui-utils', + 'rocketchat:authorization', + 'rocketchat:ui-cached-collection', 'templating', ]); - - api.use(['reactive-var', 'kadira:flow-router', 'kadira:blaze-layout', 'underscore'], 'client'); - - api.addFiles('lib/Apps.js', ['client', 'server']); - - // Storage - api.addFiles([ - 'server/storage/apps-logs-model.js', - 'server/storage/apps-model.js', - 'server/storage/apps-persistence-model.js', - 'server/storage/storage.js', - 'server/storage/index.js', - ], 'server'); - - // Bridges - api.addFiles([ - 'server/bridges/activation.js', - 'server/bridges/bridges.js', - 'server/bridges/commands.js', - 'server/bridges/environmental.js', - 'server/bridges/messages.js', - 'server/bridges/persistence.js', - 'server/bridges/rooms.js', - 'server/bridges/settings.js', - 'server/bridges/users.js', - 'server/bridges/index.js', - ], 'server'); - - // Communication pieces - api.addFiles([ - 'server/communication/methods.js', - 'server/communication/rest.js', - 'server/communication/websockets.js', - 'server/communication/index.js', - ], 'server'); - - // RocketChat <-> App Data Converters - api.addFiles([ - 'server/converters/messages.js', - 'server/converters/rooms.js', - 'server/converters/settings.js', - 'server/converters/users.js', - 'server/converters/index.js', - ], 'server'); - - // Server Orchestrator - api.addFiles('server/orchestrator.js', 'server'); - - // Client communication pieces - api.addFiles([ - 'client/communication/websockets.js', - 'client/communication/index.js', - ], 'client'); - - // Client Admin Management - api.addFiles([ - 'client/admin/apps.html', - 'client/admin/apps.js', - 'client/admin/appManage.html', - 'client/admin/appManage.js', - 'client/admin/appInstall.html', - 'client/admin/appInstall.js', - 'client/admin/appLogs.html', - 'client/admin/appLogs.js', - 'client/admin/appWhatIsIt.html', - 'client/admin/appWhatIsIt.js', + api.use([ + 'reactive-var', + 'kadira:flow-router', + 'kadira:blaze-layout', + 'underscore', ], 'client'); - - api.addFiles('assets/stylesheets/apps.css', 'client'); - - // Client orchestrator - api.addFiles('client/orchestrator.js', 'client'); - - // Add what this package actually does export (needs updated to the module import style) - api.export('Apps'); + api.mainModule('client/index.js', 'client'); + api.mainModule('server/index.js', 'server'); }); diff --git a/packages/rocketchat-apps/server/bridges/commands.js b/packages/rocketchat-apps/server/bridges/commands.js index cc59dea68346..ed4c506b4b14 100644 --- a/packages/rocketchat-apps/server/bridges/commands.js +++ b/packages/rocketchat-apps/server/bridges/commands.js @@ -1,4 +1,5 @@ import { Meteor } from 'meteor/meteor'; +import { slashCommands } from 'meteor/rocketchat:utils'; import { SlashCommandContext } from '@rocket.chat/apps-engine/definition/slashcommands'; import { Utilities } from '../../lib/misc/Utilities'; @@ -16,7 +17,7 @@ export class AppCommandsBridge { } const cmd = command.toLowerCase(); - return typeof RocketChat.slashCommands.commands[cmd] === 'object' || this.disabledCommands.has(cmd); + return typeof slashCommands.commands[cmd] === 'object' || this.disabledCommands.has(cmd); } enableCommand(command, appId) { @@ -31,7 +32,7 @@ export class AppCommandsBridge { throw new Error(`The command is not currently disabled: "${ cmd }"`); } - RocketChat.slashCommands.commands[cmd] = this.disabledCommands.get(cmd); + slashCommands.commands[cmd] = this.disabledCommands.get(cmd); this.disabledCommands.delete(cmd); this.orch.getNotifier().commandUpdated(cmd); @@ -50,12 +51,12 @@ export class AppCommandsBridge { return; } - if (typeof RocketChat.slashCommands.commands[cmd] === 'undefined') { + if (typeof slashCommands.commands[cmd] === 'undefined') { throw new Error(`Command does not exist in the system currently: "${ cmd }"`); } - this.disabledCommands.set(cmd, RocketChat.slashCommands.commands[cmd]); - delete RocketChat.slashCommands.commands[cmd]; + this.disabledCommands.set(cmd, slashCommands.commands[cmd]); + delete slashCommands.commands[cmd]; this.orch.getNotifier().commandDisabled(cmd); } @@ -67,11 +68,11 @@ export class AppCommandsBridge { this._verifyCommand(command); const cmd = command.toLowerCase(); - if (typeof RocketChat.slashCommands.commands[cmd] === 'undefined') { + if (typeof slashCommands.commands[cmd] === 'undefined') { throw new Error(`Command does not exist in the system currently (or it is disabled): "${ cmd }"`); } - const item = RocketChat.slashCommands.commands[cmd]; + const item = slashCommands.commands[cmd]; item.params = command.paramsExample ? command.paramsExample : item.params; item.description = command.i18nDescription ? command.i18nDescription : item.params; item.callback = this._appCommandExecutor.bind(this); @@ -79,7 +80,7 @@ export class AppCommandsBridge { item.previewer = command.previewer ? this._appCommandPreviewer.bind(this) : item.previewer; item.previewCallback = command.executePreviewItem ? this._appCommandPreviewExecutor.bind(this) : item.previewCallback; - RocketChat.slashCommands.commands[cmd] = item; + slashCommands.commands[cmd] = item; this.orch.getNotifier().commandUpdated(cmd); } @@ -98,7 +99,7 @@ export class AppCommandsBridge { previewCallback: !command.executePreviewItem ? undefined : this._appCommandPreviewExecutor.bind(this), }; - RocketChat.slashCommands.commands[command.command.toLowerCase()] = item; + slashCommands.commands[command.command.toLowerCase()] = item; this.orch.getNotifier().commandAdded(command.command.toLowerCase()); } @@ -111,7 +112,7 @@ export class AppCommandsBridge { const cmd = command.toLowerCase(); this.disabledCommands.delete(cmd); - delete RocketChat.slashCommands.commands[cmd]; + delete slashCommands.commands[cmd]; this.orch.getNotifier().commandRemoved(cmd); } diff --git a/packages/rocketchat-apps/server/bridges/internal.js b/packages/rocketchat-apps/server/bridges/internal.js index d475d7d2e328..3bbe4742ec29 100644 --- a/packages/rocketchat-apps/server/bridges/internal.js +++ b/packages/rocketchat-apps/server/bridges/internal.js @@ -1,10 +1,12 @@ +import { Subscriptions } from 'meteor/rocketchat:models'; + export class AppInternalBridge { constructor(orch) { this.orch = orch; } getUsernamesOfRoomById(roomId) { - const records = RocketChat.models.Subscriptions.findByRoomIdWhenUsernameExists(roomId, { + const records = Subscriptions.findByRoomIdWhenUsernameExists(roomId, { fields: { 'u.username': 1, }, diff --git a/packages/rocketchat-apps/server/bridges/messages.js b/packages/rocketchat-apps/server/bridges/messages.js index de3b0a89d9ca..0746924fbb62 100644 --- a/packages/rocketchat-apps/server/bridges/messages.js +++ b/packages/rocketchat-apps/server/bridges/messages.js @@ -1,5 +1,7 @@ import { Meteor } from 'meteor/meteor'; import { Random } from 'meteor/random'; +import { Messages, Users, Subscriptions } from 'meteor/rocketchat:models'; +import { Notifications } from 'meteor/rocketchat:notifications'; export class AppMessageBridge { constructor(orch) { @@ -26,19 +28,23 @@ export class AppMessageBridge { async update(message, appId) { console.log(`The App ${ appId } is updating a message.`); + if (!this.updateMessage) { + const { updateMessage } = await import('meteor/rocketchat:lib'); + this.updateMessage = updateMessage; + } if (!message.editor) { throw new Error('Invalid editor assigned to the message for the update.'); } - if (!message.id || !RocketChat.models.Messages.findOneById(message.id)) { + if (!message.id || !Messages.findOneById(message.id)) { throw new Error('A message must exist to update.'); } const msg = this.orch.getConverters().get('messages').convertAppMessage(message); - const editor = RocketChat.models.Users.findOneById(message.editor.id); + const editor = Users.findOneById(message.editor.id); - RocketChat.updateMessage(msg, editor); + this.updateMessage(msg, editor); } async notifyUser(user, message, appId) { @@ -46,7 +52,7 @@ export class AppMessageBridge { const msg = this.orch.getConverters().get('messages').convertAppMessage(message); - RocketChat.Notifications.notifyUser(user.id, 'message', Object.assign(msg, { + Notifications.notifyUser(user.id, 'message', Object.assign(msg, { _id: Random.id(), ts: new Date(), u: undefined, @@ -67,13 +73,13 @@ export class AppMessageBridge { editor: undefined, }); - const users = RocketChat.models.Subscriptions.findByRoomIdWhenUserIdExists(room._id, { fields: { 'u._id': 1 } }) + const users = Subscriptions.findByRoomIdWhenUserIdExists(room._id, { fields: { 'u._id': 1 } }) .fetch() .map((s) => s.u._id); - RocketChat.models.Users.findByIds(users, { fields: { _id: 1 } }) + Users.findByIds(users, { fields: { _id: 1 } }) .fetch() .forEach(({ _id }) => - RocketChat.Notifications.notifyUser(_id, 'message', rmsg) + Notifications.notifyUser(_id, 'message', rmsg) ); } } diff --git a/packages/rocketchat-apps/server/bridges/rooms.js b/packages/rocketchat-apps/server/bridges/rooms.js index 9ae44a587200..4efaab16c3bb 100644 --- a/packages/rocketchat-apps/server/bridges/rooms.js +++ b/packages/rocketchat-apps/server/bridges/rooms.js @@ -1,4 +1,5 @@ import { Meteor } from 'meteor/meteor'; +import { Rooms, Subscriptions, Users } from 'meteor/rocketchat:models'; import { RoomType } from '@rocket.chat/apps-engine/definition/rooms'; export class AppRoomBridge { @@ -61,7 +62,7 @@ export class AppRoomBridge { async getCreatorById(roomId, appId) { console.log(`The App ${ appId } is getting the room's creator by id: "${ roomId }"`); - const room = RocketChat.models.Rooms.findOneById(roomId); + const room = Rooms.findOneById(roomId); if (!room || !room.u || !room.u._id) { return undefined; @@ -73,7 +74,7 @@ export class AppRoomBridge { async getCreatorByName(roomName, appId) { console.log(`The App ${ appId } is getting the room's creator by name: "${ roomName }"`); - const room = RocketChat.models.Rooms.findOneByName(roomName); + const room = Rooms.findOneByName(roomName); if (!room || !room.u || !room.u._id) { return undefined; @@ -84,13 +85,13 @@ export class AppRoomBridge { async getMembers(roomId, appId) { console.log(`The App ${ appId } is getting the room's members by room id: "${ roomId }"`); - const subscriptions = await RocketChat.models.Subscriptions.findByRoomId(roomId); + const subscriptions = await Subscriptions.findByRoomId(roomId); return subscriptions.map((sub) => this.orch.getConverters().get('users').convertById(sub.u && sub.u._id)); } async getDirectByUsernames(usernames, appId) { console.log(`The App ${ appId } is getting direct room by usernames: "${ usernames }"`); - const room = await RocketChat.models.Rooms.findDirectRoomContainingAllUsernames(usernames); + const room = await Rooms.findDirectRoomContainingAllUsernames(usernames); if (!room) { return undefined; } @@ -100,22 +101,27 @@ export class AppRoomBridge { async update(room, members = [], appId) { console.log(`The App ${ appId } is updating a room.`); - if (!room.id || !RocketChat.models.Rooms.findOneById(room.id)) { + if (!this.addUserToRoom) { + const { addUserToRoom } = await import('meteor/rocketchat:lib'); + this.addUserToRoom = addUserToRoom; + } + + if (!room.id || !Rooms.findOneById(room.id)) { throw new Error('A room must exist to update.'); } const rm = this.orch.getConverters().get('rooms').convertAppRoom(room); - RocketChat.models.Rooms.update(rm._id, rm); + Rooms.update(rm._id, rm); for (const username of members) { - const member = RocketChat.models.Users.findOneByUsername(username); + const member = Users.findOneByUsername(username); if (!member) { continue; } - RocketChat.addUserToRoom(rm._id, member); + this.addUserToRoom(rm._id, member); } } } diff --git a/packages/rocketchat-apps/server/bridges/settings.js b/packages/rocketchat-apps/server/bridges/settings.js index ef5028f13d3b..e1f7a764f187 100644 --- a/packages/rocketchat-apps/server/bridges/settings.js +++ b/packages/rocketchat-apps/server/bridges/settings.js @@ -1,3 +1,5 @@ +import { Settings } from 'meteor/rocketchat:models'; + export class AppSettingBridge { constructor(orch) { this.orch = orch; @@ -22,7 +24,7 @@ export class AppSettingBridge { async getAll(appId) { console.log(`The App ${ appId } is getting all the settings.`); - return RocketChat.models.Settings.find({ _id: { $nin: this.disallowedSettings } }) + return Settings.find({ _id: { $nin: this.disallowedSettings } }) .fetch() .map((s) => this.orch.getConverters().get('settings').convertToApp(s)); } diff --git a/packages/rocketchat-apps/server/communication/methods.js b/packages/rocketchat-apps/server/communication/methods.js index 1f67d6e77d79..20cd00ebc874 100644 --- a/packages/rocketchat-apps/server/communication/methods.js +++ b/packages/rocketchat-apps/server/communication/methods.js @@ -1,4 +1,6 @@ import { Meteor } from 'meteor/meteor'; +import { settings } from 'meteor/rocketchat:settings'; +import { hasPermission } from 'meteor/rocketchat:authorization'; const waitToLoad = function(orch) { return new Promise((resolve) => { @@ -58,13 +60,13 @@ export class AppMethods { }); } - if (!RocketChat.authz.hasPermission(Meteor.userId(), 'manage-apps')) { + if (!hasPermission(Meteor.userId(), 'manage-apps')) { throw new Meteor.Error('error-action-not-allowed', 'Not allowed', { method: 'apps/go-enable', }); } - RocketChat.settings.set('Apps_Framework_enabled', true); + settings.set('Apps_Framework_enabled', true); Promise.await(waitToLoad(instance._orch)); }, @@ -76,13 +78,13 @@ export class AppMethods { }); } - if (!RocketChat.authz.hasPermission(Meteor.userId(), 'manage-apps')) { + if (!hasPermission(Meteor.userId(), 'manage-apps')) { throw new Meteor.Error('error-action-not-allowed', 'Not allowed', { method: 'apps/go-enable', }); } - RocketChat.settings.set('Apps_Framework_enabled', false); + settings.set('Apps_Framework_enabled', false); Promise.await(waitToUnload(instance._orch)); }, diff --git a/packages/rocketchat-apps/server/communication/rest.js b/packages/rocketchat-apps/server/communication/rest.js index 0b66c66ea665..5ef5e89850ad 100644 --- a/packages/rocketchat-apps/server/communication/rest.js +++ b/packages/rocketchat-apps/server/communication/rest.js @@ -1,21 +1,14 @@ import { Meteor } from 'meteor/meteor'; import { HTTP } from 'meteor/http'; -import { API } from 'meteor/rocketchat:api'; import Busboy from 'busboy'; +let _API; + export class AppsRestApi { constructor(orch, manager) { this._orch = orch; this._manager = manager; - this.api = new API.ApiClass({ - version: 'apps', - useDefaultAuth: true, - prettyJson: false, - enableCors: false, - auth: API.getUserAuth(), - }); - - this.addManagementRoutes(); + this.loadAPI(); } _handleFile(request, fileField) { @@ -39,6 +32,19 @@ export class AppsRestApi { })(); } + async loadAPI() { + const { API } = await import('meteor/rocketchat:api'); + _API = API; + this.api = new API.ApiClass({ + version: 'apps', + useDefaultAuth: true, + prettyJson: false, + enableCors: false, + auth: API.getUserAuth(), + }); + this.addManagementRoutes(); + } + addManagementRoutes() { const orchestrator = this._orch; const manager = this._manager; @@ -54,7 +60,7 @@ export class AppsRestApi { return info; }); - return API.v1.success({ apps }); + return _API.v1.success({ apps }); }, post() { let buff; @@ -63,7 +69,7 @@ export class AppsRestApi { const result = HTTP.call('GET', this.bodyParams.url, { npmRequestOptions: { encoding: 'base64' } }); if (result.statusCode !== 200 || !result.headers['content-type'] || result.headers['content-type'] !== 'application/zip') { - return API.v1.failure({ error: 'Invalid url. It doesn\'t exist or is not "application/zip".' }); + return _API.v1.failure({ error: 'Invalid url. It doesn\'t exist or is not "application/zip".' }); } buff = Buffer.from(result.content, 'base64'); @@ -72,7 +78,7 @@ export class AppsRestApi { } if (!buff) { - return API.v1.failure({ error: 'Failed to get a file to install for the App. ' }); + return _API.v1.failure({ error: 'Failed to get a file to install for the App. ' }); } const aff = Promise.await(manager.add(buff.toString('base64'), false)); @@ -85,7 +91,7 @@ export class AppsRestApi { info.status = 'compiler_error'; } - return API.v1.success({ + return _API.v1.success({ app: info, implemented: aff.getImplementedInferfaces(), compilerErrors: aff.getCompilerErrors(), @@ -100,7 +106,7 @@ export class AppsRestApi { languages: prl.getStorageItem().languageContent, })); - return API.v1.success({ apps }); + return _API.v1.success({ apps }); }, }); @@ -113,9 +119,9 @@ export class AppsRestApi { const info = prl.getInfo(); info.status = prl.getStatus(); - return API.v1.success({ app: info }); + return _API.v1.success({ app: info }); } else { - return API.v1.notFound(`No App found by the id of: ${ this.urlParams.id }`); + return _API.v1.notFound(`No App found by the id of: ${ this.urlParams.id }`); } }, post() { @@ -128,7 +134,7 @@ export class AppsRestApi { const result = HTTP.call('GET', this.bodyParams.url, { npmRequestOptions: { encoding: 'base64' } }); if (result.statusCode !== 200 || !result.headers['content-type'] || result.headers['content-type'] !== 'application/zip') { - return API.v1.failure({ error: 'Invalid url. It doesn\'t exist or is not "application/zip".' }); + return _API.v1.failure({ error: 'Invalid url. It doesn\'t exist or is not "application/zip".' }); } buff = Buffer.from(result.content, 'base64'); @@ -137,7 +143,7 @@ export class AppsRestApi { } if (!buff) { - return API.v1.failure({ error: 'Failed to get a file to install for the App. ' }); + return _API.v1.failure({ error: 'Failed to get a file to install for the App. ' }); } const aff = Promise.await(manager.update(buff.toString('base64'))); @@ -150,7 +156,7 @@ export class AppsRestApi { info.status = 'compiler_error'; } - return API.v1.success({ + return _API.v1.success({ app: info, implemented: aff.getImplementedInferfaces(), compilerErrors: aff.getCompilerErrors(), @@ -166,9 +172,9 @@ export class AppsRestApi { const info = prl.getInfo(); info.status = prl.getStatus(); - return API.v1.success({ app: info }); + return _API.v1.success({ app: info }); } else { - return API.v1.notFound(`No App found by the id of: ${ this.urlParams.id }`); + return _API.v1.notFound(`No App found by the id of: ${ this.urlParams.id }`); } }, }); @@ -181,9 +187,9 @@ export class AppsRestApi { if (prl) { const info = prl.getInfo(); - return API.v1.success({ iconFileContent: info.iconFileContent }); + return _API.v1.success({ iconFileContent: info.iconFileContent }); } else { - return API.v1.notFound(`No App found by the id of: ${ this.urlParams.id }`); + return _API.v1.notFound(`No App found by the id of: ${ this.urlParams.id }`); } }, }); @@ -196,9 +202,9 @@ export class AppsRestApi { if (prl) { const languages = prl.getStorageItem().languageContent || {}; - return API.v1.success({ languages }); + return _API.v1.success({ languages }); } else { - return API.v1.notFound(`No App found by the id of: ${ this.urlParams.id }`); + return _API.v1.notFound(`No App found by the id of: ${ this.urlParams.id }`); } }, }); @@ -222,9 +228,9 @@ export class AppsRestApi { const logs = Promise.await(orchestrator.getLogStorage().find(ourQuery, options)); - return API.v1.success({ logs }); + return _API.v1.success({ logs }); } else { - return API.v1.notFound(`No App found by the id of: ${ this.urlParams.id }`); + return _API.v1.notFound(`No App found by the id of: ${ this.urlParams.id }`); } }, }); @@ -243,21 +249,21 @@ export class AppsRestApi { } }); - return API.v1.success({ settings }); + return _API.v1.success({ settings }); } else { - return API.v1.notFound(`No App found by the id of: ${ this.urlParams.id }`); + return _API.v1.notFound(`No App found by the id of: ${ this.urlParams.id }`); } }, post() { console.log(`Updating ${ this.urlParams.id }'s settings..`); if (!this.bodyParams || !this.bodyParams.settings) { - return API.v1.failure('The settings to update must be present.'); + return _API.v1.failure('The settings to update must be present.'); } const prl = manager.getOneById(this.urlParams.id); if (!prl) { - return API.v1.notFound(`No App found by the id of: ${ this.urlParams.id }`); + return _API.v1.notFound(`No App found by the id of: ${ this.urlParams.id }`); } const { settings } = prl.getStorageItem(); @@ -271,7 +277,7 @@ export class AppsRestApi { } }); - return API.v1.success({ updated }); + return _API.v1.success({ updated }); }, }); @@ -282,14 +288,14 @@ export class AppsRestApi { try { const setting = manager.getSettingsManager().getAppSetting(this.urlParams.id, this.urlParams.settingId); - API.v1.success({ setting }); + _API.v1.success({ setting }); } catch (e) { if (e.message.includes('No setting found')) { - return API.v1.notFound(`No Setting found on the App by the id of: "${ this.urlParams.settingId }"`); + return _API.v1.notFound(`No Setting found on the App by the id of: "${ this.urlParams.settingId }"`); } else if (e.message.includes('No App found')) { - return API.v1.notFound(`No App found by the id of: ${ this.urlParams.id }`); + return _API.v1.notFound(`No App found by the id of: ${ this.urlParams.id }`); } else { - return API.v1.failure(e.message); + return _API.v1.failure(e.message); } } }, @@ -297,20 +303,20 @@ export class AppsRestApi { console.log(`Updating the App ${ this.urlParams.id }'s setting ${ this.urlParams.settingId }`); if (!this.bodyParams.setting) { - return API.v1.failure('Setting to update to must be present on the posted body.'); + return _API.v1.failure('Setting to update to must be present on the posted body.'); } try { Promise.await(manager.getSettingsManager().updateAppSetting(this.urlParams.id, this.bodyParams.setting)); - return API.v1.success(); + return _API.v1.success(); } catch (e) { if (e.message.includes('No setting found')) { - return API.v1.notFound(`No Setting found on the App by the id of: "${ this.urlParams.settingId }"`); + return _API.v1.notFound(`No Setting found on the App by the id of: "${ this.urlParams.settingId }"`); } else if (e.message.includes('No App found')) { - return API.v1.notFound(`No App found by the id of: ${ this.urlParams.id }`); + return _API.v1.notFound(`No App found by the id of: ${ this.urlParams.id }`); } else { - return API.v1.failure(e.message); + return _API.v1.failure(e.message); } } }, @@ -322,11 +328,11 @@ export class AppsRestApi { const prl = manager.getOneById(this.urlParams.id); if (prl) { - return API.v1.success({ + return _API.v1.success({ apis: manager.apiManager.listApis(this.urlParams.id), }); } else { - return API.v1.notFound(`No App found by the id of: ${ this.urlParams.id }`); + return _API.v1.notFound(`No App found by the id of: ${ this.urlParams.id }`); } }, }); @@ -337,14 +343,14 @@ export class AppsRestApi { const prl = manager.getOneById(this.urlParams.id); if (prl) { - return API.v1.success({ status: prl.getStatus() }); + return _API.v1.success({ status: prl.getStatus() }); } else { - return API.v1.notFound(`No App found by the id of: ${ this.urlParams.id }`); + return _API.v1.notFound(`No App found by the id of: ${ this.urlParams.id }`); } }, post() { if (!this.bodyParams.status || typeof this.bodyParams.status !== 'string') { - return API.v1.failure('Invalid status provided, it must be "status" field and a string.'); + return _API.v1.failure('Invalid status provided, it must be "status" field and a string.'); } console.log(`Updating ${ this.urlParams.id }'s status...`, this.bodyParams.status); @@ -353,9 +359,9 @@ export class AppsRestApi { if (prl) { const result = Promise.await(manager.changeStatus(prl.getID(), this.bodyParams.status)); - return API.v1.success({ status: result.getStatus() }); + return _API.v1.success({ status: result.getStatus() }); } else { - return API.v1.notFound(`No App found by the id of: ${ this.urlParams.id }`); + return _API.v1.notFound(`No App found by the id of: ${ this.urlParams.id }`); } }, }); diff --git a/packages/rocketchat-apps/server/converters/messages.js b/packages/rocketchat-apps/server/converters/messages.js index 27caf85431ae..4236ff46a843 100644 --- a/packages/rocketchat-apps/server/converters/messages.js +++ b/packages/rocketchat-apps/server/converters/messages.js @@ -1,4 +1,5 @@ import { Random } from 'meteor/random'; +import { Messages, Rooms, Users } from 'meteor/rocketchat:models'; export class AppMessagesConverter { constructor(orch) { @@ -6,7 +7,7 @@ export class AppMessagesConverter { } convertById(msgId) { - const msg = RocketChat.models.Messages.findOneById(msgId); + const msg = Messages.findOneById(msgId); return this.convertMessage(msg); } @@ -59,7 +60,7 @@ export class AppMessagesConverter { return undefined; } - const room = RocketChat.models.Rooms.findOneById(message.room.id); + const room = Rooms.findOneById(message.room.id); if (!room) { throw new Error('Invalid room provided on the message.'); @@ -67,7 +68,7 @@ export class AppMessagesConverter { let u; if (message.sender && message.sender.id) { - const user = RocketChat.models.Users.findOneById(message.sender.id); + const user = Users.findOneById(message.sender.id); if (user) { u = { @@ -86,7 +87,7 @@ export class AppMessagesConverter { let editedBy; if (message.editor) { - const editor = RocketChat.models.Users.findOneById(message.editor.id); + const editor = Users.findOneById(message.editor.id); editedBy = { _id: editor._id, username: editor.username, diff --git a/packages/rocketchat-apps/server/converters/rooms.js b/packages/rocketchat-apps/server/converters/rooms.js index e87ef1625be8..224ec5872c93 100644 --- a/packages/rocketchat-apps/server/converters/rooms.js +++ b/packages/rocketchat-apps/server/converters/rooms.js @@ -1,3 +1,4 @@ +import { Rooms, Users } from 'meteor/rocketchat:models'; import { RoomType } from '@rocket.chat/apps-engine/definition/rooms'; export class AppRoomsConverter { @@ -6,13 +7,13 @@ export class AppRoomsConverter { } convertById(roomId) { - const room = RocketChat.models.Rooms.findOneById(roomId); + const room = Rooms.findOneById(roomId); return this.convertRoom(room); } convertByName(roomName) { - const room = RocketChat.models.Rooms.findOneByName(roomName); + const room = Rooms.findOneByName(roomName); return this.convertRoom(room); } @@ -24,7 +25,7 @@ export class AppRoomsConverter { let u; if (room.creator) { - const creator = RocketChat.models.Users.findOneById(room.creator.id); + const creator = Users.findOneById(room.creator.id); u = { _id: creator._id, username: creator.username, diff --git a/packages/rocketchat-apps/server/converters/settings.js b/packages/rocketchat-apps/server/converters/settings.js index 82d628e16db7..0b6698de14a5 100644 --- a/packages/rocketchat-apps/server/converters/settings.js +++ b/packages/rocketchat-apps/server/converters/settings.js @@ -1,3 +1,4 @@ +import { Settings } from 'meteor/rocketchat:models'; import { SettingType } from '@rocket.chat/apps-engine/definition/settings'; export class AppSettingsConverter { @@ -6,7 +7,7 @@ export class AppSettingsConverter { } convertById(settingId) { - const setting = RocketChat.models.Settings.findOneNotHiddenById(settingId); + const setting = Settings.findOneNotHiddenById(settingId); return this.convertToApp(setting); } diff --git a/packages/rocketchat-apps/server/converters/users.js b/packages/rocketchat-apps/server/converters/users.js index aac153def558..148bbdce2d80 100644 --- a/packages/rocketchat-apps/server/converters/users.js +++ b/packages/rocketchat-apps/server/converters/users.js @@ -1,3 +1,4 @@ +import { Users } from 'meteor/rocketchat:models'; import { UserStatusConnection, UserType } from '@rocket.chat/apps-engine/definition/users'; export class AppUsersConverter { @@ -6,13 +7,13 @@ export class AppUsersConverter { } convertById(userId) { - const user = RocketChat.models.Users.findOneById(userId); + const user = Users.findOneById(userId); return this.convertToApp(user); } convertByUsername(username) { - const user = RocketChat.models.Users.findOneByUsername(username); + const user = Users.findOneByUsername(username); return this.convertToApp(user); } diff --git a/packages/rocketchat-apps/server/index.js b/packages/rocketchat-apps/server/index.js new file mode 100644 index 000000000000..0d8b925c2207 --- /dev/null +++ b/packages/rocketchat-apps/server/index.js @@ -0,0 +1 @@ +export { Apps } from './orchestrator'; diff --git a/packages/rocketchat-apps/server/orchestrator.js b/packages/rocketchat-apps/server/orchestrator.js index b8dd4e494cf9..644d322b77f6 100644 --- a/packages/rocketchat-apps/server/orchestrator.js +++ b/packages/rocketchat-apps/server/orchestrator.js @@ -1,15 +1,18 @@ import { Meteor } from 'meteor/meteor'; +import { Permissions, AppsLogsModel, AppsModel, AppsPersistenceModel } from 'meteor/rocketchat:models'; +import { settings } from 'meteor/rocketchat:settings'; import { RealAppBridges } from './bridges'; import { AppMethods, AppsRestApi, AppServerNotifier } from './communication'; import { AppMessagesConverter, AppRoomsConverter, AppSettingsConverter, AppUsersConverter } from './converters'; -import { AppsLogsModel, AppsModel, AppsPersistenceModel, AppRealStorage, AppRealLogsStorage } from './storage'; - +import { AppRealStorage, AppRealLogsStorage } from './storage'; import { AppManager } from '@rocket.chat/apps-engine/server/AppManager'; +export let Apps; + class AppServerOrchestrator { constructor() { - if (RocketChat.models && RocketChat.models.Permissions) { - RocketChat.models.Permissions.createOrUpdate('manage-apps', ['admin']); + if (Permissions) { + Permissions.createOrUpdate('manage-apps', ['admin']); } this._model = new AppsModel(); @@ -67,7 +70,7 @@ class AppServerOrchestrator { } isEnabled() { - return RocketChat.settings.get('Apps_Framework_enabled'); + return settings.get('Apps_Framework_enabled'); } isLoaded() { @@ -99,7 +102,7 @@ class AppServerOrchestrator { } } -RocketChat.settings.addGroup('General', function() { +settings.addGroup('General', function() { this.section('Apps', function() { this.add('Apps_Framework_enabled', true, { type: 'boolean', @@ -108,23 +111,23 @@ RocketChat.settings.addGroup('General', function() { }); }); -RocketChat.settings.get('Apps_Framework_enabled', (key, isEnabled) => { +settings.get('Apps_Framework_enabled', (key, isEnabled) => { // In case this gets called before `Meteor.startup` - if (!global.Apps) { + if (!Apps) { return; } if (isEnabled) { - global.Apps.load(); + Apps.load(); } else { - global.Apps.unload(); + Apps.unload(); } }); Meteor.startup(function _appServerOrchestrator() { - global.Apps = new AppServerOrchestrator(); + Apps = new AppServerOrchestrator(); - if (global.Apps.isEnabled()) { - global.Apps.load(); + if (Apps.isEnabled()) { + Apps.load(); } }); diff --git a/packages/rocketchat-apps/server/storage/apps-logs-model.js b/packages/rocketchat-apps/server/storage/apps-logs-model.js deleted file mode 100644 index 762b50106718..000000000000 --- a/packages/rocketchat-apps/server/storage/apps-logs-model.js +++ /dev/null @@ -1,5 +0,0 @@ -export class AppsLogsModel extends RocketChat.models._Base { - constructor() { - super('apps_logs'); - } -} diff --git a/packages/rocketchat-apps/server/storage/apps-model.js b/packages/rocketchat-apps/server/storage/apps-model.js deleted file mode 100644 index 7f582c794722..000000000000 --- a/packages/rocketchat-apps/server/storage/apps-model.js +++ /dev/null @@ -1,5 +0,0 @@ -export class AppsModel extends RocketChat.models._Base { - constructor() { - super('apps'); - } -} diff --git a/packages/rocketchat-apps/server/storage/apps-persistence-model.js b/packages/rocketchat-apps/server/storage/apps-persistence-model.js deleted file mode 100644 index c6b85aefef09..000000000000 --- a/packages/rocketchat-apps/server/storage/apps-persistence-model.js +++ /dev/null @@ -1,5 +0,0 @@ -export class AppsPersistenceModel extends RocketChat.models._Base { - constructor() { - super('apps_persistence'); - } -} diff --git a/packages/rocketchat-apps/server/storage/index.js b/packages/rocketchat-apps/server/storage/index.js index 7f24049628fa..fd1680c1c9c3 100644 --- a/packages/rocketchat-apps/server/storage/index.js +++ b/packages/rocketchat-apps/server/storage/index.js @@ -1,7 +1,4 @@ -import { AppsLogsModel } from './apps-logs-model'; -import { AppsModel } from './apps-model'; -import { AppsPersistenceModel } from './apps-persistence-model'; import { AppRealLogsStorage } from './logs-storage'; import { AppRealStorage } from './storage'; -export { AppsLogsModel, AppsModel, AppsPersistenceModel, AppRealLogsStorage, AppRealStorage }; +export { AppRealLogsStorage, AppRealStorage }; diff --git a/packages/rocketchat-importer/client/admin/adminImportHistory.js b/packages/rocketchat-importer/client/admin/adminImportHistory.js index 9a33fd86ec99..bd15f0a80302 100644 --- a/packages/rocketchat-importer/client/admin/adminImportHistory.js +++ b/packages/rocketchat-importer/client/admin/adminImportHistory.js @@ -2,12 +2,11 @@ import { Meteor } from 'meteor/meteor'; import { Importers } from 'meteor/rocketchat:importer'; import { Template } from 'meteor/templating'; import { hasRole } from 'meteor/rocketchat:authorization'; -import { t } from 'meteor/rocketchat:utils'; +import { t, APIClient } from 'meteor/rocketchat:utils'; import toastr from 'toastr'; import { ReactiveVar } from 'meteor/reactive-var'; import { ProgressStep } from '../../lib/ImporterProgressStep'; import { FlowRouter } from 'meteor/kadira:flow-router'; -import { API } from 'meteor/rocketchat:api'; Template.adminImportHistory.helpers({ isAdmin() { @@ -184,7 +183,7 @@ Template.adminImportHistory.onCreated(function() { this.preparing = new ReactiveVar(true); this.history = new ReactiveVar([]); - API.get('v1/getLatestImportOperations').then((data) => { + APIClient.get('v1/getLatestImportOperations').then((data) => { instance.history.set(data); instance.preparing.set(false); }).catch((error) => { diff --git a/packages/rocketchat-importer/client/admin/adminImportPrepare.js b/packages/rocketchat-importer/client/admin/adminImportPrepare.js index 610c4056ee82..4caceb165077 100644 --- a/packages/rocketchat-importer/client/admin/adminImportPrepare.js +++ b/packages/rocketchat-importer/client/admin/adminImportPrepare.js @@ -6,8 +6,7 @@ import { Template } from 'meteor/templating'; import { TAPi18n } from 'meteor/tap:i18n'; import { hasRole } from 'meteor/rocketchat:authorization'; import { settings } from 'meteor/rocketchat:settings'; -import { t, handleError } from 'meteor/rocketchat:utils'; -import { API } from 'meteor/rocketchat:api'; +import { t, handleError, APIClient } from 'meteor/rocketchat:utils'; import toastr from 'toastr'; Template.adminImportPrepare.helpers({ @@ -97,7 +96,7 @@ function showException(error, defaultErrorString) { } function getImportFileData(importer, template) { - API.get(`v1/getImportFileData?importerKey=${ importer.key }`).then((data) => { + APIClient.get(`v1/getImportFileData?importerKey=${ importer.key }`).then((data) => { if (!data) { console.warn(`The importer ${ importer.key } is not set up correctly, as it did not return any data.`); toastr.error(t('Importer_not_setup')); @@ -150,7 +149,7 @@ Template.adminImportPrepare.events({ reader.readAsBinaryString(file); reader.onloadend = () => { - API.post('v1/uploadImportFile', { + APIClient.post('v1/uploadImportFile', { binaryContent: reader.result, contentType: file.type, fileName: file.name, @@ -176,7 +175,7 @@ Template.adminImportPrepare.events({ template.preparing.set(true); - API.post('v1/downloadPublicImportFile', { + APIClient.post('v1/downloadPublicImportFile', { fileUrl, importerKey: importer.key, }).then(() => { diff --git a/packages/rocketchat-lib/client/lib/startup/commands.js b/packages/rocketchat-lib/client/lib/startup/commands.js index d07c7e670ce6..0c1b0864840d 100644 --- a/packages/rocketchat-lib/client/lib/startup/commands.js +++ b/packages/rocketchat-lib/client/lib/startup/commands.js @@ -1,6 +1,6 @@ import { Meteor } from 'meteor/meteor'; import { Tracker } from 'meteor/tracker'; -import { slashCommands } from 'meteor/rocketchat:utils'; +import { slashCommands, APIClient } from 'meteor/rocketchat:utils'; // Track logins and when they login, get the commands (() => { @@ -9,11 +9,9 @@ import { slashCommands } from 'meteor/rocketchat:utils'; Tracker.autorun(() => { const newUserId = Meteor.userId(); if (oldUserId === null && newUserId) { - import('meteor/rocketchat:api').then(({ API }) => { - API.v1.get('commands.list').then(function _loadedCommands(result) { - result.commands.forEach((command) => { - slashCommands.commands[command.command] = command; - }); + APIClient.v1.get('commands.list').then(function _loadedCommands(result) { + result.commands.forEach((command) => { + slashCommands.commands[command.command] = command; }); }); } diff --git a/packages/rocketchat-lib/package.js b/packages/rocketchat-lib/package.js index 622b66f3aaa5..84fb4cd31b8b 100644 --- a/packages/rocketchat-lib/package.js +++ b/packages/rocketchat-lib/package.js @@ -57,6 +57,7 @@ Package.onUse(function(api) { api.use('rocketchat:markdown'); api.use('rocketchat:channel-settings'); api.use('rocketchat:tokenpass'); + api.use('rocketchat:apps'); api.use('templating', 'client'); api.use('kadira:flow-router'); diff --git a/packages/rocketchat-lib/server/functions/createRoom.js b/packages/rocketchat-lib/server/functions/createRoom.js index ca2154fd8290..1183aa75fbb5 100644 --- a/packages/rocketchat-lib/server/functions/createRoom.js +++ b/packages/rocketchat-lib/server/functions/createRoom.js @@ -3,6 +3,7 @@ import { Users, Rooms, Subscriptions } from 'meteor/rocketchat:models'; import { callbacks } from 'meteor/rocketchat:callbacks'; import { hasPermission, addUserRoles } from 'meteor/rocketchat:authorization'; import { getValidRoomName } from 'meteor/rocketchat:utils'; +import { Apps } from 'meteor/rocketchat:apps'; import _ from 'underscore'; import s from 'underscore.string'; diff --git a/packages/rocketchat-lib/server/functions/deleteMessage.js b/packages/rocketchat-lib/server/functions/deleteMessage.js index 5c0c634d8d45..de500f84eaa8 100644 --- a/packages/rocketchat-lib/server/functions/deleteMessage.js +++ b/packages/rocketchat-lib/server/functions/deleteMessage.js @@ -4,6 +4,7 @@ import { settings } from 'meteor/rocketchat:settings'; import { Messages, Uploads, Rooms } from 'meteor/rocketchat:models'; import { Notifications } from 'meteor/rocketchat:notifications'; import { callbacks } from 'meteor/rocketchat:callbacks'; +import { Apps } from 'meteor/rocketchat:apps'; export const deleteMessage = function(message, user) { const keepHistory = settings.get('Message_KeepHistory'); diff --git a/packages/rocketchat-lib/server/functions/sendMessage.js b/packages/rocketchat-lib/server/functions/sendMessage.js index da7e7c236c38..b0c16f247f37 100644 --- a/packages/rocketchat-lib/server/functions/sendMessage.js +++ b/packages/rocketchat-lib/server/functions/sendMessage.js @@ -3,6 +3,7 @@ import { Match, check } from 'meteor/check'; import { settings } from 'meteor/rocketchat:settings'; import { callbacks } from 'meteor/rocketchat:callbacks'; import { Messages } from 'meteor/rocketchat:models'; +import { Apps } from 'meteor/rocketchat:apps'; const objectMaybeIncluding = (types) => Match.Where((value) => { Object.keys(types).forEach((field) => { diff --git a/packages/rocketchat-lib/server/functions/updateMessage.js b/packages/rocketchat-lib/server/functions/updateMessage.js index a412cdfd5ef9..f3a7098a7a9d 100644 --- a/packages/rocketchat-lib/server/functions/updateMessage.js +++ b/packages/rocketchat-lib/server/functions/updateMessage.js @@ -2,6 +2,7 @@ import { Meteor } from 'meteor/meteor'; import { Messages, Rooms } from 'meteor/rocketchat:models'; import { settings } from 'meteor/rocketchat:settings'; import { callbacks } from 'meteor/rocketchat:callbacks'; +import { Apps } from 'meteor/rocketchat:apps'; export const updateMessage = function(message, user, originalMessage) { if (!originalMessage) { diff --git a/packages/rocketchat-models/server/index.js b/packages/rocketchat-models/server/index.js index 620fd6da9dd5..d1673f0ef45c 100644 --- a/packages/rocketchat-models/server/index.js +++ b/packages/rocketchat-models/server/index.js @@ -32,6 +32,10 @@ import LivechatTrigger from './models/LivechatTrigger'; import LivechatVisitors from './models/LivechatVisitors'; import ReadReceipts from './models/ReadReceipts'; +export { AppsLogsModel } from './models/apps-logs-model'; +export { AppsPersistenceModel } from './models/apps-persistence-model'; +export { AppsModel } from './models/apps-model'; + export { Base, BaseDb, diff --git a/packages/rocketchat-models/server/models/apps-logs-model.js b/packages/rocketchat-models/server/models/apps-logs-model.js new file mode 100644 index 000000000000..a2888e3ba062 --- /dev/null +++ b/packages/rocketchat-models/server/models/apps-logs-model.js @@ -0,0 +1,7 @@ +import { Base } from './_Base'; + +export class AppsLogsModel extends Base { + constructor() { + super('apps_logs'); + } +} diff --git a/packages/rocketchat-models/server/models/apps-model.js b/packages/rocketchat-models/server/models/apps-model.js new file mode 100644 index 000000000000..086db3ccb7e6 --- /dev/null +++ b/packages/rocketchat-models/server/models/apps-model.js @@ -0,0 +1,7 @@ +import { Base } from './_Base'; + +export class AppsModel extends Base { + constructor() { + super('apps'); + } +} diff --git a/packages/rocketchat-models/server/models/apps-persistence-model.js b/packages/rocketchat-models/server/models/apps-persistence-model.js new file mode 100644 index 000000000000..bad009b7faeb --- /dev/null +++ b/packages/rocketchat-models/server/models/apps-persistence-model.js @@ -0,0 +1,7 @@ +import { Base } from './_Base'; + +export class AppsPersistenceModel extends Base { + constructor() { + super('apps_persistence'); + } +} diff --git a/packages/rocketchat-utils/client/index.js b/packages/rocketchat-utils/client/index.js index 958894c3f10e..f4874061faa0 100644 --- a/packages/rocketchat-utils/client/index.js +++ b/packages/rocketchat-utils/client/index.js @@ -18,3 +18,4 @@ export { getURL } from '../lib/getURL'; export { getValidRoomName } from '../lib/getValidRoomName'; export { placeholders } from '../lib/placeholders'; export { templateVarHandler } from '../lib/templateVarHandler'; +export { APIClient } from './lib/RestApiClient'; diff --git a/packages/rocketchat-api/client/lib/RestApiClient.js b/packages/rocketchat-utils/client/lib/RestApiClient.js similarity index 76% rename from packages/rocketchat-api/client/lib/RestApiClient.js rename to packages/rocketchat-utils/client/lib/RestApiClient.js index 403ff02f2827..de803712d691 100644 --- a/packages/rocketchat-api/client/lib/RestApiClient.js +++ b/packages/rocketchat-utils/client/lib/RestApiClient.js @@ -1,10 +1,10 @@ -export const API = { +export const APIClient = { delete(endpoint, params) { - return API._jqueryCall('DELETE', endpoint, params); + return APIClient._jqueryCall('DELETE', endpoint, params); }, get(endpoint, params) { - return API._jqueryCall('GET', endpoint, params); + return APIClient._jqueryCall('GET', endpoint, params); }, post(endpoint, params, body) { @@ -13,7 +13,7 @@ export const API = { params = {}; } - return API._jqueryCall('POST', endpoint, params, body); + return APIClient._jqueryCall('POST', endpoint, params, body); }, upload(endpoint, params, formData) { @@ -22,7 +22,7 @@ export const API = { params = {}; } - return API._jqueryFormDataCall(endpoint, params, formData); + return APIClient._jqueryFormDataCall(endpoint, params, formData); }, _generateQueryFromParams(params) { @@ -39,7 +39,7 @@ export const API = { }, _jqueryCall(method, endpoint, params, body) { - const query = API._generateQueryFromParams(params); + const query = APIClient._generateQueryFromParams(params); return new Promise(function _rlRestApiGet(resolve, reject) { jQuery.ajax({ @@ -64,7 +64,7 @@ export const API = { }, _jqueryFormDataCall(endpoint, params, formData) { - const query = API._generateQueryFromParams(params); + const query = APIClient._generateQueryFromParams(params); if (!(formData instanceof FormData)) { throw new Error('The formData parameter MUST be an instance of the FormData class.'); @@ -93,19 +93,19 @@ export const API = { v1: { delete(endpoint, params) { - return API.delete(`v1/${ endpoint }`, params); + return APIClient.delete(`v1/${ endpoint }`, params); }, get(endpoint, params) { - return API.get(`v1/${ endpoint }`, params); + return APIClient.get(`v1/${ endpoint }`, params); }, post(endpoint, params, body) { - return API.post(`v1/${ endpoint }`, params, body); + return APIClient.post(`v1/${ endpoint }`, params, body); }, upload(endpoint, params, formData) { - return API.upload(`v1/${ endpoint }`, params, formData); + return APIClient.upload(`v1/${ endpoint }`, params, formData); }, }, }; diff --git a/server/methods/eraseRoom.js b/server/methods/eraseRoom.js index 1eee5eb8c1d5..348ebbe3161a 100644 --- a/server/methods/eraseRoom.js +++ b/server/methods/eraseRoom.js @@ -3,6 +3,7 @@ import { check } from 'meteor/check'; import { roomTypes } from 'meteor/rocketchat:utils'; import { hasPermission } from 'meteor/rocketchat:authorization'; import { Rooms, Messages, Subscriptions } from 'meteor/rocketchat:models'; +import { Apps } from 'meteor/rocketchat:apps'; Meteor.methods({ eraseRoom(rid) {