From 4f72d62aa73b12456280861be884c99a1e12c2a1 Mon Sep 17 00:00:00 2001
From: Douglas Gubert <douglas.gubert@gmail.com>
Date: Mon, 17 Jun 2024 19:17:08 -0300
Subject: [PATCH] feat: Apps-Engine Deno Runtime update (#31821)

Co-authored-by: Rafael Tapia <18501599+tapiarafael@users.noreply.github.com>
---
 .changeset/tame-weeks-shout.md                |  41 +++
 .github/actions/setup-node/action.yml         |   8 +
 apps/meteor/.docker/Dockerfile                |  25 +-
 apps/meteor/.docker/Dockerfile.alpine         |  73 ++++-
 .../app/apps/server/bridges/commands.ts       |   8 +-
 apps/meteor/app/apps/server/bridges/http.ts   |  94 +++---
 .../app/metrics/server/lib/collectMetrics.ts  |   2 +-
 .../server/lib/getAppsStatistics.js           |  18 -
 .../server/lib/getAppsStatistics.ts           |  51 +++
 .../app/statistics/server/lib/statistics.ts   |   2 +-
 .../ee/lib/misc/formatAppInstanceForRest.ts   |   4 +-
 .../endpoints/appsCountHandler.ts             |   4 +-
 .../ee/server/apps/communication/rest.ts      |  26 +-
 .../server/apps/communication/websockets.ts   |   4 +-
 apps/meteor/ee/server/apps/cron.ts            |   2 +-
 apps/meteor/ee/server/apps/orchestrator.js    |  49 +--
 .../server/apps/storage/AppRealLogStorage.ts  |  36 ++
 apps/meteor/ee/server/apps/storage/index.js   |   2 +-
 .../ee/server/apps/storage/logs-storage.js    |  32 --
 apps/meteor/ee/server/services/package.json   |   2 +-
 apps/meteor/package.json                      |   2 +-
 .../server/services/apps-engine/service.ts    |   7 +-
 .../apps/02-send-messages-as-user.js          |   2 +-
 docker-compose-ci.yml                         |   1 +
 ee/apps/ddp-streamer/package.json             |   2 +-
 ee/packages/presence/package.json             |   2 +-
 packages/apps/package.json                    |   2 +-
 packages/core-services/package.json           |   2 +-
 packages/core-typings/package.json            |   2 +-
 packages/fuselage-ui-kit/package.json         |   2 +-
 .../model-typings/src/models/IAppLogsModel.ts |   3 +
 packages/rest-typings/package.json            |   2 +-
 yarn.lock                                     | 310 +++++++++++++++++-
 33 files changed, 622 insertions(+), 200 deletions(-)
 create mode 100644 .changeset/tame-weeks-shout.md
 delete mode 100644 apps/meteor/app/statistics/server/lib/getAppsStatistics.js
 create mode 100644 apps/meteor/app/statistics/server/lib/getAppsStatistics.ts
 create mode 100644 apps/meteor/ee/server/apps/storage/AppRealLogStorage.ts
 delete mode 100644 apps/meteor/ee/server/apps/storage/logs-storage.js

diff --git a/.changeset/tame-weeks-shout.md b/.changeset/tame-weeks-shout.md
new file mode 100644
index 00000000000..72bfc864274
--- /dev/null
+++ b/.changeset/tame-weeks-shout.md
@@ -0,0 +1,41 @@
+---
+'@rocket.chat/omnichannel-services': minor
+'rocketchat-services': minor
+'@rocket.chat/omnichannel-transcript': minor
+'@rocket.chat/authorization-service': minor
+'@rocket.chat/web-ui-registration': minor
+'@rocket.chat/stream-hub-service': minor
+'@rocket.chat/uikit-playground': minor
+'@rocket.chat/presence-service': minor
+'@rocket.chat/fuselage-ui-kit': minor
+'@rocket.chat/instance-status': minor
+'@rocket.chat/account-service': minor
+'@rocket.chat/mock-providers': minor
+'@rocket.chat/api-client': minor
+'@rocket.chat/ddp-client': minor
+'@rocket.chat/pdf-worker': minor
+'@rocket.chat/ui-theming': minor
+'@rocket.chat/core-services': minor
+'@rocket.chat/model-typings': minor
+'@rocket.chat/ui-video-conf': minor
+'@rocket.chat/core-typings': minor
+'@rocket.chat/rest-typings': minor
+'@rocket.chat/ddp-streamer': minor
+'@rocket.chat/queue-worker': minor
+'@rocket.chat/presence': minor
+'@rocket.chat/ui-composer': minor
+'@rocket.chat/ui-contexts': minor
+'@rocket.chat/license': minor
+'@rocket.chat/gazzodown': minor
+'@rocket.chat/ui-avatar': minor
+'@rocket.chat/ui-client': minor
+'@rocket.chat/livechat': minor
+'@rocket.chat/models': minor
+'@rocket.chat/ui-kit': minor
+'@rocket.chat/apps': minor
+'@rocket.chat/cron': minor
+'@rocket.chat/i18n': minor
+'@rocket.chat/meteor': minor
+---
+
+New runtime for apps in the Apps-Engine based on the Deno platform
diff --git a/.github/actions/setup-node/action.yml b/.github/actions/setup-node/action.yml
index 0e921e81f1f..caa3c63e00f 100644
--- a/.github/actions/setup-node/action.yml
+++ b/.github/actions/setup-node/action.yml
@@ -10,6 +10,10 @@ inputs:
   install:
     required: false
     type: boolean
+  deno-dir:
+    required: false
+    type: string
+    default: ~/.deno-cache
 
 outputs:
   node-version:
@@ -19,6 +23,9 @@ runs:
   using: composite
 
   steps:
+    - run: echo 'DENO_DIR=${{ inputs.deno-dir }}' >> $GITHUB_ENV
+      shell: bash
+
     - name: Cache Node Modules
       if: inputs.cache-modules
       id: cache-node-modules
@@ -26,6 +33,7 @@ runs:
       with:
         path: |
           node_modules
+          ${{ env.DENO_DIR }}
           apps/meteor/node_modules
           apps/meteor/ee/server/services/node_modules
         key: node-modules-${{ hashFiles('yarn.lock') }}
diff --git a/apps/meteor/.docker/Dockerfile b/apps/meteor/.docker/Dockerfile
index 456ed4becaf..1e9ed3f5e59 100644
--- a/apps/meteor/.docker/Dockerfile
+++ b/apps/meteor/.docker/Dockerfile
@@ -13,12 +13,24 @@ RUN groupadd -g 65533 -r rocketchat \
 # --chown requires Docker 17.12 and works only on Linux
 ADD --chown=rocketchat:rocketchat . /app
 
+# needs a mongoinstance - defaults to container linking with alias 'mongo'
+ENV DEPLOY_METHOD=docker \
+    NODE_ENV=production \
+    MONGO_URL=mongodb://mongo:27017/rocketchat \
+    HOME=/tmp \
+    PORT=3000 \
+    ROOT_URL=http://localhost:3000 \
+    Accounts_AvatarStorePath=/app/uploads \
+    DENO_DIR=/usr/share/deno
+
 RUN aptMark="$(apt-mark showmanual)" \
     && apt-get install -y --no-install-recommends g++ make python3 ca-certificates \
     && cd /app/bundle/programs/server \
     && npm install \
-	&& cd npm/node_modules/isolated-vm \
-	&& npm install \
+    && cd npm/node_modules/isolated-vm \
+    && npm install \
+    && cd /app/bundle/programs/server/npm/node_modules/@rocket.chat/apps-engine/deno-runtime \
+    && ../../../deno-bin/bin/deno cache main.ts \
     && apt-mark auto '.*' > /dev/null \
     && apt-mark manual $aptMark > /dev/null \
     && find /usr/local -type f -executable -exec ldd '{}' ';' \
@@ -37,15 +49,6 @@ VOLUME /app/uploads
 
 WORKDIR /app/bundle
 
-# needs a mongoinstance - defaults to container linking with alias 'mongo'
-ENV DEPLOY_METHOD=docker \
-    NODE_ENV=production \
-    MONGO_URL=mongodb://mongo:27017/rocketchat \
-    HOME=/tmp \
-    PORT=3000 \
-    ROOT_URL=http://localhost:3000 \
-    Accounts_AvatarStorePath=/app/uploads
-
 EXPOSE 3000
 
 CMD ["node", "main.js"]
diff --git a/apps/meteor/.docker/Dockerfile.alpine b/apps/meteor/.docker/Dockerfile.alpine
index 94baef80921..feebf76a03e 100644
--- a/apps/meteor/.docker/Dockerfile.alpine
+++ b/apps/meteor/.docker/Dockerfile.alpine
@@ -1,13 +1,68 @@
 FROM node:14.21.3-alpine3.16
 
-RUN apk add --no-cache ttf-dejavu
+ENV LANG=C.UTF-8
+
+# Installing glibc deps required by Deno
+# This replaces libc6-compat
+# Copied from https://github.com/Docker-Hub-frolvlad/docker-alpine-glibc, which denoland/deno:alpine-1.37.1 uses
+# NOTE: Glibc 2.35 package is broken: https://github.com/sgerrand/alpine-pkg-glibc/issues/176, so we stick to 2.34 for now
+RUN ALPINE_GLIBC_BASE_URL="https://github.com/sgerrand/alpine-pkg-glibc/releases/download" && \
+    ALPINE_GLIBC_PACKAGE_VERSION="2.34-r0" && \
+    ALPINE_GLIBC_BASE_PACKAGE_FILENAME="glibc-$ALPINE_GLIBC_PACKAGE_VERSION.apk" && \
+    ALPINE_GLIBC_BIN_PACKAGE_FILENAME="glibc-bin-$ALPINE_GLIBC_PACKAGE_VERSION.apk" && \
+    ALPINE_GLIBC_I18N_PACKAGE_FILENAME="glibc-i18n-$ALPINE_GLIBC_PACKAGE_VERSION.apk" && \
+    apk add --no-cache --virtual=.build-dependencies wget ca-certificates && \
+    echo \
+        "-----BEGIN PUBLIC KEY-----\
+        MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApZ2u1KJKUu/fW4A25y9m\
+        y70AGEa/J3Wi5ibNVGNn1gT1r0VfgeWd0pUybS4UmcHdiNzxJPgoWQhV2SSW1JYu\
+        tOqKZF5QSN6X937PTUpNBjUvLtTQ1ve1fp39uf/lEXPpFpOPL88LKnDBgbh7wkCp\
+        m2KzLVGChf83MS0ShL6G9EQIAUxLm99VpgRjwqTQ/KfzGtpke1wqws4au0Ab4qPY\
+        KXvMLSPLUp7cfulWvhmZSegr5AdhNw5KNizPqCJT8ZrGvgHypXyiFvvAH5YRtSsc\
+        Zvo9GI2e2MaZyo9/lvb+LbLEJZKEQckqRj4P26gmASrZEPStwc+yqy1ShHLA0j6m\
+        1QIDAQAB\
+        -----END PUBLIC KEY-----" | sed 's/   */\n/g' > "/etc/apk/keys/sgerrand.rsa.pub" && \
+    wget \
+        "$ALPINE_GLIBC_BASE_URL/$ALPINE_GLIBC_PACKAGE_VERSION/$ALPINE_GLIBC_BASE_PACKAGE_FILENAME" \
+        "$ALPINE_GLIBC_BASE_URL/$ALPINE_GLIBC_PACKAGE_VERSION/$ALPINE_GLIBC_BIN_PACKAGE_FILENAME" \
+        "$ALPINE_GLIBC_BASE_URL/$ALPINE_GLIBC_PACKAGE_VERSION/$ALPINE_GLIBC_I18N_PACKAGE_FILENAME" && \
+    mv /etc/nsswitch.conf /etc/nsswitch.conf.bak && \
+    apk add --no-cache --force-overwrite \
+        "$ALPINE_GLIBC_BASE_PACKAGE_FILENAME" \
+        "$ALPINE_GLIBC_BIN_PACKAGE_FILENAME" \
+        "$ALPINE_GLIBC_I18N_PACKAGE_FILENAME" && \
+    \
+    mv /etc/nsswitch.conf.bak /etc/nsswitch.conf && \
+    rm "/etc/apk/keys/sgerrand.rsa.pub" && \
+    (/usr/glibc-compat/bin/localedef --force --inputfile POSIX --charmap UTF-8 "$LANG" || true) && \
+    echo "export LANG=$LANG" > /etc/profile.d/locale.sh && \
+    \
+    apk del glibc-i18n && \
+    \
+    rm "/root/.wget-hsts" && \
+    apk del .build-dependencies && \
+    rm \
+        "$ALPINE_GLIBC_BASE_PACKAGE_FILENAME" \
+        "$ALPINE_GLIBC_BIN_PACKAGE_FILENAME" \
+        "$ALPINE_GLIBC_I18N_PACKAGE_FILENAME" && \
+    apk add --no-cache ttf-dejavu
 
 ADD . /app
 
 LABEL maintainer="buildmaster@rocket.chat"
 
+# needs a mongo instance - defaults to container linking with alias 'mongo'
+ENV DEPLOY_METHOD=docker \
+    NODE_ENV=production \
+    MONGO_URL=mongodb://mongo:27017/rocketchat \
+    HOME=/tmp \
+    PORT=3000 \
+    ROOT_URL=http://localhost:3000 \
+    Accounts_AvatarStorePath=/app/uploads \
+    DENO_DIR=/usr/share/deno
+
 RUN set -x \
-    && apk add --no-cache --virtual .fetch-deps python3 make g++ libc6-compat \
+    && apk add --no-cache --virtual .fetch-deps python3 make g++ \
     && cd /app/bundle/programs/server \
     && npm install --production \
     # Start hack for sharp...
@@ -20,20 +75,14 @@ RUN set -x \
     && npm install isolated-vm@4.4.2 \
     && mv node_modules/isolated-vm npm/node_modules/isolated-vm \
     # End hack for isolated-vm
-    && cd npm \
+    # Cache Deno dependencies for Apps-Engine
+    && cd npm/node_modules/@rocket.chat/apps-engine/deno-runtime \
+    && /app/bundle/programs/server/npm/node_modules/deno-bin/bin/deno cache main.ts \
+    && cd /app/bundle/programs/server/npm \
     && npm rebuild bcrypt --build-from-source \
     && npm cache clear --force \
     && apk del .fetch-deps
 
-# needs a mongo instance - defaults to container linking with alias 'mongo'
-ENV DEPLOY_METHOD=docker \
-    NODE_ENV=production \
-    MONGO_URL=mongodb://mongo:27017/rocketchat \
-    HOME=/tmp \
-    PORT=3000 \
-    ROOT_URL=http://localhost:3000 \
-    Accounts_AvatarStorePath=/app/uploads
-
 VOLUME /app/uploads
 
 WORKDIR /app/bundle
diff --git a/apps/meteor/app/apps/server/bridges/commands.ts b/apps/meteor/app/apps/server/bridges/commands.ts
index 5e018c51de8..5ffef647305 100644
--- a/apps/meteor/app/apps/server/bridges/commands.ts
+++ b/apps/meteor/app/apps/server/bridges/commands.ts
@@ -111,8 +111,8 @@ export class AppCommandsBridge extends CommandBridge {
 			permission: command.permission,
 			callback: this._appCommandExecutor.bind(this),
 			providesPreview: command.providesPreview,
-			previewer: !command.previewer ? undefined : this._appCommandPreviewer.bind(this),
-			previewCallback: (!command.executePreviewItem ? undefined : this._appCommandPreviewExecutor.bind(this)) as
+			previewer: command.providesPreview ? this._appCommandPreviewer.bind(this) : undefined,
+			previewCallback: (command.providesPreview ? this._appCommandPreviewExecutor.bind(this) : undefined) as
 				| (typeof slashCommands.commands)[string]['previewCallback']
 				| undefined,
 		} as SlashCommand;
@@ -155,10 +155,6 @@ export class AppCommandsBridge extends CommandBridge {
 		if (typeof command.providesPreview !== 'boolean') {
 			throw new Error('Invalid Slash Command parameter provided, it must be a valid ISlashCommand object.');
 		}
-
-		if (typeof command.executor !== 'function') {
-			throw new Error('Invalid Slash Command parameter provided, it must be a valid ISlashCommand object.');
-		}
 	}
 
 	private async _appCommandExecutor({ command, message, params, triggerId, userId }: SlashCommandCallbackParams<string>): Promise<void> {
diff --git a/apps/meteor/app/apps/server/bridges/http.ts b/apps/meteor/app/apps/server/bridges/http.ts
index 1535a18823c..9d62769336a 100644
--- a/apps/meteor/app/apps/server/bridges/http.ts
+++ b/apps/meteor/app/apps/server/bridges/http.ts
@@ -72,55 +72,51 @@ export class AppHttpBridge extends HttpBridge {
 
 		this.orch.debugLog(`The App ${info.appId} is requesting from the outter webs:`, info);
 
-		try {
-			const response = await fetch(
-				url.href,
-				{
-					method,
-					body: content,
-					headers,
-					timeout,
-				},
-				(request.hasOwnProperty('strictSSL') && !request.strictSSL) ||
-					(request.hasOwnProperty('rejectUnauthorized') && request.rejectUnauthorized),
-			);
-
-			const result: IHttpResponse = {
-				url: info.url,
-				method: info.method,
-				statusCode: response.status,
-				headers: Object.fromEntries(response.headers as unknown as any),
-			};
-
-			const body = Buffer.from(await response.arrayBuffer());
-
-			if (request.encoding === null) {
-				/**
-				 * The property `content` is not appropriately typed in the
-				 * Apps-engine definition, and we can't simply change it there
-				 * as it would be a breaking change. Thus, we're left with this
-				 * type assertion.
-				 */
-				result.content = body as any;
-			} else {
-				result.content = body.toString(request.encoding as BufferEncoding);
-				result.data = ((): any => {
-					const contentType = (response.headers.get('content-type') || '').split(';')[0];
-					if (!['application/json', 'text/javascript', 'application/javascript', 'application/x-javascript'].includes(contentType)) {
-						return null;
-					}
-
-					try {
-						return JSON.parse(result.content);
-					} catch {
-						return null;
-					}
-				})();
-			}
-
-			return result;
-		} catch (e: any) {
-			return e.response;
+		const response = await fetch(
+			url.href,
+			{
+				method,
+				body: content,
+				headers,
+				timeout,
+			},
+			(request.hasOwnProperty('strictSSL') && !request.strictSSL) ||
+				(request.hasOwnProperty('rejectUnauthorized') && request.rejectUnauthorized),
+		);
+
+		const result: IHttpResponse = {
+			url: info.url,
+			method: info.method,
+			statusCode: response.status,
+			headers: Object.fromEntries(response.headers as unknown as any),
+		};
+
+		const body = Buffer.from(await response.arrayBuffer());
+
+		if (request.encoding === null) {
+			/**
+			 * The property `content` is not appropriately typed in the
+			 * Apps-engine definition, and we can't simply change it there
+			 * as it would be a breaking change. Thus, we're left with this
+			 * type assertion.
+			 */
+			result.content = body as any;
+		} else {
+			result.content = body.toString(request.encoding as BufferEncoding);
+			result.data = ((): any => {
+				const contentType = (response.headers.get('content-type') || '').split(';')[0];
+				if (!['application/json', 'text/javascript', 'application/javascript', 'application/x-javascript'].includes(contentType)) {
+					return null;
+				}
+
+				try {
+					return JSON.parse(result.content);
+				} catch {
+					return null;
+				}
+			})();
 		}
+
+		return result;
 	}
 }
diff --git a/apps/meteor/app/metrics/server/lib/collectMetrics.ts b/apps/meteor/app/metrics/server/lib/collectMetrics.ts
index 136686f49c9..978b3d59ec9 100644
--- a/apps/meteor/app/metrics/server/lib/collectMetrics.ts
+++ b/apps/meteor/app/metrics/server/lib/collectMetrics.ts
@@ -39,7 +39,7 @@ const setPrometheusData = async (): Promise<void> => {
 	metrics.ddpConnectedUsers.set(_.unique(authenticatedSessions.map((s) => s.userId)).length);
 
 	// Apps metrics
-	const { totalInstalled, totalActive, totalFailed } = getAppsStatistics();
+	const { totalInstalled, totalActive, totalFailed } = await getAppsStatistics();
 
 	metrics.totalAppsInstalled.set(totalInstalled || 0);
 	metrics.totalAppsEnabled.set(totalActive || 0);
diff --git a/apps/meteor/app/statistics/server/lib/getAppsStatistics.js b/apps/meteor/app/statistics/server/lib/getAppsStatistics.js
deleted file mode 100644
index 1d84bead3e8..00000000000
--- a/apps/meteor/app/statistics/server/lib/getAppsStatistics.js
+++ /dev/null
@@ -1,18 +0,0 @@
-import { Apps } from '@rocket.chat/apps';
-import { AppStatus } from '@rocket.chat/apps-engine/definition/AppStatus';
-
-import { Info } from '../../../utils/rocketchat.info';
-
-export function getAppsStatistics() {
-	return {
-		engineVersion: Info.marketplaceApiVersion,
-		totalInstalled: (Apps.self?.isInitialized() && Apps.getManager().get().length) ?? 0,
-		totalActive: (Apps.self?.isInitialized() && Apps.getManager().get({ enabled: true }).length) ?? 0,
-		totalFailed:
-			(Apps.self?.isInitialized() &&
-				Apps.getManager()
-					.get({ disabled: true })
-					.filter(({ app: { status } }) => status !== AppStatus.MANUALLY_DISABLED).length) ??
-			0,
-	};
-}
diff --git a/apps/meteor/app/statistics/server/lib/getAppsStatistics.ts b/apps/meteor/app/statistics/server/lib/getAppsStatistics.ts
new file mode 100644
index 00000000000..930fc15a9c5
--- /dev/null
+++ b/apps/meteor/app/statistics/server/lib/getAppsStatistics.ts
@@ -0,0 +1,51 @@
+import { Apps } from '@rocket.chat/apps';
+import { AppStatus, AppStatusUtils } from '@rocket.chat/apps-engine/definition/AppStatus';
+
+import { Info } from '../../../utils/rocketchat.info';
+
+export type AppsStatistics = {
+	engineVersion: string;
+	totalInstalled: number | false;
+	totalActive: number | false;
+	totalFailed: number | false;
+};
+
+export async function getAppsStatistics(): Promise<AppsStatistics> {
+	if (!Apps.self?.isInitialized()) {
+		return {
+			engineVersion: Info.marketplaceApiVersion,
+			totalInstalled: false,
+			totalActive: false,
+			totalFailed: false,
+		};
+	}
+
+	const apps = await Apps.getManager().get();
+
+	let totalInstalled = 0;
+	let totalActive = 0;
+	let totalFailed = 0;
+
+	await Promise.all(
+		apps.map(async (app) => {
+			totalInstalled++;
+
+			const status = await app.getStatus();
+
+			if (status === AppStatus.MANUALLY_DISABLED) {
+				totalFailed++;
+			}
+
+			if (AppStatusUtils.isEnabled(status)) {
+				totalActive++;
+			}
+		}),
+	);
+
+	return {
+		engineVersion: Info.marketplaceApiVersion,
+		totalInstalled,
+		totalActive,
+		totalFailed,
+	};
+}
diff --git a/apps/meteor/app/statistics/server/lib/statistics.ts b/apps/meteor/app/statistics/server/lib/statistics.ts
index a6fcc5b17b5..cff2aaefcc5 100644
--- a/apps/meteor/app/statistics/server/lib/statistics.ts
+++ b/apps/meteor/app/statistics/server/lib/statistics.ts
@@ -467,7 +467,7 @@ export const statistics = {
 			}),
 		);
 
-		statistics.apps = getAppsStatistics();
+		statistics.apps = await getAppsStatistics();
 		statistics.services = await getServicesStatistics();
 		statistics.importer = getImporterStatistics();
 		statistics.videoConf = await VideoConf.getStatistics();
diff --git a/apps/meteor/ee/lib/misc/formatAppInstanceForRest.ts b/apps/meteor/ee/lib/misc/formatAppInstanceForRest.ts
index d76b7ae59ae..bf096122c50 100644
--- a/apps/meteor/ee/lib/misc/formatAppInstanceForRest.ts
+++ b/apps/meteor/ee/lib/misc/formatAppInstanceForRest.ts
@@ -14,10 +14,10 @@ interface IAppInfoRest extends IAppInfo {
 	migrated: boolean;
 }
 
-export function formatAppInstanceForRest(app: ProxiedApp): IAppInfoRest {
+export async function formatAppInstanceForRest(app: ProxiedApp): Promise<IAppInfoRest> {
 	const appRest: IAppInfoRest = {
 		...app.getInfo(),
-		status: app.getStatus(),
+		status: await app.getStatus(),
 		languages: app.getStorageItem().languageContent,
 		private: getInstallationSourceFromAppStorageItem(app.getStorageItem()) === 'private',
 		migrated: !!app.getStorageItem().migrated,
diff --git a/apps/meteor/ee/server/apps/communication/endpoints/appsCountHandler.ts b/apps/meteor/ee/server/apps/communication/endpoints/appsCountHandler.ts
index fc436b8229c..878dd9aab92 100644
--- a/apps/meteor/ee/server/apps/communication/endpoints/appsCountHandler.ts
+++ b/apps/meteor/ee/server/apps/communication/endpoints/appsCountHandler.ts
@@ -19,10 +19,10 @@ export const appsCountHandler = (apiManager: AppsRestApi) =>
 			authRequired: false,
 		},
 		{
-			get(): SuccessResult<AppsCountResult> {
+			async get(): Promise<SuccessResult<AppsCountResult>> {
 				const manager = apiManager._manager as AppManager;
 
-				const apps = manager.get({ enabled: true });
+				const apps = await manager.get({ enabled: true });
 				const { maxMarketplaceApps, maxPrivateApps } = License.getAppsConfig();
 
 				return API.v1.success({
diff --git a/apps/meteor/ee/server/apps/communication/rest.ts b/apps/meteor/ee/server/apps/communication/rest.ts
index df30cccc8e7..02f8aeb7b34 100644
--- a/apps/meteor/ee/server/apps/communication/rest.ts
+++ b/apps/meteor/ee/server/apps/communication/rest.ts
@@ -209,8 +209,9 @@ export class AppsRestApi {
 			{ authRequired: true },
 			{
 				async get() {
-					const apps = manager.get().map(formatAppInstanceForRest);
-					return API.v1.success({ apps });
+					const apps = await manager.get();
+					const formatted = await Promise.all(apps.map(formatAppInstanceForRest));
+					return API.v1.success({ apps: formatted });
 				},
 			},
 		);
@@ -302,7 +303,8 @@ export class AppsRestApi {
 					}
 					apiDeprecationLogger.endpoint(this.request.route, '7.0.0', this.response, 'Use /apps/installed to get the installed apps list.');
 
-					const apps = manager.get().map(formatAppInstanceForRest);
+					const proxiedApps = await manager.get();
+					const apps = await Promise.all(proxiedApps.map(formatAppInstanceForRest));
 
 					return API.v1.success({ apps });
 				},
@@ -412,7 +414,7 @@ export class AppsRestApi {
 						});
 					}
 
-					info.status = aff.getApp().getStatus();
+					info.status = await aff.getApp().getStatus();
 
 					void notifyAppInstall(orchestrator.getMarketplaceUrl() as string, 'install', info);
 
@@ -508,8 +510,8 @@ export class AppsRestApi {
 			'languages',
 			{ authRequired: false },
 			{
-				get() {
-					const apps = manager.get().map((prl) => ({
+				async get() {
+					const apps = (await manager.get()).map((prl) => ({
 						id: prl.getID(),
 						languages: prl.getStorageItem().languageContent,
 					}));
@@ -760,7 +762,7 @@ export class AppsRestApi {
 						});
 					}
 
-					info.status = aff.getApp().getStatus();
+					info.status = await aff.getApp().getStatus();
 
 					void notifyAppInstall(orchestrator.getMarketplaceUrl() as string, 'update', info);
 
@@ -784,10 +786,14 @@ export class AppsRestApi {
 						?.get('users')
 						.convertToApp(await Meteor.userAsync());
 
-					await manager.remove(prl.getID(), { user });
-
 					const info: IAppInfo & { status?: AppStatus } = prl.getInfo();
-					info.status = prl.getStatus();
+					try {
+						await manager.remove(prl.getID(), { user });
+						info.status = AppStatus.DISABLED;
+					} catch (e) {
+						info.status = await prl.getStatus();
+						return API.v1.failure({ app: info });
+					}
 
 					void notifyAppInstall(orchestrator.getMarketplaceUrl() as string, 'uninstall', info);
 
diff --git a/apps/meteor/ee/server/apps/communication/websockets.ts b/apps/meteor/ee/server/apps/communication/websockets.ts
index 65a2a73ca06..83a16142714 100644
--- a/apps/meteor/ee/server/apps/communication/websockets.ts
+++ b/apps/meteor/ee/server/apps/communication/websockets.ts
@@ -51,7 +51,7 @@ export class AppServerListener {
 	async onAppStatusUpdated({ appId, status }: { appId: string; status: AppStatus }): Promise<void> {
 		const app = this.orch.getManager()?.getOneById(appId);
 
-		if (!app || app.getStatus() === status) {
+		if (!app || (await app.getStatus()) === status) {
 			return;
 		}
 
@@ -76,10 +76,12 @@ export class AppServerListener {
 			setting,
 			when: new Date(),
 		});
+
 		await this.orch
 			.getManager()!
 			.getSettingsManager()
 			.updateAppSetting(appId, setting as any); // TO-DO: fix type of `setting`
+
 		this.clientStreamer.emitWithoutBroadcast(AppEvents.APP_SETTING_UPDATED, { appId, setting });
 	}
 
diff --git a/apps/meteor/ee/server/apps/cron.ts b/apps/meteor/ee/server/apps/cron.ts
index e58610d2cbf..f904486bf61 100644
--- a/apps/meteor/ee/server/apps/cron.ts
+++ b/apps/meteor/ee/server/apps/cron.ts
@@ -57,7 +57,7 @@ const notifyAdminsAboutRenewedApps = async function _notifyAdminsAboutRenewedApp
 	}
 
 	const renewedApps = apps.filter(
-		(app) => app.getStatus() === AppStatus.DISABLED && app.getPreviousStatus() === AppStatus.INVALID_LICENSE_DISABLED,
+		async (app) => (await app.getStatus()) === AppStatus.DISABLED && app.getPreviousStatus() === AppStatus.INVALID_LICENSE_DISABLED,
 	);
 
 	if (renewedApps.length === 0) {
diff --git a/apps/meteor/ee/server/apps/orchestrator.js b/apps/meteor/ee/server/apps/orchestrator.js
index 37c31e890e8..c252579138c 100644
--- a/apps/meteor/ee/server/apps/orchestrator.js
+++ b/apps/meteor/ee/server/apps/orchestrator.js
@@ -21,7 +21,7 @@ import { AppThreadsConverter } from '../../../app/apps/server/converters/threads
 import { settings } from '../../../app/settings/server';
 import { canEnableApp } from '../../app/license/server/canEnableApp';
 import { AppServerNotifier, AppsRestApi, AppUIKitInteractionApi } from './communication';
-import { AppRealLogsStorage, AppRealStorage, ConfigurableAppSourceStorage } from './storage';
+import { AppRealLogStorage, AppRealStorage, ConfigurableAppSourceStorage } from './storage';
 
 function isTesting() {
 	return process.env.TEST_MODE === 'true';
@@ -54,7 +54,7 @@ export class AppServerOrchestrator {
 		this._logModel = AppLogs;
 		this._persistModel = AppsPersistence;
 		this._storage = new AppRealStorage(this._model);
-		this._logStorage = new AppRealLogsStorage(this._logModel);
+		this._logStorage = new AppRealLogStorage(this._logModel);
 		this._appSourceStorage = new ConfigurableAppSourceStorage(appsSourceStorageType, appsSourceStorageFilesystemPath);
 
 		this._converters = new Map();
@@ -172,34 +172,35 @@ export class AppServerOrchestrator {
 		await this.getManager().load();
 
 		// Before enabling each app we verify if there is still room for it
-		await this.getManager()
-			.get()
-			// We reduce everything to a promise chain so it runs sequentially
-			.reduce(
-				(control, app) =>
-					control.then(async () => {
-						const canEnable = await canEnableApp(app.getStorageItem());
-
-						if (canEnable) {
-							return this.getManager().loadOne(app.getID());
-						}
-
-						this._rocketchatLogger.warn(`App "${app.getInfo().name}" can't be enabled due to CE limits.`);
-					}),
-				Promise.resolve(),
-			);
+		const apps = await this.getManager().get();
+
+		/* eslint-disable no-await-in-loop */
+		// This needs to happen sequentially to keep track of app limits
+		for (const app of apps) {
+			const canEnable = await canEnableApp(app.getStorageItem());
+
+			if (!canEnable) {
+				this._rocketchatLogger.warn(`App "${app.getInfo().name}" can't be enabled due to CE limits.`);
+				// We need to continue as the limits are applied depending on the app installation source
+				// i.e. if one limit is hit, we can't break the loop as the following apps might still be valid
+				continue;
+			}
+
+			await this.getManager().loadOne(app.getID());
+		}
+		/* eslint-enable no-await-in-loop */
 
 		await this.getBridges().getSchedulerBridge().startScheduler();
 
-		this._rocketchatLogger.info(`Loaded the Apps Framework and loaded a total of ${this.getManager().get({ enabled: true }).length} Apps!`);
+		const appCount = (await this.getManager().get({ enabled: true })).length;
+
+		this._rocketchatLogger.info(`Loaded the Apps Framework and loaded a total of ${appCount} Apps!`);
 	}
 
 	async disableApps() {
-		await this.getManager()
-			.get()
-			.forEach((app) => {
-				this.getManager().disable(app.getID());
-			});
+		const apps = await this.getManager().get();
+
+		await Promise.all(apps.map((app) => this.getManager().disable(app.getID())));
 	}
 
 	async unload() {
diff --git a/apps/meteor/ee/server/apps/storage/AppRealLogStorage.ts b/apps/meteor/ee/server/apps/storage/AppRealLogStorage.ts
new file mode 100644
index 00000000000..17a8f2f838a
--- /dev/null
+++ b/apps/meteor/ee/server/apps/storage/AppRealLogStorage.ts
@@ -0,0 +1,36 @@
+import type { ILoggerStorageEntry } from '@rocket.chat/apps-engine/server/logging';
+import type { IAppLogStorageFindOptions } from '@rocket.chat/apps-engine/server/storage';
+import { AppLogStorage } from '@rocket.chat/apps-engine/server/storage';
+import { InstanceStatus } from '@rocket.chat/instance-status';
+import type { AppLogs } from '@rocket.chat/models';
+
+export class AppRealLogStorage extends AppLogStorage {
+	constructor(private db: typeof AppLogs) {
+		super('mongodb');
+	}
+
+	async find(
+		query: {
+			[field: string]: any;
+		},
+		{ fields, ...options }: IAppLogStorageFindOptions,
+	): Promise<ILoggerStorageEntry[]> {
+		return this.db.findPaginated(query, { projection: fields, ...options }).cursor.toArray();
+	}
+
+	async storeEntries(logEntry: ILoggerStorageEntry): Promise<ILoggerStorageEntry> {
+		logEntry.instanceId = InstanceStatus.id();
+
+		const id = (await this.db.insertOne(logEntry)).insertedId;
+
+		return this.db.findOneById(id);
+	}
+
+	async getEntriesFor(appId: string): Promise<ILoggerStorageEntry[]> {
+		return this.db.find({ appId }).toArray();
+	}
+
+	async removeEntriesFor(appId: string): Promise<void> {
+		await this.db.deleteOne({ appId });
+	}
+}
diff --git a/apps/meteor/ee/server/apps/storage/index.js b/apps/meteor/ee/server/apps/storage/index.js
index 7f8d90715a9..7b8d2f5af96 100644
--- a/apps/meteor/ee/server/apps/storage/index.js
+++ b/apps/meteor/ee/server/apps/storage/index.js
@@ -1,6 +1,6 @@
 import './AppFileSystemSourceStorage';
 import './AppGridFSSourceStorage';
 
-export { AppRealLogsStorage } from './logs-storage';
+export { AppRealLogStorage } from './AppRealLogStorage';
 export { AppRealStorage } from './AppRealStorage';
 export { ConfigurableAppSourceStorage } from './ConfigurableAppSourceStorage';
diff --git a/apps/meteor/ee/server/apps/storage/logs-storage.js b/apps/meteor/ee/server/apps/storage/logs-storage.js
deleted file mode 100644
index b48599ca2d3..00000000000
--- a/apps/meteor/ee/server/apps/storage/logs-storage.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import { AppConsole } from '@rocket.chat/apps-engine/server/logging';
-import { AppLogStorage } from '@rocket.chat/apps-engine/server/storage';
-import { InstanceStatus } from '@rocket.chat/instance-status';
-
-export class AppRealLogsStorage extends AppLogStorage {
-	constructor(model) {
-		super('mongodb');
-		this.db = model;
-	}
-
-	async find(...args) {
-		return this.db.find(...args).toArray();
-	}
-
-	async storeEntries(appId, logger) {
-		const item = AppConsole.toStorageEntry(appId, logger);
-
-		item.instanceId = InstanceStatus.id();
-
-		const id = (await this.db.insertOne(item)).insertedId;
-
-		return this.db.findOneById(id);
-	}
-
-	async getEntriesFor(appId) {
-		return this.db.find({ appId }).toArray();
-	}
-
-	async removeEntriesFor(appId) {
-		await this.db.remove({ appId });
-	}
-}
diff --git a/apps/meteor/ee/server/services/package.json b/apps/meteor/ee/server/services/package.json
index c2119b1d3b2..20af1002f73 100644
--- a/apps/meteor/ee/server/services/package.json
+++ b/apps/meteor/ee/server/services/package.json
@@ -18,7 +18,7 @@
 	"author": "Rocket.Chat",
 	"license": "MIT",
 	"dependencies": {
-		"@rocket.chat/apps-engine": "1.42.2",
+		"@rocket.chat/apps-engine": "alpha",
 		"@rocket.chat/core-services": "workspace:^",
 		"@rocket.chat/core-typings": "workspace:^",
 		"@rocket.chat/emitter": "~0.31.25",
diff --git a/apps/meteor/package.json b/apps/meteor/package.json
index d7915516784..9d02e91c6cb 100644
--- a/apps/meteor/package.json
+++ b/apps/meteor/package.json
@@ -231,7 +231,7 @@
 		"@rocket.chat/agenda": "workspace:^",
 		"@rocket.chat/api-client": "workspace:^",
 		"@rocket.chat/apps": "workspace:^",
-		"@rocket.chat/apps-engine": "1.42.2",
+		"@rocket.chat/apps-engine": "alpha",
 		"@rocket.chat/base64": "workspace:^",
 		"@rocket.chat/cas-validate": "workspace:^",
 		"@rocket.chat/core-services": "workspace:^",
diff --git a/apps/meteor/server/services/apps-engine/service.ts b/apps/meteor/server/services/apps-engine/service.ts
index 41a53cf5bbb..19838fd8411 100644
--- a/apps/meteor/server/services/apps-engine/service.ts
+++ b/apps/meteor/server/services/apps-engine/service.ts
@@ -75,7 +75,7 @@ export class AppsEngineService extends ServiceClassInternal implements IAppsEngi
 				return;
 			}
 
-			if (app.getStatus() === status) {
+			if ((await app.getStatus()) === status) {
 				Apps.self?.getRocketChatLogger().info(`"apps.statusUpdate" event received for app "${appId}", but the status is the same`);
 				return;
 			}
@@ -116,10 +116,7 @@ export class AppsEngineService extends ServiceClassInternal implements IAppsEngi
 	}
 
 	async getApps(query: IGetAppsFilter): Promise<IAppInfo[] | undefined> {
-		return Apps.self
-			?.getManager()
-			?.get(query)
-			.map((app) => app.getApp().getInfo());
+		return (await Apps.self?.getManager()?.get(query))?.map((app) => app.getInfo());
 	}
 
 	async getAppStorageItemById(appId: string): Promise<IAppStorageItem | undefined> {
diff --git a/apps/meteor/tests/end-to-end/apps/02-send-messages-as-user.js b/apps/meteor/tests/end-to-end/apps/02-send-messages-as-user.js
index a0be3273430..61d812571d7 100644
--- a/apps/meteor/tests/end-to-end/apps/02-send-messages-as-user.js
+++ b/apps/meteor/tests/end-to-end/apps/02-send-messages-as-user.js
@@ -95,7 +95,7 @@ describe('Apps - Send Messages As User', function () {
 
 			after(() => Promise.all([deleteRoom({ type: 'p', roomId: group._id }), deleteUser(user)]));
 
-			it('should send a message as app user', (done) => {
+			it('should return 500 when sending a message as user that has no permissions', (done) => {
 				request
 					.post(apps(`/public/${app.id}/send-message-as-user?userId=${user._id}`))
 					.set(userCredentials)
diff --git a/docker-compose-ci.yml b/docker-compose-ci.yml
index a533ae29d2d..67b89d61ef5 100644
--- a/docker-compose-ci.yml
+++ b/docker-compose-ci.yml
@@ -11,6 +11,7 @@ services:
     image: ghcr.io/${LOWERCASE_REPOSITORY}/rocket.chat:${RC_DOCKER_TAG}
     environment:
       - TEST_MODE=true
+      - DEBUG=${DEBUG}
       - EXIT_UNHANDLEDPROMISEREJECTION=true
       - 'MONGO_URL=${MONGO_URL}'
       - 'MONGO_OPLOG_URL=${MONGO_OPLOG_URL}'
diff --git a/ee/apps/ddp-streamer/package.json b/ee/apps/ddp-streamer/package.json
index c1dd482d2e7..9a2fd606576 100644
--- a/ee/apps/ddp-streamer/package.json
+++ b/ee/apps/ddp-streamer/package.json
@@ -15,7 +15,7 @@
 	],
 	"author": "Rocket.Chat",
 	"dependencies": {
-		"@rocket.chat/apps-engine": "1.42.2",
+		"@rocket.chat/apps-engine": "alpha",
 		"@rocket.chat/core-services": "workspace:^",
 		"@rocket.chat/core-typings": "workspace:^",
 		"@rocket.chat/emitter": "~0.31.25",
diff --git a/ee/packages/presence/package.json b/ee/packages/presence/package.json
index 4e609c5d954..4de31f3214b 100644
--- a/ee/packages/presence/package.json
+++ b/ee/packages/presence/package.json
@@ -6,7 +6,7 @@
 		"@babel/core": "~7.22.20",
 		"@babel/preset-env": "~7.22.20",
 		"@babel/preset-typescript": "~7.22.15",
-		"@rocket.chat/apps-engine": "1.42.2",
+		"@rocket.chat/apps-engine": "alpha",
 		"@rocket.chat/eslint-config": "workspace:^",
 		"@rocket.chat/rest-typings": "workspace:^",
 		"@types/node": "^14.18.63",
diff --git a/packages/apps/package.json b/packages/apps/package.json
index ee99ba288fa..359bb605e82 100644
--- a/packages/apps/package.json
+++ b/packages/apps/package.json
@@ -22,7 +22,7 @@
 		"/dist"
 	],
 	"dependencies": {
-		"@rocket.chat/apps-engine": "1.42.2",
+		"@rocket.chat/apps-engine": "alpha",
 		"@rocket.chat/core-typings": "workspace:^",
 		"@rocket.chat/model-typings": "workspace:^"
 	}
diff --git a/packages/core-services/package.json b/packages/core-services/package.json
index 6033814bf2f..9a4705673b1 100644
--- a/packages/core-services/package.json
+++ b/packages/core-services/package.json
@@ -34,7 +34,7 @@
 		"extends": "../../package.json"
 	},
 	"dependencies": {
-		"@rocket.chat/apps-engine": "1.42.2",
+		"@rocket.chat/apps-engine": "alpha",
 		"@rocket.chat/core-typings": "workspace:^",
 		"@rocket.chat/icons": "^0.36.0",
 		"@rocket.chat/message-parser": "workspace:^",
diff --git a/packages/core-typings/package.json b/packages/core-typings/package.json
index 9256b3e8b6e..b9b259a1b78 100644
--- a/packages/core-typings/package.json
+++ b/packages/core-typings/package.json
@@ -22,7 +22,7 @@
 		"/dist"
 	],
 	"dependencies": {
-		"@rocket.chat/apps-engine": "1.42.2",
+		"@rocket.chat/apps-engine": "alpha",
 		"@rocket.chat/icons": "^0.36.0",
 		"@rocket.chat/message-parser": "workspace:^",
 		"@rocket.chat/ui-kit": "workspace:~"
diff --git a/packages/fuselage-ui-kit/package.json b/packages/fuselage-ui-kit/package.json
index 25d44e876df..119a2375928 100644
--- a/packages/fuselage-ui-kit/package.json
+++ b/packages/fuselage-ui-kit/package.json
@@ -63,7 +63,7 @@
     "@babel/preset-env": "~7.22.20",
     "@babel/preset-react": "~7.22.15",
     "@babel/preset-typescript": "~7.22.15",
-    "@rocket.chat/apps-engine": "^1.42.2",
+    "@rocket.chat/apps-engine": "alpha",
     "@rocket.chat/core-typings": "workspace:^",
     "@rocket.chat/eslint-config": "workspace:^",
     "@rocket.chat/fuselage": "^0.54.2",
diff --git a/packages/model-typings/src/models/IAppLogsModel.ts b/packages/model-typings/src/models/IAppLogsModel.ts
index f73964c5768..6a6bc765cd8 100644
--- a/packages/model-typings/src/models/IAppLogsModel.ts
+++ b/packages/model-typings/src/models/IAppLogsModel.ts
@@ -1,6 +1,9 @@
+import type { DeleteResult, Filter } from 'mongodb';
+
 import type { IBaseModel } from './IBaseModel';
 
 // TODO: type for AppLogs
 export interface IAppLogsModel extends IBaseModel<any> {
 	resetTTLIndex(expireAfterSeconds: number): Promise<void>;
+	remove(query: Filter<any>): Promise<DeleteResult>;
 }
diff --git a/packages/rest-typings/package.json b/packages/rest-typings/package.json
index 2d567eb10fa..91ec61eb40e 100644
--- a/packages/rest-typings/package.json
+++ b/packages/rest-typings/package.json
@@ -24,7 +24,7 @@
 		"/dist"
 	],
 	"dependencies": {
-		"@rocket.chat/apps-engine": "1.42.2",
+		"@rocket.chat/apps-engine": "alpha",
 		"@rocket.chat/core-typings": "workspace:^",
 		"@rocket.chat/message-parser": "workspace:^",
 		"@rocket.chat/ui-kit": "workspace:~",
diff --git a/yarn.lock b/yarn.lock
index 1f73a73df3e..6321b0aff77 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3653,6 +3653,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/aix-ppc64@npm:0.20.2":
+  version: 0.20.2
+  resolution: "@esbuild/aix-ppc64@npm:0.20.2"
+  conditions: os=aix & cpu=ppc64
+  languageName: node
+  linkType: hard
+
 "@esbuild/android-arm64@npm:0.17.19":
   version: 0.17.19
   resolution: "@esbuild/android-arm64@npm:0.17.19"
@@ -3660,6 +3667,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/android-arm64@npm:0.20.2":
+  version: 0.20.2
+  resolution: "@esbuild/android-arm64@npm:0.20.2"
+  conditions: os=android & cpu=arm64
+  languageName: node
+  linkType: hard
+
 "@esbuild/android-arm@npm:0.17.19":
   version: 0.17.19
   resolution: "@esbuild/android-arm@npm:0.17.19"
@@ -3667,6 +3681,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/android-arm@npm:0.20.2":
+  version: 0.20.2
+  resolution: "@esbuild/android-arm@npm:0.20.2"
+  conditions: os=android & cpu=arm
+  languageName: node
+  linkType: hard
+
 "@esbuild/android-x64@npm:0.17.19":
   version: 0.17.19
   resolution: "@esbuild/android-x64@npm:0.17.19"
@@ -3674,6 +3695,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/android-x64@npm:0.20.2":
+  version: 0.20.2
+  resolution: "@esbuild/android-x64@npm:0.20.2"
+  conditions: os=android & cpu=x64
+  languageName: node
+  linkType: hard
+
 "@esbuild/darwin-arm64@npm:0.17.19":
   version: 0.17.19
   resolution: "@esbuild/darwin-arm64@npm:0.17.19"
@@ -3681,6 +3709,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/darwin-arm64@npm:0.20.2":
+  version: 0.20.2
+  resolution: "@esbuild/darwin-arm64@npm:0.20.2"
+  conditions: os=darwin & cpu=arm64
+  languageName: node
+  linkType: hard
+
 "@esbuild/darwin-x64@npm:0.17.19":
   version: 0.17.19
   resolution: "@esbuild/darwin-x64@npm:0.17.19"
@@ -3688,6 +3723,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/darwin-x64@npm:0.20.2":
+  version: 0.20.2
+  resolution: "@esbuild/darwin-x64@npm:0.20.2"
+  conditions: os=darwin & cpu=x64
+  languageName: node
+  linkType: hard
+
 "@esbuild/freebsd-arm64@npm:0.17.19":
   version: 0.17.19
   resolution: "@esbuild/freebsd-arm64@npm:0.17.19"
@@ -3695,6 +3737,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/freebsd-arm64@npm:0.20.2":
+  version: 0.20.2
+  resolution: "@esbuild/freebsd-arm64@npm:0.20.2"
+  conditions: os=freebsd & cpu=arm64
+  languageName: node
+  linkType: hard
+
 "@esbuild/freebsd-x64@npm:0.17.19":
   version: 0.17.19
   resolution: "@esbuild/freebsd-x64@npm:0.17.19"
@@ -3702,6 +3751,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/freebsd-x64@npm:0.20.2":
+  version: 0.20.2
+  resolution: "@esbuild/freebsd-x64@npm:0.20.2"
+  conditions: os=freebsd & cpu=x64
+  languageName: node
+  linkType: hard
+
 "@esbuild/linux-arm64@npm:0.17.19":
   version: 0.17.19
   resolution: "@esbuild/linux-arm64@npm:0.17.19"
@@ -3709,6 +3765,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/linux-arm64@npm:0.20.2":
+  version: 0.20.2
+  resolution: "@esbuild/linux-arm64@npm:0.20.2"
+  conditions: os=linux & cpu=arm64
+  languageName: node
+  linkType: hard
+
 "@esbuild/linux-arm@npm:0.17.19":
   version: 0.17.19
   resolution: "@esbuild/linux-arm@npm:0.17.19"
@@ -3716,6 +3779,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/linux-arm@npm:0.20.2":
+  version: 0.20.2
+  resolution: "@esbuild/linux-arm@npm:0.20.2"
+  conditions: os=linux & cpu=arm
+  languageName: node
+  linkType: hard
+
 "@esbuild/linux-ia32@npm:0.17.19":
   version: 0.17.19
   resolution: "@esbuild/linux-ia32@npm:0.17.19"
@@ -3723,6 +3793,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/linux-ia32@npm:0.20.2":
+  version: 0.20.2
+  resolution: "@esbuild/linux-ia32@npm:0.20.2"
+  conditions: os=linux & cpu=ia32
+  languageName: node
+  linkType: hard
+
 "@esbuild/linux-loong64@npm:0.17.19":
   version: 0.17.19
   resolution: "@esbuild/linux-loong64@npm:0.17.19"
@@ -3730,6 +3807,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/linux-loong64@npm:0.20.2":
+  version: 0.20.2
+  resolution: "@esbuild/linux-loong64@npm:0.20.2"
+  conditions: os=linux & cpu=loong64
+  languageName: node
+  linkType: hard
+
 "@esbuild/linux-mips64el@npm:0.17.19":
   version: 0.17.19
   resolution: "@esbuild/linux-mips64el@npm:0.17.19"
@@ -3737,6 +3821,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/linux-mips64el@npm:0.20.2":
+  version: 0.20.2
+  resolution: "@esbuild/linux-mips64el@npm:0.20.2"
+  conditions: os=linux & cpu=mips64el
+  languageName: node
+  linkType: hard
+
 "@esbuild/linux-ppc64@npm:0.17.19":
   version: 0.17.19
   resolution: "@esbuild/linux-ppc64@npm:0.17.19"
@@ -3744,6 +3835,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/linux-ppc64@npm:0.20.2":
+  version: 0.20.2
+  resolution: "@esbuild/linux-ppc64@npm:0.20.2"
+  conditions: os=linux & cpu=ppc64
+  languageName: node
+  linkType: hard
+
 "@esbuild/linux-riscv64@npm:0.17.19":
   version: 0.17.19
   resolution: "@esbuild/linux-riscv64@npm:0.17.19"
@@ -3751,6 +3849,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/linux-riscv64@npm:0.20.2":
+  version: 0.20.2
+  resolution: "@esbuild/linux-riscv64@npm:0.20.2"
+  conditions: os=linux & cpu=riscv64
+  languageName: node
+  linkType: hard
+
 "@esbuild/linux-s390x@npm:0.17.19":
   version: 0.17.19
   resolution: "@esbuild/linux-s390x@npm:0.17.19"
@@ -3758,6 +3863,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/linux-s390x@npm:0.20.2":
+  version: 0.20.2
+  resolution: "@esbuild/linux-s390x@npm:0.20.2"
+  conditions: os=linux & cpu=s390x
+  languageName: node
+  linkType: hard
+
 "@esbuild/linux-x64@npm:0.17.19":
   version: 0.17.19
   resolution: "@esbuild/linux-x64@npm:0.17.19"
@@ -3765,6 +3877,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/linux-x64@npm:0.20.2":
+  version: 0.20.2
+  resolution: "@esbuild/linux-x64@npm:0.20.2"
+  conditions: os=linux & cpu=x64
+  languageName: node
+  linkType: hard
+
 "@esbuild/netbsd-x64@npm:0.17.19":
   version: 0.17.19
   resolution: "@esbuild/netbsd-x64@npm:0.17.19"
@@ -3772,6 +3891,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/netbsd-x64@npm:0.20.2":
+  version: 0.20.2
+  resolution: "@esbuild/netbsd-x64@npm:0.20.2"
+  conditions: os=netbsd & cpu=x64
+  languageName: node
+  linkType: hard
+
 "@esbuild/openbsd-x64@npm:0.17.19":
   version: 0.17.19
   resolution: "@esbuild/openbsd-x64@npm:0.17.19"
@@ -3779,6 +3905,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/openbsd-x64@npm:0.20.2":
+  version: 0.20.2
+  resolution: "@esbuild/openbsd-x64@npm:0.20.2"
+  conditions: os=openbsd & cpu=x64
+  languageName: node
+  linkType: hard
+
 "@esbuild/sunos-x64@npm:0.17.19":
   version: 0.17.19
   resolution: "@esbuild/sunos-x64@npm:0.17.19"
@@ -3786,6 +3919,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/sunos-x64@npm:0.20.2":
+  version: 0.20.2
+  resolution: "@esbuild/sunos-x64@npm:0.20.2"
+  conditions: os=sunos & cpu=x64
+  languageName: node
+  linkType: hard
+
 "@esbuild/win32-arm64@npm:0.17.19":
   version: 0.17.19
   resolution: "@esbuild/win32-arm64@npm:0.17.19"
@@ -3793,6 +3933,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/win32-arm64@npm:0.20.2":
+  version: 0.20.2
+  resolution: "@esbuild/win32-arm64@npm:0.20.2"
+  conditions: os=win32 & cpu=arm64
+  languageName: node
+  linkType: hard
+
 "@esbuild/win32-ia32@npm:0.17.19":
   version: 0.17.19
   resolution: "@esbuild/win32-ia32@npm:0.17.19"
@@ -3800,6 +3947,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/win32-ia32@npm:0.20.2":
+  version: 0.20.2
+  resolution: "@esbuild/win32-ia32@npm:0.20.2"
+  conditions: os=win32 & cpu=ia32
+  languageName: node
+  linkType: hard
+
 "@esbuild/win32-x64@npm:0.17.19":
   version: 0.17.19
   resolution: "@esbuild/win32-x64@npm:0.17.19"
@@ -3807,6 +3961,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@esbuild/win32-x64@npm:0.20.2":
+  version: 0.20.2
+  resolution: "@esbuild/win32-x64@npm:0.20.2"
+  conditions: os=win32 & cpu=x64
+  languageName: node
+  linkType: hard
+
 "@eslint-community/eslint-utils@npm:^4.2.0":
   version: 4.4.0
   resolution: "@eslint-community/eslint-utils@npm:4.4.0"
@@ -4725,6 +4886,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@msgpack/msgpack@npm:3.0.0-beta2":
+  version: 3.0.0-beta2
+  resolution: "@msgpack/msgpack@npm:3.0.0-beta2"
+  checksum: d86e5d48146051952d6bea35a6cf733a401cf65ad5614d79689aa48c7076021737ca2c782978dd1b6c0c9c45888b246e379e45ae906179e3a0e8ef4ee6f221c1
+  languageName: node
+  linkType: hard
+
 "@napi-rs/cli@npm:^2.2.0":
   version: 2.6.2
   resolution: "@napi-rs/cli@npm:2.6.2"
@@ -8340,21 +8508,25 @@ __metadata:
   languageName: unknown
   linkType: soft
 
-"@rocket.chat/apps-engine@npm:1.42.2, @rocket.chat/apps-engine@npm:^1.42.2":
-  version: 1.42.2
-  resolution: "@rocket.chat/apps-engine@npm:1.42.2"
+"@rocket.chat/apps-engine@npm:alpha":
+  version: 1.43.0-alpha.763
+  resolution: "@rocket.chat/apps-engine@npm:1.43.0-alpha.763"
   dependencies:
+    "@msgpack/msgpack": 3.0.0-beta2
     adm-zip: ^0.5.9
     cryptiles: ^4.1.3
+    debug: ^4.3.4
+    deno-bin: 1.37.1
+    esbuild: ^0.20.2
     jose: ^4.11.1
+    jsonrpc-lite: ^2.2.0
     lodash.clonedeep: ^4.5.0
     semver: ^5.7.1
     stack-trace: 0.0.10
     uuid: ~8.3.2
-    vm2: ^3.9.19
   peerDependencies:
     "@rocket.chat/ui-kit": "*"
-  checksum: d7aa23249823e37072b6b7af16a40d9a4e7cb6b8047f2a87e52163dfe516d6c8a09b21cafd4f28dfbe4dd3da9cd0190d71f7623fec8c573a3f215ca4f9529b56
+  checksum: f4498febb2f11766c6cab98c3738ca8ba50e9cfa68d129577a781a6fbbe91cfc48c82d6e418f05f0db6b3561becd6aab09b5b19b26652deb5e5621d7fd7b4c4a
   languageName: node
   linkType: hard
 
@@ -8362,7 +8534,7 @@ __metadata:
   version: 0.0.0-use.local
   resolution: "@rocket.chat/apps@workspace:packages/apps"
   dependencies:
-    "@rocket.chat/apps-engine": 1.42.2
+    "@rocket.chat/apps-engine": alpha
     "@rocket.chat/core-typings": "workspace:^"
     "@rocket.chat/model-typings": "workspace:^"
     "@types/jest": ~29.5.7
@@ -8441,7 +8613,7 @@ __metadata:
     "@babel/core": ~7.22.20
     "@babel/preset-env": ~7.22.20
     "@babel/preset-typescript": ~7.22.15
-    "@rocket.chat/apps-engine": 1.42.2
+    "@rocket.chat/apps-engine": alpha
     "@rocket.chat/core-typings": "workspace:^"
     "@rocket.chat/eslint-config": "workspace:^"
     "@rocket.chat/icons": ^0.36.0
@@ -8467,7 +8639,7 @@ __metadata:
   version: 0.0.0-use.local
   resolution: "@rocket.chat/core-typings@workspace:packages/core-typings"
   dependencies:
-    "@rocket.chat/apps-engine": 1.42.2
+    "@rocket.chat/apps-engine": alpha
     "@rocket.chat/eslint-config": "workspace:^"
     "@rocket.chat/icons": ^0.36.0
     "@rocket.chat/message-parser": "workspace:^"
@@ -8544,7 +8716,7 @@ __metadata:
   version: 0.0.0-use.local
   resolution: "@rocket.chat/ddp-streamer@workspace:ee/apps/ddp-streamer"
   dependencies:
-    "@rocket.chat/apps-engine": 1.42.2
+    "@rocket.chat/apps-engine": alpha
     "@rocket.chat/core-services": "workspace:^"
     "@rocket.chat/core-typings": "workspace:^"
     "@rocket.chat/emitter": ~0.31.25
@@ -8740,7 +8912,7 @@ __metadata:
     "@babel/preset-env": ~7.22.20
     "@babel/preset-react": ~7.22.15
     "@babel/preset-typescript": ~7.22.15
-    "@rocket.chat/apps-engine": ^1.42.2
+    "@rocket.chat/apps-engine": alpha
     "@rocket.chat/core-typings": "workspace:^"
     "@rocket.chat/eslint-config": "workspace:^"
     "@rocket.chat/fuselage": ^0.54.2
@@ -9184,7 +9356,7 @@ __metadata:
     "@rocket.chat/agenda": "workspace:^"
     "@rocket.chat/api-client": "workspace:^"
     "@rocket.chat/apps": "workspace:^"
-    "@rocket.chat/apps-engine": 1.42.2
+    "@rocket.chat/apps-engine": alpha
     "@rocket.chat/base64": "workspace:^"
     "@rocket.chat/cas-validate": "workspace:^"
     "@rocket.chat/core-services": "workspace:^"
@@ -9822,7 +9994,7 @@ __metadata:
     "@babel/core": ~7.22.20
     "@babel/preset-env": ~7.22.20
     "@babel/preset-typescript": ~7.22.15
-    "@rocket.chat/apps-engine": 1.42.2
+    "@rocket.chat/apps-engine": alpha
     "@rocket.chat/core-services": "workspace:^"
     "@rocket.chat/core-typings": "workspace:^"
     "@rocket.chat/eslint-config": "workspace:^"
@@ -9937,7 +10109,7 @@ __metadata:
   version: 0.0.0-use.local
   resolution: "@rocket.chat/rest-typings@workspace:packages/rest-typings"
   dependencies:
-    "@rocket.chat/apps-engine": 1.42.2
+    "@rocket.chat/apps-engine": alpha
     "@rocket.chat/core-typings": "workspace:^"
     "@rocket.chat/eslint-config": "workspace:^"
     "@rocket.chat/message-parser": "workspace:^"
@@ -20891,6 +21063,19 @@ __metadata:
   languageName: node
   linkType: hard
 
+"deno-bin@npm:1.37.1":
+  version: 1.37.1
+  resolution: "deno-bin@npm:1.37.1"
+  dependencies:
+    adm-zip: ^0.5.4
+    follow-redirects: ^1.10.0
+  bin:
+    deno: bin/deno.js
+    deno-bin: bin/deno.js
+  checksum: 1c985611aa67b4b72f68b5608644af73dbff75619ac4fba67fecf036763acf76c66a9bb537cf09865c855313ceec6af1190474fa0163a616620b8af705c82736
+  languageName: node
+  linkType: hard
+
 "depd@npm:2.0.0, depd@npm:~2.0.0":
   version: 2.0.0
   resolution: "depd@npm:2.0.0"
@@ -22166,6 +22351,86 @@ __metadata:
   languageName: node
   linkType: hard
 
+"esbuild@npm:^0.20.2":
+  version: 0.20.2
+  resolution: "esbuild@npm:0.20.2"
+  dependencies:
+    "@esbuild/aix-ppc64": 0.20.2
+    "@esbuild/android-arm": 0.20.2
+    "@esbuild/android-arm64": 0.20.2
+    "@esbuild/android-x64": 0.20.2
+    "@esbuild/darwin-arm64": 0.20.2
+    "@esbuild/darwin-x64": 0.20.2
+    "@esbuild/freebsd-arm64": 0.20.2
+    "@esbuild/freebsd-x64": 0.20.2
+    "@esbuild/linux-arm": 0.20.2
+    "@esbuild/linux-arm64": 0.20.2
+    "@esbuild/linux-ia32": 0.20.2
+    "@esbuild/linux-loong64": 0.20.2
+    "@esbuild/linux-mips64el": 0.20.2
+    "@esbuild/linux-ppc64": 0.20.2
+    "@esbuild/linux-riscv64": 0.20.2
+    "@esbuild/linux-s390x": 0.20.2
+    "@esbuild/linux-x64": 0.20.2
+    "@esbuild/netbsd-x64": 0.20.2
+    "@esbuild/openbsd-x64": 0.20.2
+    "@esbuild/sunos-x64": 0.20.2
+    "@esbuild/win32-arm64": 0.20.2
+    "@esbuild/win32-ia32": 0.20.2
+    "@esbuild/win32-x64": 0.20.2
+  dependenciesMeta:
+    "@esbuild/aix-ppc64":
+      optional: true
+    "@esbuild/android-arm":
+      optional: true
+    "@esbuild/android-arm64":
+      optional: true
+    "@esbuild/android-x64":
+      optional: true
+    "@esbuild/darwin-arm64":
+      optional: true
+    "@esbuild/darwin-x64":
+      optional: true
+    "@esbuild/freebsd-arm64":
+      optional: true
+    "@esbuild/freebsd-x64":
+      optional: true
+    "@esbuild/linux-arm":
+      optional: true
+    "@esbuild/linux-arm64":
+      optional: true
+    "@esbuild/linux-ia32":
+      optional: true
+    "@esbuild/linux-loong64":
+      optional: true
+    "@esbuild/linux-mips64el":
+      optional: true
+    "@esbuild/linux-ppc64":
+      optional: true
+    "@esbuild/linux-riscv64":
+      optional: true
+    "@esbuild/linux-s390x":
+      optional: true
+    "@esbuild/linux-x64":
+      optional: true
+    "@esbuild/netbsd-x64":
+      optional: true
+    "@esbuild/openbsd-x64":
+      optional: true
+    "@esbuild/sunos-x64":
+      optional: true
+    "@esbuild/win32-arm64":
+      optional: true
+    "@esbuild/win32-ia32":
+      optional: true
+    "@esbuild/win32-x64":
+      optional: true
+  bin:
+    esbuild: bin/esbuild
+  checksum: bc88050fc1ca5c1bd03648f9979e514bdefb956a63aa3974373bb7b9cbac0b3aac9b9da1b5bdca0b3490e39d6b451c72815dbd6b7d7f978c91fbe9c9e9aa4e4c
+  languageName: node
+  linkType: hard
+
 "escalade@npm:^3.1.1":
   version: 3.1.1
   resolution: "escalade@npm:3.1.1"
@@ -23826,6 +24091,16 @@ __metadata:
   languageName: node
   linkType: hard
 
+"follow-redirects@npm:^1.10.0":
+  version: 1.15.4
+  resolution: "follow-redirects@npm:1.15.4"
+  peerDependenciesMeta:
+    debug:
+      optional: true
+  checksum: e178d1deff8b23d5d24ec3f7a94cde6e47d74d0dc649c35fc9857041267c12ec5d44650a0c5597ef83056ada9ea6ca0c30e7c4f97dbf07d035086be9e6a5b7b6
+  languageName: node
+  linkType: hard
+
 "fontkit@npm:^2.0.2":
   version: 2.0.2
   resolution: "fontkit@npm:2.0.2"
@@ -28792,6 +29067,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"jsonrpc-lite@npm:^2.2.0":
+  version: 2.2.0
+  resolution: "jsonrpc-lite@npm:2.2.0"
+  checksum: 3062101d3c93401d176c1c24b90e0feebdd063546f8ed89c299531dd792c4d37c6766666d160efb83b94f17f7e2deed4346cdd9124b99581ed4620779e8733bb
+  languageName: node
+  linkType: hard
+
 "jsonwebtoken@npm:^8.1.0, jsonwebtoken@npm:^8.5.1":
   version: 8.5.1
   resolution: "jsonwebtoken@npm:8.5.1"
@@ -36853,7 +37135,7 @@ __metadata:
   version: 0.0.0-use.local
   resolution: "rocketchat-services@workspace:apps/meteor/ee/server/services"
   dependencies:
-    "@rocket.chat/apps-engine": 1.42.2
+    "@rocket.chat/apps-engine": alpha
     "@rocket.chat/core-services": "workspace:^"
     "@rocket.chat/core-typings": "workspace:^"
     "@rocket.chat/emitter": ~0.31.25
-- 
GitLab