diff --git a/apps/meteor/app/authentication/server/startup/index.js b/apps/meteor/app/authentication/server/startup/index.js index ab622be95d53a..e3b97c1aae88a 100644 --- a/apps/meteor/app/authentication/server/startup/index.js +++ b/apps/meteor/app/authentication/server/startup/index.js @@ -1,4 +1,3 @@ -import { Apps, AppEvents } from '@rocket.chat/apps'; import { Roles, Settings, Users } from '@rocket.chat/models'; import { escapeRegExp, escapeHTML } from '@rocket.chat/string-helpers'; import { Accounts } from 'meteor/accounts-base'; @@ -6,6 +5,7 @@ import { Match } from 'meteor/check'; import { Meteor } from 'meteor/meteor'; import _ from 'underscore'; +import { AppEvents, Apps } from '../../../../ee/server/apps/orchestrator'; import { callbacks } from '../../../../lib/callbacks'; import { beforeCreateUserCallback } from '../../../../lib/callbacks/beforeCreateUserCallback'; import { parseCSV } from '../../../../lib/utils/parseCSV'; @@ -350,8 +350,8 @@ const insertUserDocAsync = async function (options, user) { if (!options.skipAppsEngineEvent) { // `post` triggered events don't need to wait for the promise to resolve - Apps?.triggerEvent(AppEvents.IPostUserCreated, { user, performedBy: await safeGetMeteorUser() }).catch((e) => { - Apps?.getRocketChatLogger().error('Error while executing post user created event:', e); + Apps.triggerEvent(AppEvents.IPostUserCreated, { user, performedBy: await safeGetMeteorUser() }).catch((e) => { + Apps.getRocketChatLogger().error('Error while executing post user created event:', e); }); } @@ -424,7 +424,7 @@ const validateLoginAttemptAsync = async function (login) { */ if (login.type !== 'resume') { // App IPostUserLoggedIn event hook - await Apps?.triggerEvent(AppEvents.IPostUserLoggedIn, login.user); + await Apps.triggerEvent(AppEvents.IPostUserLoggedIn, login.user); } return true; diff --git a/apps/meteor/app/file-upload/server/lib/FileUpload.ts b/apps/meteor/app/file-upload/server/lib/FileUpload.ts index 342d541f01bf5..e512e5d09bfe8 100644 --- a/apps/meteor/app/file-upload/server/lib/FileUpload.ts +++ b/apps/meteor/app/file-upload/server/lib/FileUpload.ts @@ -8,7 +8,6 @@ import stream from 'stream'; import URL from 'url'; import { hashLoginToken } from '@rocket.chat/account-utils'; -import { Apps, AppEvents } from '@rocket.chat/apps'; import { AppsEngineException } from '@rocket.chat/apps-engine/definition/exceptions'; import type { IUpload } from '@rocket.chat/core-typings'; import { Users, Avatars, UserDataFiles, Uploads, Settings, Subscriptions, Messages, Rooms } from '@rocket.chat/models'; @@ -22,6 +21,7 @@ import sharp from 'sharp'; import type { WritableStreamBuffer } from 'stream-buffers'; import streamBuffers from 'stream-buffers'; +import { AppEvents, Apps } from '../../../../ee/server/apps'; import { i18n } from '../../../../server/lib/i18n'; import { SystemLogger } from '../../../../server/lib/logger/system'; import { roomCoordinator } from '../../../../server/lib/rooms/roomCoordinator'; @@ -177,7 +177,7 @@ export const FileUpload = { // App IPreFileUpload event hook try { - await Apps?.triggerEvent(AppEvents.IPreFileUpload, { file, content: content || Buffer.from([]) }); + await Apps.triggerEvent(AppEvents.IPreFileUpload, { file, content: content || Buffer.from([]) }); } catch (error: any) { if (error.name === AppsEngineException.name) { throw new Meteor.Error('error-app-prevented', error.message); diff --git a/apps/meteor/app/lib/server/functions/addUserToRoom.ts b/apps/meteor/app/lib/server/functions/addUserToRoom.ts index 4a70943d28e27..4e29576cf3bb5 100644 --- a/apps/meteor/app/lib/server/functions/addUserToRoom.ts +++ b/apps/meteor/app/lib/server/functions/addUserToRoom.ts @@ -1,4 +1,3 @@ -import { Apps, AppEvents } from '@rocket.chat/apps'; import { AppsEngineException } from '@rocket.chat/apps-engine/definition/exceptions'; import { Message, Team } from '@rocket.chat/core-services'; import type { IUser } from '@rocket.chat/core-typings'; @@ -6,6 +5,7 @@ import { Subscriptions, Users, Rooms } from '@rocket.chat/models'; import { Meteor } from 'meteor/meteor'; import { RoomMemberActions } from '../../../../definition/IRoomTypeConfig'; +import { AppEvents, Apps } from '../../../../ee/server/apps'; import { callbacks } from '../../../../lib/callbacks'; import { getSubscriptionAutotranslateDefaultConfig } from '../../../../server/lib/getSubscriptionAutotranslateDefaultConfig'; import { roomCoordinator } from '../../../../server/lib/rooms/roomCoordinator'; @@ -54,7 +54,7 @@ export const addUserToRoom = async function ( } try { - await Apps?.triggerEvent(AppEvents.IPreRoomUserJoined, room, userToBeAdded, inviter); + await Apps.triggerEvent(AppEvents.IPreRoomUserJoined, room, userToBeAdded, inviter); } catch (error: any) { if (error.name === AppsEngineException.name) { throw new Meteor.Error('error-app-prevented', error.message); @@ -118,7 +118,7 @@ export const addUserToRoom = async function ( // Keep the current event await callbacks.run('afterJoinRoom', userToBeAdded, room); - void Apps?.triggerEvent(AppEvents.IPostRoomUserJoined, room, userToBeAdded, inviter); + void Apps.triggerEvent(AppEvents.IPostRoomUserJoined, room, userToBeAdded, inviter); }); } diff --git a/apps/meteor/app/lib/server/functions/createDirectRoom.ts b/apps/meteor/app/lib/server/functions/createDirectRoom.ts index cf9d2fdb7042e..b8383875444fe 100644 --- a/apps/meteor/app/lib/server/functions/createDirectRoom.ts +++ b/apps/meteor/app/lib/server/functions/createDirectRoom.ts @@ -1,4 +1,3 @@ -import { AppEvents, Apps } from '@rocket.chat/apps'; import { AppsEngineException } from '@rocket.chat/apps-engine/definition/exceptions'; import type { ISubscriptionExtraData } from '@rocket.chat/core-services'; import type { ICreatedRoom, IRoom, ISubscription, IUser } from '@rocket.chat/core-typings'; @@ -7,6 +6,7 @@ import { Random } from '@rocket.chat/random'; import { Meteor } from 'meteor/meteor'; import type { MatchKeysAndValues } from 'mongodb'; +import { Apps } from '../../../../ee/server/apps'; import { callbacks } from '../../../../lib/callbacks'; import { isTruthy } from '../../../../lib/isTruthy'; import { settings } from '../../../settings/server'; @@ -104,7 +104,7 @@ export async function createDirectRoom( _USERNAMES: usernames, }; - const prevent = await Apps?.triggerEvent(AppEvents.IPreRoomCreatePrevent, tmpRoom).catch((error) => { + const prevent = await Apps.triggerEvent('IPreRoomCreatePrevent', tmpRoom).catch((error) => { if (error.name === AppsEngineException.name) { throw new Meteor.Error('error-app-prevented', error.message); } @@ -116,10 +116,7 @@ export async function createDirectRoom( throw new Meteor.Error('error-app-prevented', 'A Rocket.Chat App prevented the room creation.'); } - const result = await Apps?.triggerEvent( - AppEvents.IPreRoomCreateModify, - await Apps?.triggerEvent(AppEvents.IPreRoomCreateExtend, tmpRoom), - ); + const result = await Apps.triggerEvent('IPreRoomCreateModify', await Apps.triggerEvent('IPreRoomCreateExtend', tmpRoom)); if (typeof result === 'object') { Object.assign(roomInfo, result); @@ -173,7 +170,7 @@ export async function createDirectRoom( await callbacks.run('afterCreateDirectRoom', insertedRoom, { members: roomMembers, creatorId: options?.creator }); - void Apps?.triggerEvent(AppEvents.IPostRoomCreate, insertedRoom); + void Apps.triggerEvent('IPostRoomCreate', insertedRoom); } return { diff --git a/apps/meteor/app/lib/server/functions/createRoom.ts b/apps/meteor/app/lib/server/functions/createRoom.ts index 517d794e68d37..3004dcd445cae 100644 --- a/apps/meteor/app/lib/server/functions/createRoom.ts +++ b/apps/meteor/app/lib/server/functions/createRoom.ts @@ -1,5 +1,4 @@ /* eslint-disable complexity */ -import { AppEvents, Apps } from '@rocket.chat/apps'; import { AppsEngineException } from '@rocket.chat/apps-engine/definition/exceptions'; import { Message, Team } from '@rocket.chat/core-services'; import type { ICreateRoomParams, ISubscriptionExtraData } from '@rocket.chat/core-services'; @@ -7,6 +6,7 @@ import type { ICreatedRoom, IUser, IRoom, RoomType } from '@rocket.chat/core-typ import { Rooms, Subscriptions, Users } from '@rocket.chat/models'; import { Meteor } from 'meteor/meteor'; +import { Apps } from '../../../../ee/server/apps/orchestrator'; import { callbacks } from '../../../../lib/callbacks'; import { beforeCreateRoomCallback } from '../../../../lib/callbacks/beforeCreateRoomCallback'; import { getSubscriptionAutotranslateDefaultConfig } from '../../../../server/lib/getSubscriptionAutotranslateDefaultConfig'; @@ -197,7 +197,7 @@ export const createRoom = async ( _USERNAMES: members, }; - const prevent = await Apps?.triggerEvent(AppEvents.IPreRoomCreatePrevent, tmp).catch((error) => { + const prevent = await Apps.triggerEvent('IPreRoomCreatePrevent', tmp).catch((error) => { if (error.name === AppsEngineException.name) { throw new Meteor.Error('error-app-prevented', error.message); } @@ -209,10 +209,7 @@ export const createRoom = async ( throw new Meteor.Error('error-app-prevented', 'A Rocket.Chat App prevented the room creation.'); } - const eventResult = await Apps?.triggerEvent( - AppEvents.IPreRoomCreateModify, - await Apps.triggerEvent(AppEvents.IPreRoomCreateExtend, tmp), - ); + const eventResult = await Apps.triggerEvent('IPreRoomCreateModify', await Apps.triggerEvent('IPreRoomCreateExtend', tmp)); if (eventResult && typeof eventResult === 'object' && delete eventResult._USERNAMES) { Object.assign(roomProps, eventResult); @@ -244,7 +241,7 @@ export const createRoom = async ( callbacks.runAsync('federation.afterCreateFederatedRoom', room, { owner, originalMemberList: members }); } - void Apps?.triggerEvent(AppEvents.IPostRoomCreate, room); + void Apps.triggerEvent('IPostRoomCreate', room); return { rid: room._id, // backwards compatible inserted: true, diff --git a/apps/meteor/app/lib/server/functions/deleteMessage.ts b/apps/meteor/app/lib/server/functions/deleteMessage.ts index 26677bf37fffa..cd4456b24514c 100644 --- a/apps/meteor/app/lib/server/functions/deleteMessage.ts +++ b/apps/meteor/app/lib/server/functions/deleteMessage.ts @@ -1,9 +1,9 @@ -import { AppEvents, Apps } from '@rocket.chat/apps'; import { api } from '@rocket.chat/core-services'; import type { AtLeast, IMessage, IUser } from '@rocket.chat/core-typings'; import { Messages, Rooms, Uploads, Users, ReadReceipts } from '@rocket.chat/models'; import { Meteor } from 'meteor/meteor'; +import { Apps } from '../../../../ee/server/apps'; import { callbacks } from '../../../../lib/callbacks'; import { broadcastMessageFromData } from '../../../../server/modules/watchers/lib/messages'; import { canDeleteMessageAsync } from '../../../authorization/server/functions/canDeleteMessage'; @@ -29,14 +29,14 @@ export const deleteMessageValidatingPermission = async (message: AtLeast { - const deletedMsg: IMessage | null = await Messages.findOneById(message._id); + const deletedMsg = await Messages.findOneById(message._id); const isThread = (deletedMsg?.tcount || 0) > 0; const keepHistory = settings.get('Message_KeepHistory') || isThread; const showDeletedStatus = settings.get('Message_ShowDeletedStatus') || isThread; const bridges = Apps?.isLoaded() && Apps.getBridges(); if (deletedMsg && bridges) { - const prevent = await bridges.getListenerBridge().messageEvent(AppEvents.IPreMessageDeletePrevent, deletedMsg); + const prevent = await bridges.getListenerBridge().messageEvent('IPreMessageDeletePrevent', deletedMsg); if (prevent) { throw new Meteor.Error('error-app-prevented-deleting', 'A Rocket.Chat App prevented the message deleting.'); } @@ -95,7 +95,7 @@ export async function deleteMessage(message: IMessage, user: IUser): Promise { const originalMessage = originalMsg || (await Messages.findOneById(message._id)); - if (!originalMessage) { - throw new Error('Invalid message ID.'); - } - - let messageData: IMessage = Object.assign({}, originalMessage, message); // For the Rocket.Chat Apps :) if (message && Apps && Apps.isLoaded()) { - const prevent = await Apps.getBridges().getListenerBridge().messageEvent(AppEvents.IPreMessageUpdatedPrevent, messageData); + const appMessage = Object.assign({}, originalMessage, message); + + const prevent = await Apps.getBridges()?.getListenerBridge().messageEvent('IPreMessageUpdatedPrevent', appMessage); if (prevent) { throw new Meteor.Error('error-app-prevented-updating', 'A Rocket.Chat App prevented the message updating.'); } - let result = await Apps.getBridges().getListenerBridge().messageEvent(AppEvents.IPreMessageUpdatedExtend, messageData); - result = await Apps.getBridges().getListenerBridge().messageEvent(AppEvents.IPreMessageUpdatedModify, result); + let result; + result = await Apps.getBridges()?.getListenerBridge().messageEvent('IPreMessageUpdatedExtend', appMessage); + result = await Apps.getBridges()?.getListenerBridge().messageEvent('IPreMessageUpdatedModify', result); if (typeof result === 'object') { - Object.assign(messageData, result); + message = Object.assign(appMessage, result); } } // If we keep history of edits, insert a new message to store history information if (settings.get('Message_KeepHistory')) { - await Messages.cloneAndSaveAsHistoryById(messageData._id, user as Required>); + await Messages.cloneAndSaveAsHistoryById(message._id, user as Required>); } - Object.assign(messageData, { + Object.assign, Omit>(message, { editedAt: new Date(), editedBy: { _id: user._id, @@ -50,16 +48,17 @@ export const updateMessage = async function ( }, }); - parseUrlsInMessage(messageData, previewUrls); + parseUrlsInMessage(message, previewUrls); - const room = await Rooms.findOneById(messageData.rid); + const room = await Rooms.findOneById(message.rid); if (!room) { return; } - messageData = await Message.beforeSave({ message: messageData, room, user }); + // TODO remove type cast + message = await Message.beforeSave({ message: message as IMessage, room, user }); - const { _id, ...editedMessage } = messageData; + const { _id, ...editedMessage } = message; if (!editedMessage.msg) { delete editedMessage.md; @@ -79,7 +78,7 @@ export const updateMessage = async function ( if (Apps?.isLoaded()) { // This returns a promise, but it won't mutate anything about the message // so, we don't really care if it is successful or fails - void Apps.getBridges()?.getListenerBridge().messageEvent(AppEvents.IPostMessageUpdated, messageData); + void Apps.getBridges()?.getListenerBridge().messageEvent('IPostMessageUpdated', message); } setImmediate(async () => { diff --git a/apps/meteor/app/lib/server/methods/deleteUserOwnAccount.ts b/apps/meteor/app/lib/server/methods/deleteUserOwnAccount.ts index f30182def68e8..ed9929622c6d1 100644 --- a/apps/meteor/app/lib/server/methods/deleteUserOwnAccount.ts +++ b/apps/meteor/app/lib/server/methods/deleteUserOwnAccount.ts @@ -1,4 +1,3 @@ -import { Apps, AppEvents } from '@rocket.chat/apps'; import { Users } from '@rocket.chat/models'; import { SHA256 } from '@rocket.chat/sha256'; import type { ServerMethods } from '@rocket.chat/ui-contexts'; @@ -6,6 +5,7 @@ import { Accounts } from 'meteor/accounts-base'; import { check } from 'meteor/check'; import { Meteor } from 'meteor/meteor'; +import { AppEvents, Apps } from '../../../../ee/server/apps/orchestrator'; import { trim } from '../../../../lib/utils/stringUtils'; import { settings } from '../../../settings/server'; import { deleteUser } from '../functions/deleteUser'; @@ -66,7 +66,7 @@ Meteor.methods({ await deleteUser(uid, confirmRelinquish); // App IPostUserDeleted event hook - await Apps?.triggerEvent(AppEvents.IPostUserDeleted, { user }); + await Apps.triggerEvent(AppEvents.IPostUserDeleted, { user }); return true; }, diff --git a/apps/meteor/app/livechat/server/lib/Helper.ts b/apps/meteor/app/livechat/server/lib/Helper.ts index 24cb2dd320cc1..771f50724c389 100644 --- a/apps/meteor/app/livechat/server/lib/Helper.ts +++ b/apps/meteor/app/livechat/server/lib/Helper.ts @@ -1,4 +1,3 @@ -import { Apps, AppEvents } from '@rocket.chat/apps'; import { LivechatTransferEventType } from '@rocket.chat/apps-engine/definition/livechat'; import { api, Message, Omnichannel } from '@rocket.chat/core-services'; import type { @@ -31,6 +30,7 @@ import { import { Match, check } from 'meteor/check'; import { Meteor } from 'meteor/meteor'; +import { Apps, AppEvents } from '../../../../ee/server/apps'; import { callbacks } from '../../../../lib/callbacks'; import { validateEmail as validatorFunc } from '../../../../lib/emailValidator'; import { i18n } from '../../../../server/lib/i18n'; @@ -118,7 +118,7 @@ export const createLivechatRoom = async ( const roomId = (await Rooms.insertOne(room)).insertedId; - void Apps?.triggerEvent(AppEvents.IPostLivechatRoomStarted, room); + void Apps.triggerEvent(AppEvents.IPostLivechatRoomStarted, room); await callbacks.run('livechat.newRoom', room); await sendMessage(guest, { t: 'livechat-started', msg: '', groupable: false }, room); @@ -274,7 +274,7 @@ export const removeAgentFromSubscription = async (rid: string, { _id, username } await Message.saveSystemMessage('ul', rid, username || '', { _id: user._id, username: user.username, name: user.name }); setImmediate(() => { - void Apps?.triggerEvent(AppEvents.IPostLivechatAgentUnassigned, { room, user }); + void Apps.triggerEvent(AppEvents.IPostLivechatAgentUnassigned, { room, user }); }); }; @@ -453,7 +453,7 @@ export const forwardRoomToAgent = async (room: IOmnichannelRoom, transferData: T } setImmediate(() => { - void Apps?.triggerEvent(AppEvents.IPostLivechatRoomTransferred, { + void Apps.triggerEvent(AppEvents.IPostLivechatRoomTransferred, { type: LivechatTransferEventType.AGENT, room: rid, from: oldServedBy?._id, @@ -483,7 +483,7 @@ export const updateChatDepartment = async ({ ]); setImmediate(() => { - void Apps?.triggerEvent(AppEvents.IPostLivechatRoomTransferred, { + void Apps.triggerEvent(AppEvents.IPostLivechatRoomTransferred, { type: LivechatTransferEventType.DEPARTMENT, room: rid, from: oldDepartmentId, diff --git a/apps/meteor/app/livechat/server/lib/LivechatTyped.ts b/apps/meteor/app/livechat/server/lib/LivechatTyped.ts index 8442585d961f9..fb1098db4272d 100644 --- a/apps/meteor/app/livechat/server/lib/LivechatTyped.ts +++ b/apps/meteor/app/livechat/server/lib/LivechatTyped.ts @@ -1,7 +1,6 @@ import dns from 'dns'; import * as util from 'util'; -import { Apps, AppEvents } from '@rocket.chat/apps'; import { Message, VideoConf, api, Omnichannel } from '@rocket.chat/core-services'; import type { IOmnichannelRoom, @@ -44,6 +43,7 @@ import moment from 'moment-timezone'; import type { Filter, FindCursor, UpdateFilter } from 'mongodb'; import UAParser from 'ua-parser-js'; +import { Apps, AppEvents } from '../../../../ee/server/apps'; import { callbacks } from '../../../../lib/callbacks'; import { trim } from '../../../../lib/utils/stringUtils'; import { i18n } from '../../../../server/lib/i18n'; @@ -330,8 +330,8 @@ class LivechatClass { * @deprecated the `AppEvents.ILivechatRoomClosedHandler` event will be removed * in the next major version of the Apps-Engine */ - void Apps?.getBridges()?.getListenerBridge().livechatEvent(AppEvents.ILivechatRoomClosedHandler, newRoom); - void Apps?.getBridges()?.getListenerBridge().livechatEvent(AppEvents.IPostLivechatRoomClosed, newRoom); + void Apps.getBridges()?.getListenerBridge().livechatEvent(AppEvents.ILivechatRoomClosedHandler, newRoom); + void Apps.getBridges()?.getListenerBridge().livechatEvent(AppEvents.IPostLivechatRoomClosed, newRoom); }); if (process.env.TEST_MODE) { await callbacks.run('livechat.closeRoom', { @@ -1420,7 +1420,7 @@ class LivechatClass { const ret = await LivechatVisitors.saveGuestById(_id, updateData); setImmediate(() => { - void Apps?.triggerEvent(AppEvents.IPostLivechatGuestSaved, _id); + void Apps.triggerEvent(AppEvents.IPostLivechatGuestSaved, _id); }); return ret; @@ -1786,7 +1786,7 @@ class LivechatClass { await LivechatRooms.saveRoomById(roomData); setImmediate(() => { - void Apps?.triggerEvent(AppEvents.IPostLivechatRoomSaved, roomData._id); + void Apps.triggerEvent(AppEvents.IPostLivechatRoomSaved, roomData._id); }); if (guestData?.name?.trim().length) { diff --git a/apps/meteor/app/livechat/server/lib/RoutingManager.ts b/apps/meteor/app/livechat/server/lib/RoutingManager.ts index 96621bece8b00..7b85c31f26ac9 100644 --- a/apps/meteor/app/livechat/server/lib/RoutingManager.ts +++ b/apps/meteor/app/livechat/server/lib/RoutingManager.ts @@ -1,4 +1,3 @@ -import { Apps, AppEvents } from '@rocket.chat/apps'; import { Message, Omnichannel } from '@rocket.chat/core-services'; import type { ILivechatInquiryRecord, @@ -17,6 +16,7 @@ import { LivechatInquiry, LivechatRooms, Subscriptions, Rooms, Users } from '@ro import { Match, check } from 'meteor/check'; import { Meteor } from 'meteor/meteor'; +import { Apps, AppEvents } from '../../../../ee/server/apps'; import { callbacks } from '../../../../lib/callbacks'; import { createLivechatSubscription, @@ -172,7 +172,7 @@ export const RoutingManager: Routing = { await dispatchAgentDelegated(rid, agent.agentId); logger.debug(`Agent ${agent.agentId} assigned to inquriy ${inquiry._id}. Instances notified`); - void Apps?.getBridges()?.getListenerBridge().livechatEvent(AppEvents.IPostLivechatAgentAssigned, { room, user }); + void Apps.getBridges()?.getListenerBridge().livechatEvent(AppEvents.IPostLivechatAgentAssigned, { room, user }); return inquiry; }, diff --git a/apps/meteor/app/mailer/server/api.ts b/apps/meteor/app/mailer/server/api.ts index cc2caae74ba6a..b50fdfd26a2a3 100644 --- a/apps/meteor/app/mailer/server/api.ts +++ b/apps/meteor/app/mailer/server/api.ts @@ -1,4 +1,3 @@ -import { AppEvents, Apps } from '@rocket.chat/apps'; import type { ISetting } from '@rocket.chat/core-typings'; import { Settings } from '@rocket.chat/models'; import { escapeHTML } from '@rocket.chat/string-helpers'; @@ -8,6 +7,7 @@ import { Meteor } from 'meteor/meteor'; import stripHtml from 'string-strip-html'; import _ from 'underscore'; +import { Apps } from '../../../ee/server/apps'; import { validateEmail } from '../../../lib/emailValidator'; import { strLeft, strRightBack } from '../../../lib/utils/stringUtils'; import { i18n } from '../../../server/lib/i18n'; @@ -170,7 +170,7 @@ export const sendNoWrap = async ({ const email = { to, from, replyTo, subject, html, text, headers }; - const eventResult = await Apps?.triggerEvent(AppEvents.IPreEmailSent, { email }); + const eventResult = await Apps.triggerEvent('IPreEmailSent', { email }); setImmediate(() => Email.sendAsync(eventResult || email).catch((e) => console.error(e))); }; diff --git a/apps/meteor/app/message-pin/server/pinMessage.ts b/apps/meteor/app/message-pin/server/pinMessage.ts index 4887e36031228..1ed0a172028bc 100644 --- a/apps/meteor/app/message-pin/server/pinMessage.ts +++ b/apps/meteor/app/message-pin/server/pinMessage.ts @@ -1,4 +1,3 @@ -import { Apps, AppEvents } from '@rocket.chat/apps'; import { Message } from '@rocket.chat/core-services'; import { isQuoteAttachment, isRegisterUser } from '@rocket.chat/core-typings'; import type { IMessage, MessageAttachment, MessageQuoteAttachment } from '@rocket.chat/core-typings'; @@ -7,6 +6,7 @@ import type { ServerMethods } from '@rocket.chat/ui-contexts'; import { check } from 'meteor/check'; import { Meteor } from 'meteor/meteor'; +import { Apps, AppEvents } from '../../../ee/server/apps/orchestrator'; import { isTruthy } from '../../../lib/isTruthy'; import { broadcastMessageFromData } from '../../../server/modules/watchers/lib/messages'; import { canAccessRoomAsync, roomAccessAttributes } from '../../authorization/server'; @@ -129,7 +129,7 @@ Meteor.methods({ } // App IPostMessagePinned event hook - await Apps?.triggerEvent(AppEvents.IPostMessagePinned, originalMessage, await Meteor.userAsync(), originalMessage.pinned); + await Apps.triggerEvent(AppEvents.IPostMessagePinned, originalMessage, await Meteor.userAsync(), originalMessage.pinned); const msgId = await Message.saveSystemMessage('message_pinned', originalMessage.rid, '', me, { attachments: [ @@ -216,7 +216,7 @@ Meteor.methods({ } // App IPostMessagePinned event hook - await Apps?.triggerEvent(AppEvents.IPostMessagePinned, originalMessage, await Meteor.userAsync(), originalMessage.pinned); + await Apps.triggerEvent(AppEvents.IPostMessagePinned, originalMessage, await Meteor.userAsync(), originalMessage.pinned); await Messages.setPinnedByIdAndUserId(originalMessage._id, originalMessage.pinnedBy, originalMessage.pinned); if (settings.get('Message_Read_Receipt_Store_Users')) { diff --git a/apps/meteor/app/message-star/server/starMessage.ts b/apps/meteor/app/message-star/server/starMessage.ts index 9f8ba75c45365..8f025d9200571 100644 --- a/apps/meteor/app/message-star/server/starMessage.ts +++ b/apps/meteor/app/message-star/server/starMessage.ts @@ -1,9 +1,9 @@ -import { Apps, AppEvents } from '@rocket.chat/apps'; import type { IMessage } from '@rocket.chat/core-typings'; import { Messages, Subscriptions, Rooms } from '@rocket.chat/models'; import type { ServerMethods } from '@rocket.chat/ui-contexts'; import { Meteor } from 'meteor/meteor'; +import { Apps, AppEvents } from '../../../ee/server/apps/orchestrator'; import { broadcastMessageFromData } from '../../../server/modules/watchers/lib/messages'; import { canAccessRoomAsync, roomAccessAttributes } from '../../authorization/server'; import { isTheLastMessage } from '../../lib/server/functions/isTheLastMessage'; @@ -57,7 +57,7 @@ Meteor.methods({ await Rooms.updateLastMessageStar(room._id, uid, message.starred); } - await Apps?.triggerEvent(AppEvents.IPostMessageStarred, message, await Meteor.userAsync(), message.starred); + await Apps.triggerEvent(AppEvents.IPostMessageStarred, message, await Meteor.userAsync(), message.starred); await Messages.updateUserStarById(message._id, uid, message.starred); diff --git a/apps/meteor/app/reactions/server/setReaction.ts b/apps/meteor/app/reactions/server/setReaction.ts index ed2271a5d4d0a..27fe4d36a053f 100644 --- a/apps/meteor/app/reactions/server/setReaction.ts +++ b/apps/meteor/app/reactions/server/setReaction.ts @@ -1,4 +1,3 @@ -import { Apps, AppEvents } from '@rocket.chat/apps'; import { api } from '@rocket.chat/core-services'; import type { IMessage, IRoom, IUser } from '@rocket.chat/core-typings'; import { Messages, EmojiCustom, Rooms, Users } from '@rocket.chat/models'; @@ -6,6 +5,7 @@ import type { ServerMethods } from '@rocket.chat/ui-contexts'; import { Meteor } from 'meteor/meteor'; import _ from 'underscore'; +import { AppEvents, Apps } from '../../../ee/server/apps/orchestrator'; import { callbacks } from '../../../lib/callbacks'; import { i18n } from '../../../server/lib/i18n'; import { broadcastMessageFromData } from '../../../server/modules/watchers/lib/messages'; @@ -106,7 +106,7 @@ async function setReaction(room: IRoom, user: IUser, message: IMessage, reaction isReacted = true; } - await Apps?.triggerEvent(AppEvents.IPostMessageReacted, message, user, reaction, isReacted); + await Apps.triggerEvent(AppEvents.IPostMessageReacted, message, user, reaction, isReacted); void broadcastMessageFromData({ id: message._id, diff --git a/apps/meteor/app/statistics/server/lib/getAppsStatistics.js b/apps/meteor/app/statistics/server/lib/getAppsStatistics.js index 652686e6715c8..6337b287506a1 100644 --- a/apps/meteor/app/statistics/server/lib/getAppsStatistics.js +++ b/apps/meteor/app/statistics/server/lib/getAppsStatistics.js @@ -1,18 +1,17 @@ -import { Apps } from '@rocket.chat/apps'; import { AppStatus } from '@rocket.chat/apps-engine/definition/AppStatus'; +import { Apps } from '../../../../ee/server/apps'; import { Info } from '../../../utils/rocketchat.info'; export function getAppsStatistics() { return { engineVersion: Info.marketplaceApiVersion, - totalInstalled: (Apps?.isInitialized() && Apps.getManager().get().length) ?? 0, - totalActive: (Apps?.isInitialized() && Apps.getManager().get({ enabled: true }).length) ?? 0, + totalInstalled: Apps.isInitialized() && Apps.getManager().get().length, + totalActive: Apps.isInitialized() && Apps.getManager().get({ enabled: true }).length, totalFailed: - (Apps?.isInitialized() && - Apps.getManager() - .get({ disabled: true }) - .filter(({ app: { status } }) => status !== AppStatus.MANUALLY_DISABLED).length) ?? - 0, + Apps.isInitialized() && + Apps.getManager() + .get({ disabled: true }) + .filter(({ app: { status } }) => status !== AppStatus.MANUALLY_DISABLED).length, }; } diff --git a/apps/meteor/app/threads/server/methods/followMessage.ts b/apps/meteor/app/threads/server/methods/followMessage.ts index f6bae69b1aaaa..cede3dda33a73 100644 --- a/apps/meteor/app/threads/server/methods/followMessage.ts +++ b/apps/meteor/app/threads/server/methods/followMessage.ts @@ -1,10 +1,10 @@ -import { Apps, AppEvents } from '@rocket.chat/apps'; import type { IMessage } from '@rocket.chat/core-typings'; import { Messages } from '@rocket.chat/models'; import type { ServerMethods } from '@rocket.chat/ui-contexts'; import { check } from 'meteor/check'; import { Meteor } from 'meteor/meteor'; +import { Apps, AppEvents } from '../../../../ee/server/apps/orchestrator'; import { canAccessRoomIdAsync } from '../../../authorization/server/functions/canAccessRoom'; import { RateLimiter } from '../../../lib/server'; import { settings } from '../../../settings/server'; @@ -44,7 +44,7 @@ Meteor.methods({ const followResult = await follow({ tmid: message.tmid || message._id, uid }); const isFollowed = true; - await Apps?.triggerEvent(AppEvents.IPostMessageFollowed, message, await Meteor.userAsync(), isFollowed); + await Apps.triggerEvent(AppEvents.IPostMessageFollowed, message, await Meteor.userAsync(), isFollowed); return followResult; }, diff --git a/apps/meteor/app/threads/server/methods/unfollowMessage.ts b/apps/meteor/app/threads/server/methods/unfollowMessage.ts index b50c26508ebc7..c5dad12331734 100644 --- a/apps/meteor/app/threads/server/methods/unfollowMessage.ts +++ b/apps/meteor/app/threads/server/methods/unfollowMessage.ts @@ -1,10 +1,10 @@ -import { Apps, AppEvents } from '@rocket.chat/apps'; import type { IMessage } from '@rocket.chat/core-typings'; import { Messages } from '@rocket.chat/models'; import type { ServerMethods } from '@rocket.chat/ui-contexts'; import { check } from 'meteor/check'; import { Meteor } from 'meteor/meteor'; +import { Apps, AppEvents } from '../../../../ee/server/apps/orchestrator'; import { canAccessRoomIdAsync } from '../../../authorization/server/functions/canAccessRoom'; import { RateLimiter } from '../../../lib/server'; import { settings } from '../../../settings/server'; @@ -44,7 +44,7 @@ Meteor.methods({ const unfollowResult = await unfollow({ rid: message.rid, tmid: message.tmid || message._id, uid }); const isFollowed = false; - await Apps?.triggerEvent(AppEvents.IPostMessageFollowed, message, await Meteor.userAsync(), isFollowed); + await Apps.triggerEvent(AppEvents.IPostMessageFollowed, message, await Meteor.userAsync(), isFollowed); return unfollowResult; }, diff --git a/apps/meteor/ee/server/apps/index.ts b/apps/meteor/ee/server/apps/index.ts index 0306575e00f1c..35f7c2cc041fd 100644 --- a/apps/meteor/ee/server/apps/index.ts +++ b/apps/meteor/ee/server/apps/index.ts @@ -1,4 +1,4 @@ import './cron'; import './appRequestsCron'; -export { Apps } from './orchestrator'; +export { Apps, AppEvents } from './orchestrator'; diff --git a/apps/meteor/ee/server/apps/orchestrator.js b/apps/meteor/ee/server/apps/orchestrator.js index 37c31e890e894..84f9cb1372f34 100644 --- a/apps/meteor/ee/server/apps/orchestrator.js +++ b/apps/meteor/ee/server/apps/orchestrator.js @@ -1,5 +1,5 @@ -import { registerOrchestrator } from '@rocket.chat/apps'; import { EssentialAppDisabledException } from '@rocket.chat/apps-engine/definition/exceptions'; +import { AppInterface } from '@rocket.chat/apps-engine/definition/metadata'; import { AppManager } from '@rocket.chat/apps-engine/server/AppManager'; import { Logger } from '@rocket.chat/logger'; import { AppLogs, Apps as AppsModel, AppsPersistence } from '@rocket.chat/models'; @@ -249,8 +249,8 @@ export class AppServerOrchestrator { } } +export const AppEvents = AppInterface; export const Apps = new AppServerOrchestrator(); -registerOrchestrator(Apps); settings.watch('Apps_Framework_Source_Package_Storage_Type', (value) => { if (!Apps.isInitialized()) { diff --git a/apps/meteor/server/lib/moderation/reportMessage.ts b/apps/meteor/server/lib/moderation/reportMessage.ts index 710ea6e1b685c..be8b917fd6f56 100644 --- a/apps/meteor/server/lib/moderation/reportMessage.ts +++ b/apps/meteor/server/lib/moderation/reportMessage.ts @@ -1,8 +1,8 @@ -import { Apps, AppEvents } from '@rocket.chat/apps'; import type { IMessage, IUser } from '@rocket.chat/core-typings'; import { Messages, ModerationReports, Rooms, Users } from '@rocket.chat/models'; import { canAccessRoomAsync } from '../../../app/authorization/server/functions/canAccessRoom'; +import { AppEvents, Apps } from '../../../ee/server/apps'; export const reportMessage = async (messageId: IMessage['_id'], description: string, uid: IUser['_id']) => { if (!uid) { @@ -49,7 +49,7 @@ export const reportMessage = async (messageId: IMessage['_id'], description: str await ModerationReports.createWithMessageDescriptionAndUserId(message, description, roomInfo, reportedBy); - await Apps?.triggerEvent(AppEvents.IPostMessageReported, message, user, description); + await Apps.triggerEvent(AppEvents.IPostMessageReported, message, user, description); return true; }; diff --git a/apps/meteor/server/methods/deleteUser.ts b/apps/meteor/server/methods/deleteUser.ts index 8762cfab2437d..4dafad7a3a0cf 100644 --- a/apps/meteor/server/methods/deleteUser.ts +++ b/apps/meteor/server/methods/deleteUser.ts @@ -1,4 +1,3 @@ -import { Apps, AppEvents } from '@rocket.chat/apps'; import type { IUser } from '@rocket.chat/core-typings'; import { Users } from '@rocket.chat/models'; import type { ServerMethods } from '@rocket.chat/ui-contexts'; @@ -7,6 +6,7 @@ import { Meteor } from 'meteor/meteor'; import { hasPermissionAsync } from '../../app/authorization/server/functions/hasPermission'; import { deleteUser } from '../../app/lib/server/functions/deleteUser'; +import { AppEvents, Apps } from '../../ee/server/apps/orchestrator'; declare module '@rocket.chat/ui-contexts' { // eslint-disable-next-line @typescript-eslint/naming-convention @@ -52,7 +52,7 @@ Meteor.methods({ await deleteUser(userId, confirmRelinquish, uid); // App IPostUserDeleted event hook - await Apps?.triggerEvent(AppEvents.IPostUserDeleted, { user, performedBy: await Meteor.userAsync() }); + await Apps.triggerEvent(AppEvents.IPostUserDeleted, { user, performedBy: await Meteor.userAsync() }); return true; }, diff --git a/apps/meteor/server/methods/eraseRoom.ts b/apps/meteor/server/methods/eraseRoom.ts index 687b9ad669928..177b3c23bb9c3 100644 --- a/apps/meteor/server/methods/eraseRoom.ts +++ b/apps/meteor/server/methods/eraseRoom.ts @@ -1,4 +1,3 @@ -import { AppEvents, Apps } from '@rocket.chat/apps'; import { Message, Team } from '@rocket.chat/core-services'; import { Rooms } from '@rocket.chat/models'; import type { ServerMethods } from '@rocket.chat/ui-contexts'; @@ -8,6 +7,7 @@ import { Meteor } from 'meteor/meteor'; import { hasPermissionAsync } from '../../app/authorization/server/functions/hasPermission'; import { deleteRoom } from '../../app/lib/server/functions/deleteRoom'; import { methodDeprecationLogger } from '../../app/lib/server/lib/deprecationWarningLogger'; +import { Apps } from '../../ee/server/apps'; import { roomCoordinator } from '../lib/rooms/roomCoordinator'; export async function eraseRoom(rid: string, uid: string): Promise { @@ -36,7 +36,7 @@ export async function eraseRoom(rid: string, uid: string): Promise { } if (Apps?.isLoaded()) { - const prevent = await Apps.getBridges()?.getListenerBridge().roomEvent(AppEvents.IPreRoomDeletePrevent, room); + const prevent = await Apps.getBridges()?.getListenerBridge().roomEvent('IPreRoomDeletePrevent', room); if (prevent) { throw new Meteor.Error('error-app-prevented-deleting', 'A Rocket.Chat App prevented the room erasing.'); } @@ -54,7 +54,7 @@ export async function eraseRoom(rid: string, uid: string): Promise { } if (Apps?.isLoaded()) { - void Apps.getBridges()?.getListenerBridge().roomEvent(AppEvents.IPostRoomDeleted, room); + void Apps.getBridges()?.getListenerBridge().roomEvent('IPostRoomDeleted', room); } } diff --git a/apps/meteor/server/methods/logoutCleanUp.ts b/apps/meteor/server/methods/logoutCleanUp.ts index 502cad3c5fbf9..9b9af5356af5b 100644 --- a/apps/meteor/server/methods/logoutCleanUp.ts +++ b/apps/meteor/server/methods/logoutCleanUp.ts @@ -1,9 +1,9 @@ -import { AppEvents, Apps } from '@rocket.chat/apps'; import type { IUser } from '@rocket.chat/core-typings'; import type { ServerMethods } from '@rocket.chat/ui-contexts'; import { check } from 'meteor/check'; import { Meteor } from 'meteor/meteor'; +import { AppEvents, Apps } from '../../ee/server/apps/orchestrator'; import { afterLogoutCleanUpCallback } from '../../lib/callbacks/afterLogoutCleanUpCallback'; declare module '@rocket.chat/ui-contexts' { @@ -22,6 +22,6 @@ Meteor.methods({ }); // App IPostUserLogout event hook - await Apps?.triggerEvent(AppEvents.IPostUserLoggedOut, user); + await Apps.triggerEvent(AppEvents.IPostUserLoggedOut, user); }, }); diff --git a/apps/meteor/server/methods/reportMessage.ts b/apps/meteor/server/methods/reportMessage.ts index 44087dad04245..94d6fc1fd315f 100644 --- a/apps/meteor/server/methods/reportMessage.ts +++ b/apps/meteor/server/methods/reportMessage.ts @@ -1,4 +1,3 @@ -import { Apps, AppEvents } from '@rocket.chat/apps'; import type { IMessage } from '@rocket.chat/core-typings'; import { ModerationReports, Rooms, Users, Messages } from '@rocket.chat/models'; import type { ServerMethods } from '@rocket.chat/ui-contexts'; @@ -7,6 +6,7 @@ import { Meteor } from 'meteor/meteor'; import { canAccessRoomAsync } from '../../app/authorization/server/functions/canAccessRoom'; import { methodDeprecationLogger } from '../../app/lib/server/lib/deprecationWarningLogger'; +import { AppEvents, Apps } from '../../ee/server/apps'; declare module '@rocket.chat/ui-contexts' { // eslint-disable-next-line @typescript-eslint/naming-convention @@ -77,7 +77,7 @@ Meteor.methods({ await ModerationReports.createWithMessageDescriptionAndUserId(message, description, roomInfo, reportedBy); - await Apps?.triggerEvent(AppEvents.IPostMessageReported, message, await Meteor.userAsync(), description); + await Apps.triggerEvent(AppEvents.IPostMessageReported, message, await Meteor.userAsync(), description); return true; }, diff --git a/apps/meteor/server/methods/saveUserProfile.ts b/apps/meteor/server/methods/saveUserProfile.ts index 695742977ad33..5bfbba5b1b3fc 100644 --- a/apps/meteor/server/methods/saveUserProfile.ts +++ b/apps/meteor/server/methods/saveUserProfile.ts @@ -1,4 +1,3 @@ -import { Apps, AppEvents } from '@rocket.chat/apps'; import type { UserStatus } from '@rocket.chat/core-typings'; import { Users } from '@rocket.chat/models'; import type { ServerMethods } from '@rocket.chat/ui-contexts'; @@ -13,6 +12,7 @@ import { saveUserIdentity } from '../../app/lib/server/functions/saveUserIdentit import { passwordPolicy } from '../../app/lib/server/lib/passwordPolicy'; import { settings as rcSettings } from '../../app/settings/server'; import { setUserStatusMethod } from '../../app/user-status/server/methods/setUserStatus'; +import { AppEvents, Apps } from '../../ee/server/apps/orchestrator'; import { compareUserPassword } from '../lib/compareUserPassword'; import { compareUserPasswordHistory } from '../lib/compareUserPasswordHistory'; @@ -156,7 +156,7 @@ async function saveUserProfile( // App IPostUserUpdated event hook const updatedUser = await Users.findOneById(this.userId); - await Apps?.triggerEvent(AppEvents.IPostUserUpdated, { user: updatedUser, previousUser: user }); + await Apps.triggerEvent(AppEvents.IPostUserUpdated, { user: updatedUser, previousUser: user }); return true; } diff --git a/apps/meteor/server/services/apps-engine/service.ts b/apps/meteor/server/services/apps-engine/service.ts index 7e36a937e6a6f..e72ce3cbce0a0 100644 --- a/apps/meteor/server/services/apps-engine/service.ts +++ b/apps/meteor/server/services/apps-engine/service.ts @@ -1,4 +1,3 @@ -import { Apps, AppEvents } from '@rocket.chat/apps'; import type { AppStatus } from '@rocket.chat/apps-engine/definition/AppStatus'; import { AppStatusUtils } from '@rocket.chat/apps-engine/definition/AppStatus'; import type { IAppInfo } from '@rocket.chat/apps-engine/definition/metadata'; @@ -7,6 +6,7 @@ import type { IAppStorageItem } from '@rocket.chat/apps-engine/server/storage'; import type { IAppsEngineService } from '@rocket.chat/core-services'; import { ServiceClassInternal } from '@rocket.chat/core-services'; +import { Apps, AppEvents } from '../../../ee/server/apps/orchestrator'; import { SystemLogger } from '../../lib/logger/system'; export class AppsEngineService extends ServiceClassInternal implements IAppsEngineService { @@ -16,7 +16,7 @@ export class AppsEngineService extends ServiceClassInternal implements IAppsEngi super(); this.onEvent('presence.status', async ({ user, previousStatus }): Promise => { - await Apps?.triggerEvent(AppEvents.IPostUserStatusChanged, { + await Apps.triggerEvent(AppEvents.IPostUserStatusChanged, { user, currentStatus: user.status, previousStatus, @@ -24,70 +24,68 @@ export class AppsEngineService extends ServiceClassInternal implements IAppsEngi }); this.onEvent('apps.added', async (appId: string): Promise => { - Apps?.getRocketChatLogger().debug(`"apps.added" event received for app "${appId}"`); + Apps.getRocketChatLogger().debug(`"apps.added" event received for app "${appId}"`); // if the app already exists in this instance, don't load it again - const app = Apps?.getManager()?.getOneById(appId); + const app = Apps.getManager()?.getOneById(appId); if (app) { - Apps?.getRocketChatLogger().info(`"apps.added" event received for app "${appId}", but it already exists in this instance`); + Apps.getRocketChatLogger().info(`"apps.added" event received for app "${appId}", but it already exists in this instance`); return; } - await Apps?.getManager()?.addLocal(appId); + await Apps.getManager()?.addLocal(appId); }); this.onEvent('apps.removed', async (appId: string): Promise => { - Apps?.getRocketChatLogger().debug(`"apps.removed" event received for app "${appId}"`); - const app = Apps?.getManager()?.getOneById(appId); + Apps.getRocketChatLogger().debug(`"apps.removed" event received for app "${appId}"`); + const app = Apps.getManager()?.getOneById(appId); if (!app) { - Apps?.getRocketChatLogger().info(`"apps.removed" event received for app "${appId}", but it couldn't be found in this instance`); + Apps.getRocketChatLogger().info(`"apps.removed" event received for app "${appId}", but it couldn't be found in this instance`); return; } - await Apps?.getManager()?.removeLocal(appId); + await Apps.getManager()?.removeLocal(appId); }); this.onEvent('apps.updated', async (appId: string): Promise => { - Apps?.getRocketChatLogger().debug(`"apps.updated" event received for app "${appId}"`); - const storageItem = await Apps?.getStorage()?.retrieveOne(appId); + Apps.getRocketChatLogger().debug(`"apps.updated" event received for app "${appId}"`); + const storageItem = await Apps.getStorage()?.retrieveOne(appId); if (!storageItem) { - Apps?.getRocketChatLogger().info(`"apps.updated" event received for app "${appId}", but it couldn't be found in the storage`); + Apps.getRocketChatLogger().info(`"apps.updated" event received for app "${appId}", but it couldn't be found in the storage`); return; } - const appPackage = await Apps?.getAppSourceStorage()?.fetch(storageItem); + const appPackage = await Apps.getAppSourceStorage()?.fetch(storageItem); if (!appPackage) { return; } - await Apps?.getManager()?.updateLocal(storageItem, appPackage); + await Apps.getManager()?.updateLocal(storageItem, appPackage); }); this.onEvent('apps.statusUpdate', async (appId: string, status: AppStatus): Promise => { - Apps?.getRocketChatLogger().debug(`"apps.statusUpdate" event received for app "${appId}" with status "${status}"`); - const app = Apps?.getManager()?.getOneById(appId); + Apps.getRocketChatLogger().debug(`"apps.statusUpdate" event received for app "${appId}" with status "${status}"`); + const app = Apps.getManager()?.getOneById(appId); if (!app) { - Apps?.getRocketChatLogger().info( - `"apps.statusUpdate" event received for app "${appId}", but it couldn't be found in this instance`, - ); + Apps.getRocketChatLogger().info(`"apps.statusUpdate" event received for app "${appId}", but it couldn't be found in this instance`); return; } if (app.getStatus() === status) { - Apps?.getRocketChatLogger().info(`"apps.statusUpdate" event received for app "${appId}", but the status is the same`); + Apps.getRocketChatLogger().info(`"apps.statusUpdate" event received for app "${appId}", but the status is the same`); return; } if (AppStatusUtils.isEnabled(status)) { - await Apps?.getManager()?.enable(appId).catch(SystemLogger.error); + await Apps.getManager()?.enable(appId).catch(SystemLogger.error); } else if (AppStatusUtils.isDisabled(status)) { - await Apps?.getManager()?.disable(appId, status, true).catch(SystemLogger.error); + await Apps.getManager()?.disable(appId, status, true).catch(SystemLogger.error); } }); this.onEvent('apps.settingUpdated', async (appId: string, setting): Promise => { - Apps?.getRocketChatLogger().debug(`"apps.settingUpdated" event received for app "${appId}"`, { setting }); - const app = Apps?.getManager()?.getOneById(appId); + Apps.getRocketChatLogger().debug(`"apps.settingUpdated" event received for app "${appId}"`, { setting }); + const app = Apps.getManager()?.getOneById(appId); const oldSetting = app?.getStorageItem().settings[setting.id].value; // avoid updating the setting if the value is the same, @@ -96,30 +94,30 @@ export class AppsEngineService extends ServiceClassInternal implements IAppsEngi // so we need to convert it to JSON stringified to compare it if (JSON.stringify(oldSetting) === JSON.stringify(setting.value)) { - Apps?.getRocketChatLogger().info( + Apps.getRocketChatLogger().info( `"apps.settingUpdated" event received for setting ${setting.id} of app "${appId}", but the setting value is the same`, ); return; } - await Apps?.getManager() + await Apps.getManager() ?.getSettingsManager() .updateAppSetting(appId, setting as any); }); } isInitialized(): boolean { - return Boolean(Apps?.isInitialized()); + return Apps.isInitialized(); } async getApps(query: IGetAppsFilter): Promise { - return Apps?.getManager() + return Apps.getManager() ?.get(query) .map((app) => app.getApp().getInfo()); } async getAppStorageItemById(appId: string): Promise { - const app = Apps?.getManager()?.getOneById(appId); + const app = Apps.getManager()?.getOneById(appId); if (!app) { return; diff --git a/apps/meteor/server/services/video-conference/service.ts b/apps/meteor/server/services/video-conference/service.ts index 87fe279d0d94e..90a7a33024278 100644 --- a/apps/meteor/server/services/video-conference/service.ts +++ b/apps/meteor/server/services/video-conference/service.ts @@ -1,4 +1,3 @@ -import { Apps } from '@rocket.chat/apps'; import type { AppVideoConfProviderManager } from '@rocket.chat/apps-engine/server/managers'; import type { IVideoConfService, VideoConferenceJoinOptions } from '@rocket.chat/core-services'; import { api, ServiceClassInternal } from '@rocket.chat/core-services'; @@ -42,6 +41,7 @@ import { settings } from '../../../app/settings/server'; import { updateCounter } from '../../../app/statistics/server/functions/updateStatsCounter'; import { getUserAvatarURL } from '../../../app/utils/server/getUserAvatarURL'; import { getUserPreference } from '../../../app/utils/server/lib/getUserPreference'; +import { Apps } from '../../../ee/server/apps'; import { callbacks } from '../../../lib/callbacks'; import { availabilityErrors } from '../../../lib/videoConference/constants'; import { readSecondaryPreferred } from '../../database/readSecondaryPreferred'; @@ -832,7 +832,7 @@ export class VideoConfService extends ServiceClassInternal implements IVideoConf throw new Error('apps-engine-not-loaded'); } - const manager = Apps?.getManager()?.getVideoConfProviderManager(); + const manager = Apps.getManager()?.getVideoConfProviderManager(); if (!manager) { throw new Error(availabilityErrors.NO_APP); } diff --git a/apps/meteor/server/startup/migrations/v291.ts b/apps/meteor/server/startup/migrations/v291.ts index f4fdbb743447a..8923f3b282c3c 100644 --- a/apps/meteor/server/startup/migrations/v291.ts +++ b/apps/meteor/server/startup/migrations/v291.ts @@ -1,7 +1,8 @@ -import { Apps, type AppMetadataStorage } from '@rocket.chat/apps'; import type { IAppStorageItem } from '@rocket.chat/apps-engine/server/storage'; import { Settings } from '@rocket.chat/models'; +import { Apps } from '../../../ee/server/apps'; +import type { AppRealStorage } from '../../../ee/server/apps/storage'; import { addMigration } from '../../lib/migrations'; addMigration({ @@ -12,17 +13,13 @@ addMigration({ await Settings.removeById('Apps_Framework_Development_Mode'); await Settings.removeById('Apps_Framework_enabled'); - if (!Apps) { - throw new Error('Apps Orchestrator not registered.'); - } - Apps.initialize(); - const appsStorage = Apps.getStorage(); + const appsStorage = Apps.getStorage() as AppRealStorage; const apps = await appsStorage.retrieveAll(); - const promises: Array> = []; + const promises: Array> = []; apps.forEach((app) => promises.push( diff --git a/apps/meteor/server/startup/migrations/v292.ts b/apps/meteor/server/startup/migrations/v292.ts index beec6967a9044..7f590f4038e24 100644 --- a/apps/meteor/server/startup/migrations/v292.ts +++ b/apps/meteor/server/startup/migrations/v292.ts @@ -1,7 +1,7 @@ -import { Apps } from '@rocket.chat/apps'; import type { AppSignatureManager } from '@rocket.chat/apps-engine/server/managers/AppSignatureManager'; import type { IAppStorageItem } from '@rocket.chat/apps-engine/server/storage'; +import { Apps } from '../../../ee/server/apps'; import type { AppRealStorage } from '../../../ee/server/apps/storage'; import { addMigration } from '../../lib/migrations'; @@ -9,10 +9,6 @@ addMigration({ version: 292, name: 'Add checksum signature to existing apps', async up() { - if (!Apps) { - throw new Error('Apps Orchestrator not registered.'); - } - Apps.initialize(); const sigMan = Apps.getManager()?.getSignatureManager() as AppSignatureManager; diff --git a/apps/meteor/server/startup/migrations/v294.ts b/apps/meteor/server/startup/migrations/v294.ts index 832043740f89b..abcb20d079eca 100644 --- a/apps/meteor/server/startup/migrations/v294.ts +++ b/apps/meteor/server/startup/migrations/v294.ts @@ -1,17 +1,13 @@ -import { Apps } from '@rocket.chat/apps'; import type { AppSignatureManager } from '@rocket.chat/apps-engine/server/managers/AppSignatureManager'; import type { IAppStorageItem } from '@rocket.chat/apps-engine/server/storage'; +import { Apps } from '../../../ee/server/apps'; import type { AppRealStorage } from '../../../ee/server/apps/storage'; import { addMigration } from '../../lib/migrations'; addMigration({ version: 294, async up() { - if (!Apps) { - throw new Error('Apps Orchestrator not registered.'); - } - Apps.initialize(); const sigMan = Apps.getManager()?.getSignatureManager() as AppSignatureManager; diff --git a/packages/apps/src/AppsEngine.ts b/packages/apps/src/AppsEngine.ts index 856bc12537905..117e93c0ec2f7 100644 --- a/packages/apps/src/AppsEngine.ts +++ b/packages/apps/src/AppsEngine.ts @@ -8,7 +8,6 @@ export type { IVisitorPhone as IAppsVisitorPhone, } from '@rocket.chat/apps-engine/definition/livechat'; export type { IMessage as IAppsMessage } from '@rocket.chat/apps-engine/definition/messages'; -export { AppInterface as AppEvents } from '@rocket.chat/apps-engine/definition/metadata'; export type { IUser as IAppsUser } from '@rocket.chat/apps-engine/definition/users'; export type { IRole as IAppsRole } from '@rocket.chat/apps-engine/definition/roles'; export type { IRoom as IAppsRoom } from '@rocket.chat/apps-engine/definition/rooms'; @@ -19,5 +18,3 @@ export type { VideoConference as AppsVideoConference, } from '@rocket.chat/apps-engine/definition/videoConferences'; export { AppManager } from '@rocket.chat/apps-engine/server/AppManager'; -export { AppBridges } from '@rocket.chat/apps-engine/server/bridges'; -export { AppMetadataStorage } from '@rocket.chat/apps-engine/server/storage'; diff --git a/packages/apps/src/IAppServerOrchestrator.ts b/packages/apps/src/IAppServerOrchestrator.ts index 2f1f7db5d4b50..dbfc5aee7a20d 100644 --- a/packages/apps/src/IAppServerOrchestrator.ts +++ b/packages/apps/src/IAppServerOrchestrator.ts @@ -1,16 +1,12 @@ import type { AppManager } from '@rocket.chat/apps-engine/server/AppManager'; -import type { AppSourceStorage } from '@rocket.chat/apps-engine/server/storage'; import type { Logger } from '@rocket.chat/logger'; import type { IAppsPersistenceModel } from '@rocket.chat/model-typings'; -import type { AppBridges, AppEvents, AppMetadataStorage } from './AppsEngine'; import type { IAppServerNotifier } from './IAppServerNotifier'; import type { IAppConvertersMap } from './converters'; export interface IAppServerOrchestrator { initialize(): void; - isInitialized(): boolean; - isLoaded(): boolean; getNotifier(): IAppServerNotifier; isDebugging(): boolean; debugLog(...args: any[]): void; @@ -18,8 +14,4 @@ export interface IAppServerOrchestrator { getConverters(): IAppConvertersMap; getPersistenceModel(): IAppsPersistenceModel; getRocketChatLogger(): Logger; - triggerEvent(event: AppEvents, ...payload: any[]): Promise; - getBridges(): AppBridges; - getStorage(): AppMetadataStorage; - getAppSourceStorage(): AppSourceStorage; } diff --git a/packages/apps/src/bridges/IListenerBridge.ts b/packages/apps/src/bridges/IListenerBridge.ts deleted file mode 100644 index faf34118cd30b..0000000000000 --- a/packages/apps/src/bridges/IListenerBridge.ts +++ /dev/null @@ -1,48 +0,0 @@ -import type { IMessage, IRoom, IUser, ILivechatDepartment, ILivechatVisitor, IOmnichannelRoom } from '@rocket.chat/core-typings'; - -import type { AppEvents } from '../AppsEngine'; - -declare module '@rocket.chat/apps-engine/server/bridges' { - interface IListenerBridge { - messageEvent(int: 'IPostMessageDeleted', message: IMessage, userDeleted: IUser): Promise; - messageEvent(int: 'IPostMessageReacted', message: IMessage, userReacted: IUser, reaction: string, isReacted: boolean): Promise; - messageEvent(int: 'IPostMessageFollowed', message: IMessage, userFollowed: IUser, isFollowed: boolean): Promise; - messageEvent(int: 'IPostMessagePinned', message: IMessage, userPinned: IUser, isPinned: boolean): Promise; - messageEvent(int: 'IPostMessageStarred', message: IMessage, userStarred: IUser, isStarred: boolean): Promise; - messageEvent(int: 'IPostMessageReported', message: IMessage, userReported: IUser, reason: boolean): Promise; - - messageEvent( - int: 'IPreMessageSentPrevent' | 'IPreMessageDeletePrevent' | 'IPreMessageUpdatedPrevent', - message: IMessage, - ): Promise; - messageEvent( - int: 'IPreMessageSentExtend' | 'IPreMessageSentModify' | 'IPreMessageUpdatedExtend' | 'IPreMessageUpdatedModify', - message: IMessage, - ): Promise; - messageEvent(int: 'IPostMessageSent' | 'IPostMessageUpdated', message: IMessage): Promise; - - roomEvent(int: 'IPreRoomUserJoined' | 'IPostRoomUserJoined', room: IRoom, joiningUser: IUser, invitingUser?: IUser): Promise; - roomEvent(int: 'IPreRoomUserLeave' | 'IPostRoomUserLeave', room: IRoom, leavingUser: IUser): Promise; - - roomEvent(int: 'IPreRoomCreatePrevent' | 'IPreRoomDeletePrevent', room: IRoom): Promise; - roomEvent(int: 'IPreRoomCreateExtend' | 'IPreRoomCreateModify', room: IRoom): Promise; - roomEvent(int: 'IPostRoomCreate' | 'IPostRoomDeleted', room: IRoom): Promise; - - livechatEvent( - int: 'IPostLivechatAgentAssigned' | 'IPostLivechatAgentUnassigned', - data: { user: IUser; room: IOmnichannelRoom }, - ): Promise; - livechatEvent( - int: 'IPostLivechatRoomTransferred', - data: { type: 'agent'; room: IRoom['_id']; from: IUser['_id']; to: IUser['_id'] }, - ): Promise; - livechatEvent( - int: 'IPostLivechatRoomTransferred', - data: { type: 'department'; room: IRoom['_id']; from: ILivechatDepartment['_id']; to: ILivechatDepartment['_id'] }, - ): Promise; - livechatEvent(int: 'IPostLivechatGuestSaved', data: ILivechatVisitor['_id']): Promise; - livechatEvent(int: 'IPostLivechatRoomSaved', data: IRoom['_id']): Promise; - livechatEvent(int: 'ILivechatRoomClosedHandler' | 'IPostLivechatRoomStarted' | 'IPostLivechatRoomClosed', data: IRoom): Promise; - livechatEvent(int: AppEvents | AppEvents[keyof AppEvents], data: any): Promise; - } -} diff --git a/packages/apps/src/index.ts b/packages/apps/src/index.ts index 837749af62c0f..e137fa3cf0078 100644 --- a/packages/apps/src/index.ts +++ b/packages/apps/src/index.ts @@ -1,7 +1,4 @@ -import './bridges/IListenerBridge'; - export * from './converters'; export * from './AppsEngine'; export * from './IAppServerNotifier'; export * from './IAppServerOrchestrator'; -export * from './orchestrator'; diff --git a/packages/apps/src/orchestrator.ts b/packages/apps/src/orchestrator.ts deleted file mode 100644 index 4e3a53d9d5f00..0000000000000 --- a/packages/apps/src/orchestrator.ts +++ /dev/null @@ -1,7 +0,0 @@ -import type { IAppServerOrchestrator } from './IAppServerOrchestrator'; - -export let Apps: IAppServerOrchestrator | undefined; - -export function registerOrchestrator(orch: IAppServerOrchestrator): void { - Apps = orch; -} diff --git a/yarn.lock b/yarn.lock index 41869c1761c6a..72c94c3be6d4c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -39995,7 +39995,7 @@ __metadata: languageName: node linkType: hard -"typescript@npm:~5.3.2, typescript@npm:~5.3.3": +"typescript@npm:~5.3.3": version: 5.3.3 resolution: "typescript@npm:5.3.3" bin: @@ -40005,7 +40005,7 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@~5.3.2#~builtin, typescript@patch:typescript@~5.3.3#~builtin": +"typescript@patch:typescript@~5.3.3#~builtin": version: 5.3.3 resolution: "typescript@patch:typescript@npm%3A5.3.3#~builtin::version=5.3.3&hash=85af82" bin: